From f0589a75dc8fcc24afdbdbe006e5df2bc8c8c2bf Mon Sep 17 00:00:00 2001 From: Kristoffer Carlsson Date: Mon, 19 Feb 2018 23:21:54 +0100 Subject: [PATCH] update docs, enable doctests (#68) --- docs/make.jl | 3 +- docs/src/examples/coordinates.md | 3 +- docs/src/index.md | 25 +++---- docs/src/man/custom_types.md | 5 -- docs/src/man/options.md | 82 +++++++++++------------ docs/src/man/save.md | 9 +-- docs/src/man/structs.md | 109 +++++++++++++++++++------------ 7 files changed, 132 insertions(+), 104 deletions(-) delete mode 100644 docs/src/man/custom_types.md diff --git a/docs/make.jl b/docs/make.jl index fddd835c..83ec1041 100644 --- a/docs/make.jl +++ b/docs/make.jl @@ -6,7 +6,7 @@ makedocs( modules = [PGFPlotsX], format = :html, sitename = "PGFPlotsX.jl", - doctest = false, + doctest = true, strict = false, pages = Any[ "Home" => "index.md", @@ -14,7 +14,6 @@ makedocs( "man/options.md", "man/structs.md", "man/save.md", - "man/custom_types.md", ], "Examples" => [ "examples/coordinates.md", diff --git a/docs/src/examples/coordinates.md b/docs/src/examples/coordinates.md index 942003af..e8f3f10d 100644 --- a/docs/src/examples/coordinates.md +++ b/docs/src/examples/coordinates.md @@ -35,7 +35,8 @@ savefigs("coordinates-simple", ans) # hide ![](coordinates-simple.svg) -Use `xerror`, `xerrorplus`, `xerrorminus`, `yerror` etc for error bars. +Use `xerror`, `xerrorplus`, `xerrorminus`, `yerror` etc. for error bars. + ```@example pgf x = linspace(0, 2π, 20) @pgf Plot( diff --git a/docs/src/index.md b/docs/src/index.md index 53770480..e0e76746 100644 --- a/docs/src/index.md +++ b/docs/src/index.md @@ -2,14 +2,14 @@ ## Introduction -*PGFPlotsX* is a Julia package to generate publication quality figures using the LaTeX library PGFPlots. - -It is similar in spirit to the package [PGFPlots.jl](https://github.com/sisl/PGFPlots.jl) but it -tries to have a very close mapping to the PGFPlots API as well as minimize the number of dependencies. -The fact that the syntax is similar to the TeX version means that examples from Stack Overflow and the PGFPlots manual can -easily be incorporated in the Julia code. - -Documentation is a WIP but a quite extensive set of examples can be found at the [PGFPlotsXExamples repo](https://github.com/KristofferC/PGFPlotsXExamples). +*PGFPlotsX* is a Julia package for creating publication quality figures using the LaTeX library [PGFPlots](http://pgfplots.sourceforge.net/) +as the backend. PGFPlots has [extensive documentation (pdf)](http://pgfplots.sourceforge.net/pgfplots.pdf) +and a rich database of answered questions on places like [stack overflow](https://stackoverflow.com/questions/tagged/pgf) +and [tex.stackexchange](https://tex.stackexchange.com/questions/tagged/pgfplots). +In order to take advantage of this, the syntax in PGFPlotsX is similar to the one written in `.tex`. +It is therefore, usually, easy to translate a PGFPlots example written in `.tex` to PGFPlotsX Julia code. +The advantage of using *PGFPlotsX.jl* over writing raw latex code is that it is possible to use Julia objects directly in the figures. Furthermore, the figures can be previewed in notebooks and IDE's, like julia-vscode and Atom-Juno. +It is for example possible to directly use a `DataFrame` from [*DataFrames.jl*](https://github.com/JuliaData/DataFrames.jl) as a PGFPlots `table`. ## Installation @@ -17,9 +17,12 @@ Documentation is a WIP but a quite extensive set of examples can be found at the Pkg.add("PGFPlotsX") ``` -To show figures in svg (like is done by default in Jupyter notebooks) you need `pdf2svg`. On Ubuntu, you can get this by running `sudo apt-get install pdf2svg` and on RHEL/Fedora by running `sudo dnf install pdf2svg`. On Windows, you can download the binaries from [here](http://www.cityinthesky.co.uk/opensource/pdf2svg/). Be sure to add `pdf2svg` to your path. +*PGFPlots.jl* requires a latex installation with the PGFPlots package installed. +We recommend using a latex installation with access to lualatex since it can have significantly better performance than pdflatex. + +To generate or preview figures in svg (like is done by default in Jupyter notebooks) `pdf2svg` is required. This can obtained by, on Ubuntu, running `sudo apt-get install pdf2svg`, on RHEL/Fedora `sudo dnf install pdf2svg` and on macOS e.g. `brew install pdf2svg`. On Windows, the binary can be downloaded from [here](http://www.cityinthesky.co.uk/opensource/pdf2svg/); be sure to add `pdf2svg` to the `PATH`. -For saving (or showing) png figures you need `pdftoppm` which should be installed by default on Linux but can otherwise be downloaded [here](http://www.foolabs.com/xpdf/download.html). +For png figures `pdftoppm` is required. This should by default on Linux and on macOS should be available after running `brew install poppler`. It is also available in the *Xpdf tools* archive which can be downloaded [here](http://www.foolabs.com/xpdf/download.html). !!! note - If you installed a new latex engine, `pdf2svg` or `pdftoppm` after you installed *PGFPlotsX* you need to run `Pkg.build("PGFPlotsX")` for this to be reflected. + If you installed a new latex engine, `pdf2svg` or `pdftoppm` after you installed *PGFPlotsX* you need to run `Pkg.build("PGFPlotsX")` for this to be reflected. The output from `Pkg.build` should tell you what latex engines and figure converters it finds. diff --git a/docs/src/man/custom_types.md b/docs/src/man/custom_types.md deleted file mode 100644 index de4064a6..00000000 --- a/docs/src/man/custom_types.md +++ /dev/null @@ -1,5 +0,0 @@ -# Optional packages - -By loading different packages, you automatically get access to new functionality. - -Please see [the example notebook](https://github.com/KristofferC/PGFPlotsXExamples/blob/master/examples/custom_types.ipynb) diff --git a/docs/src/man/options.md b/docs/src/man/options.md index 608e160c..2b4853ee 100644 --- a/docs/src/man/options.md +++ b/docs/src/man/options.md @@ -1,7 +1,12 @@ # Defining options +```@meta +DocTestSetup = quote + using PGFPlotsX +end +``` -In PGFPlots, options are given as a list of keys that might have corresponding values +In PGFPlots, options are given as a list of keys, that might have corresponding values, inside of two square brackets e.g. ```tex @@ -10,11 +15,7 @@ inside of two square brackets e.g. \end{axis} ``` -This section shows the method for which to set and retrieve such options. - -!!! note - Sometimes examples are more telling than documentation so please check out [the examples](https://github.com/KristofferC/PGFPlotsXExamples). - +This section shows the method for which to set and retrieve such options in Julia. ## Setting options when constructing an object @@ -24,12 +25,12 @@ When constructing an object (like a `Plot`), options to that object can be enter where a string represents a key without a value (e.g. `"very thick"`) and a pair represents a key/value option, (e.g. `"samples" => 50`). This works well when the options are few and there is only one level of options in the object. -```julia-repl -julia> c = Coordinates([1,2,3], [2, 4, 8]); +```jldoctest p1 +julia> c = Coordinates([1, 2, 3], [2, 4, 8]); -julia> p = Plot(c, "very thick", "mark" => "halfcircle") +julia> p = Plot(c, "very thick", "mark" => "halfcircle"); -julia> print_tex(p); # print_tex is typically not called from user code +julia> print_tex(p); # print_tex can be used to preview the generated .tex \addplot+[very thick, mark={halfcircle}] coordinates { (1, 2) @@ -46,33 +47,34 @@ Instead, we provide a macro `@pgf` so that options can be entered similarly to h The previous example is then written as -```julia-repl -@pgf Plot(c, - { - very_thick, - mark = "halfcircle" - }) +```jldoctest p1 +julia> @pgf Plot( + { + very_thick, + mark = "halfcircle" + }, + c); ``` A more complicated example is: -```julia-repl -@pgf a = Axis(Plot(c), - { - "axis background/.style" = - { - shade, - top_color = "gray", - bottom_color = "white", - }, - ymode = "log" - } -) +```jldoctest p1 +julia> @pgf a = Axis(Plot(c), + { + "axis background/.style" = + { + shade, + top_color = "gray", + bottom_color = "white", + }, + ymode = "log" + } + ); ``` which is printed as -```julia-repl +```jldoctest p1 julia> print_tex(a) \begin{axis}[axis background/.style={shade, top color={gray}, bottom color={white}}, ymode={log}] \addplot+[] @@ -89,7 +91,7 @@ The macro can be applied to any type of expression and will be applied to everyt that is of the form `{ expr }`. !!!note - * Keys that contain symbols that in Julia are operators (e.g the key `"axis background/.style"`) has to be entered + * Keys that contain symbols that in Julia are operators (e.g the key `"axis background/.style"`) have to be entered as strings, as in the example above. ### Transformations @@ -104,29 +106,26 @@ The following transformations of keys/values are done when the options are writt It is sometimes convenient to set and get options after an object has been created. -```julia-repl -julia> c = Coordinates([1,2,3], [2, 4, 8]); +```jldoctest +julia> c = Coordinates([1, 2, 3], [2, 4, 8]); -julia> p = Plot(c) +julia> p = Plot(c); julia> p["fill"] = "blue"; -julia> p["fill"]; +julia> p["fill"] "blue" julia> @pgf p["axis background/.style"] = { shade, top_color = "gray", bottom_color = "white" }; julia> p["axis background/.style"]["top_color"]; -"gray" -julia> p["very thick"] = nothing # Set a value less options; +julia> p["very thick"] = nothing # Set a value-less options; julia> delete!(p, "fill"); -julia> p - julia> print_tex(p) - \addplot+[axis background/.style={shade, top color={gray}, bottom color={white}}, very tick] + \addplot+[axis background/.style={shade, top color={gray}, bottom color={white}}, very thick] coordinates { (1, 2) (2, 4) @@ -137,12 +136,12 @@ julia> print_tex(p) You can also merge in options that have been separately created using `merge!` -```julia-repl +```jldoctest julia> a = Axis(); julia> @pgf opts = {xmin = 0, ymax = 1, ybar}; -julia> merge!(a, opts) +julia> merge!(a, opts); julia> print_tex(a) \begin{axis}[xmin={0}, ymax={1}, ybar] @@ -150,3 +149,4 @@ julia> print_tex(a) ``` It is then easy to apply for example a "theme" to an axis where the themed is a set of options already saved. +Just `merge!` the theme into an `Axis`. diff --git a/docs/src/man/save.md b/docs/src/man/save.md index 1d80c368..bbf02824 100644 --- a/docs/src/man/save.md +++ b/docs/src/man/save.md @@ -15,7 +15,7 @@ To set the dpi of the figures in Juno when using `png`, run `dpi_juno_png(dpi::I In the REPL, the figure will be exported to a `pdf` and attempted to be opened in the default `pdf` viewing program. If you wish to disable this, run `pgf.enable_interactive(false)`. -## Exporting +## Exporting to files Figures can be exported to files using @@ -23,13 +23,14 @@ Figures can be exported to files using PGFPlotsX.save(filename::String, figure; include_preamble::Bool = true, dpi = 150) ``` -where the file extension of `filename` determines the file type (can be `.pdf`, `.svg` or `.tex`, or the standalone `tikz` file extensions below), `include_preamble` sets if the preamble should be included in the output (only relevant for `tex` export) and `dpi` determines the dpi of the figure (only relevant for `png` export). +where the file extension of `filename` determines the file type (can be `pdf`, `svg` or `tex`, or the standalone `tikz` file extensions below), `include_preamble` sets if the preamble should be included in the output (only relevant for `tex` export) and `dpi` determines the dpi of the figure (only relevant for `png` export). The standalone file extensions `.tikz`, `.TIKZ`, `.TikZ`, `.pgf`, `.PGF` save LaTeX code for a `tikzpicture` environment without a preamble. You can `\input` them directly into a LaTeX document, or use the the [tikzscale](https://www.ctan.org/pkg/tikzscale) LaTeX package for using `\includegraphics` with possible size adjustments. ## Customizing the preamble -It is common to want to use a custom preamble to add user-defined macros or different packages to the preamble. There are a few ways to do this: +It is common to use a custom preamble to add user-defined macros or use different packages. +There are a few ways to do this: * `push!` strings into the global variable `CUSTOM_PREAMBLE`. Each string in that vector will be inserted in the preamble. * Modify the `custom_premble.tex` file in the `deps` folder of the directory of the package. This file is directly spliced into the preamble of the output. @@ -38,7 +39,7 @@ It is common to want to use a custom preamble to add user-defined macros or diff ## Choosing the LaTeX engine used Thee are two different choices for latex engines, `PDFLATEX`, `LUALATEX`. -By default, `LUALATEX` is used if it was available during `Pkg.build()`. The active engine can be retrieved with the `latexengine()` function and be set with `latexengine!(engine)` where `engine` is one of the three previously mentioned engines. +By default, `LUALATEX` is used if it was available during `Pkg.build()`. The active engine can be retrieved with the `latexengine()` function and be set with `latexengine!(engine)` where `engine` is one of the two previously mentioned engines (e.g. `PGFPlotsX.PDFLATEX`). ## Custom flags diff --git a/docs/src/man/structs.md b/docs/src/man/structs.md index 0f8846b7..a7154ec6 100644 --- a/docs/src/man/structs.md +++ b/docs/src/man/structs.md @@ -1,6 +1,12 @@ # Building up figures -This section presents the structs used in PGFPlotsX to build up figures. An `X` after the struct name means that it supports option as described in +```@meta +DocTestSetup = quote + using PGFPlotsX +end +``` + +This section presents the structs used in PGFPlotsX to build up figures. An `X` after the struct name means that it supports option as described in the section on defining options. ## Data @@ -12,10 +18,9 @@ Coordinates a are a list of points `(x,y)` or `(x,y,z)`. They can be created as: * `Coordinates(x, y, [z])` where `x` and `y` (and optionally `z`) are lists. -* `Coordinates(x, f2)` or `Coordinates(x, y, f3)` where `x` and `y` are lists and `f2`, `f3` are functions taking one and two arguments respectively. * `Coordinates(points)` where `points` is a list of tuples, e.g. `x = [(1.0, 2.0), (2.0, 4.0)]`. -For two dimensional coordinates, errors can be added to `Coordinates` with the keywords: +For two-dimensional coordinates, errors can be added to `Coordinates` with the keywords: * `xerror`, `yerror` for symmetric errors * `xerrorplus` `yerrorplus` for positive errors @@ -40,7 +45,7 @@ julia> print_tex(Coordinates(x, y, z)) (3, 8, -3) } -julia> print_tex(Coordinates(x, x -> x^3)) +julia> print_tex(Coordinates(x, x.^3)) coordinates { (1, 1) @@ -58,13 +63,12 @@ julia> c = Coordinates(x, y, xerror = [0.2, 0.3, 0.5], yerror = [0.2, 0.1, 0.5]) julia> print_tex(c) coordinates { - (1, 2)+-(0.2, 0.2) - (2, 4)+-(0.3, 0.1) - (3, 8)+-(0.5, 0.5) + (1, 2) +- (0.2, 0.2) + (2, 4) +- (0.3, 0.1) + (3, 8) +- (0.5, 0.5) } ``` - ### `Expression` An `Expression` is a string, representing a function and is written in a way LaTeX understands. @@ -84,30 +88,29 @@ A table represents a matrix of data where each column is labeled. It can simply Examples: -```jldoctest -julia> t = Table("data.dat", "x" => "Dof"); +```julia-repl make_into_doctest +julia> t = @pgf Table({x = "Dof"}, "data.dat"); julia> print_tex(t) table [x={Dof}] - {data.dat} + {/data.dat} ``` Inline data is constructed using a keyword constructor: ```jldoctest -julia> t = Table("x" => "Dof", "y" => "Err"; Dof = rand(3), Err = rand(3)); +julia> t = @pgf Table({x => "Dof", y => "Err"}, [:Dof => [1, 2, 4], :Err => [2.0, 1.0, 0.1]]); julia> print_tex(t) table [x={Dof}, y={Err}] - {Dof Err - 0.6073590230719768 0.36281513247882136 - 0.7285438246638971 0.11629575623266741 - 0.29590973933842424 0.9782972101143201 + {Dof Err + 1.0 2.0 + 2.0 1.0 + 4.0 0.1 } ``` -If you load the DataFrames package, you can also create tables from data frames, see the TODO - +If you load the DataFrames package, you can also create tables from data frames, see the examples in [Julia types](@ref). ### Graphics - `X` @@ -115,7 +118,7 @@ If you load the DataFrames package, you can also create tables from data frames, Example: -```juliadoctest +```jldoctest julia> print_tex(Graphics("img.png")) graphics [] {img.png} @@ -131,13 +134,13 @@ A keyword argument `incremental::Bool` is used to determine if `\addplot+` (defa Example: -```jldoctest +```julia-repl make_into_doctest julia> p = @pgf Plot(Table("plotdata/invcum.dat"), { blue }; incremental = false); julia> print_tex(p) \addplot[blue] table [] - {plotdata/invcum.dat} + {/plotdata/invcum.dat} ; ``` @@ -149,16 +152,16 @@ Otherwise it works the same as `Plot`. Example: ```jldoctest -julia> x, y, z = rand(3), rand(3), rand(3); +julia> x, y, z = [1, 2, 3], [2, 4, 8], [3, 9, 27]; -julia> p = @pgf Plot3(Coordinates(x,y,z), { very_thick }) +julia> p = @pgf Plot3(Coordinates(x, y, z), { very_thick }); julia> print_tex(p) \addplot3+[very thick] coordinates { - (0.7399041050338018, 0.4333342656950161, 0.31102760595379864) - (0.8533903392895954, 0.4437618168514108, 0.05325494618659876) - (0.4871968750637172, 0.09021596022672318, 0.817385325577578) + (1, 2, 3) + (2, 4, 9) + (3, 8, 27) } ; ``` @@ -182,7 +185,7 @@ julia> @pgf a = Axis( Plot( Expression("x^2")), { xlabel = "x" ylabel = "y" title = "Figure" - }) + }); julia> print_tex(a) \begin{axis}[xlabel={x}, ylabel={y}, title={Figure}] @@ -191,7 +194,8 @@ julia> print_tex(a) ; \end{axis} -julia> push!(a, Plot( Table("data.dat"))); +julia> push!(a, Plot(Coordinates([1,2], [3,4]))); + julia> print_tex(a) \begin{axis}[xlabel={x}, ylabel={y}, title={Figure}] @@ -199,8 +203,10 @@ julia> print_tex(a) {x^2} ; \addplot+[] - table [] - {data.dat} + coordinates { + (1, 3) + (2, 4) + } ; \end{axis} ``` @@ -214,7 +220,7 @@ A `GroupPlot` is a way of grouping multiple plots in one figure. Example: -```jldoctest +```julia-repl make_into_doctest julia> @pgf gp = GroupPlot({group_style = { group_size = "2 by 1",}, height = "6cm", width = "6cm"}); julia> for (expr, data) in zip(["x^2", "exp(x)"], ["data1.dat", "data2.dat"]) @@ -247,7 +253,7 @@ julia> print_tex(gp) In order to add options to the `\nextgroupplot` call simply add arguments in an "option like way" (using strings / pairs / `@pgf`) when you `push!` -```jldoctest +```julia-repl make_into_doctest2 julia> @pgf gp = GroupPlot({group_style = { group_size = "1 by 1",}, height = "6cm", width = "6cm"}); julia> @pgf for (expr, data) in zip(["x^2"], ["data2.dat"]) @@ -275,7 +281,19 @@ A `PolarAxis` plot data on a polar grid. Example: ```jldoctest -julia> PolarAxis( Plot( Coordinates([0, 90, 180, 270], [1, 1, 1, 1]))) +julia> p = PolarAxis( Plot( Coordinates([0, 90, 180, 270], [1, 1, 1, 1]))); + +julia> print_tex(p) + \begin{polaraxis}[] + \addplot+[] + coordinates { + (0, 1) + (90, 1) + (180, 1) + (270, 1) + } + ; + \end{polaraxis} ``` ### `Legend` @@ -296,18 +314,15 @@ A `TikzPicture` can contain multiple `Axis`'s or `GroupPlot`'s. Example: ```jldoctest -julia> tp = TikzPicture( Axis( Plot( Coordinates(rand(5), rand(5)))), "scale" => 1.5) +julia> tp = TikzPicture(Axis(Plot(Coordinates([1, 2], [2, 4]))), "scale" => 1.5); julia> print_tex(tp) \begin{tikzpicture}[scale={1.5}] \begin{axis}[] \addplot+[] coordinates { - (0.019179024805588307, 0.2501519456458139) - (0.05113231216989789, 0.9221777779905538) - (0.5648080180343429, 0.9586784922834994) - (0.5248828812399753, 0.8642592693396507) - (0.02943482346303017, 0.7327568460567329) + (1, 2) + (2, 4) } ; \end{axis} @@ -325,7 +340,21 @@ Normally you would also push `Axis`'s that contain plots. ```julia-repl julia> td = TikzDocument(); -julia> push!(td, "Hello World") +julia> push!(td, "Hello World"); + +julia> print_tex(td) +\RequirePackage{luatex85} +\documentclass[tikz]{standalone} + % Default preamble + \usepackage{pgfplots} + \pgfplotsset{compat=newest} + \usepgfplotslibrary{groupplots} + \usepgfplotslibrary{polar} + \usepgfplotslibrary{statistics} +\begin{document} + Hello World + +\end{document} ``` !!! note