PGFPlots

This library uses the LaTeX package pgfplots to produce plots. It integrates with IJulia, outputting SVG images to the notebook. This version of PGFPlots requires Julia 0.4 or later.

Installation


In [ ]:
Pkg.add("PGFPlots")

In addition, you will need to install the following dependencies if you do not already have them on your system.

  • Pdf2svg. This is required by TikzPictures. 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 http://www.cityinthesky.co.uk/opensource/pdf2svg/. Be sure to add pdf2svg to your path (and restart).
  • Pgfplots (version 1.10 or later). Install using your latex package manager (e.g., texlive or miktex).

Once these things are installed, you should be able to run the following:


In [1]:
using PGFPlots

Examples

Linear Plots

You can create a very basic plot by passing in vectors of $x$ and $y$ coordinates.


In [2]:
x = [1,2,3]
y = [2,4,1]
plot(x, y)


Out[2]:

The version of the plot function above actually just creates an empty Axis and inserts a Plots.Linear instance containing the data.


In [3]:
Axis(Plots.Linear(x, y))


Out[3]:

If you create the Axis object explicitly, as done above, then you can set various properties of the axis.


In [4]:
pushPGFPlotsOptions("scale=1.5")
a = Axis(Plots.Linear(x, y, legendentry="My Plot"), xlabel="X", ylabel="Y", title="My Title")


Out[4]:

The options can be set after the plot a is created. Here we rotate the y-label and move the legend by setting the ylabelStyle and legendStyle:


In [5]:
a.ylabelStyle = "rotate = -90"
a.legendStyle = "{at={(1.05,1.0)},anchor=north west}"
a


Out[5]:

This will remove the latest added setting


In [6]:
popPGFPlotsOptions();

And to reset all options, use


In [7]:
resetPGFPlotsOptions();

You can set the width and height of the axis.


In [8]:
a = Axis(Plots.Linear(x, y), width="3cm", height="3cm")


Out[8]:

Since latex is used to typeset everything, you can use any latex math symbols you want. If you use L"..." (as below), you do not have to escape \ and $.


In [9]:
Axis(Plots.Linear(x, y), xlabel=L"$X$", ylabel=L"$Y$", title=L"$\int_0^\infty e^{\pi x}dx$")


Out[9]:

You can put multiple plots on the same axis and assign legend entries. You can also pass in functions and their range.


In [10]:
Axis([
    Plots.Linear(sin, (0,10), legendentry=L"$\sin(x)$"),
    Plots.Linear(x->sqrt(2*x), (0,10), legendentry=L"$\sqrt{2x}$")
])


Out[10]:

You can change the legend position by setting the legendPos parameter in the axis.


In [11]:
Axis([
    Plots.Linear(sin, (0,10), legendentry=L"$\sin(x)$"),
    Plots.Linear(x->sqrt(2*x), (0,10), legendentry=L"$\sqrt{2x}$")
    ], legendPos="north west")


Out[11]:

You can do comb plots by setting the style. The style string gets passed directly into PGFPlots, giving you full control over the plots (see PGFPlots documentation).


In [12]:
Plots.Linear(1:10, sin(1:10), style="ycomb")


Out[12]:

You can also do horizontal comb plots.


In [13]:
Plots.Linear(abs(sin(1:10)), 1:10, style="xcomb")


Out[13]:

You can also make it smooth.


In [14]:
Plots.Linear(1:10, sin(1:10), style="smooth")


Out[14]:

There is support for constant plots.


In [15]:
Plots.Linear(1:10, sin(1:10), style="const plot")


Out[15]:

In [16]:
Plots.Linear(1:10, sin(1:10), style="ybar")


Out[16]:

In [17]:
Plots.Linear(1:10, sin(1:10), style="ybar,fill=green", mark="none")


Out[17]:

You can give an axis a log scale by specifying xmode or ymode parameters of Axis:


In [18]:
p = Plots.Linear(0.01:0.01:1, 10.^(0.01:0.01:1), mark="none")
Axis(p, ymode="log")


Out[18]:

Fill and fill opacity can be handled through the style parameter.


In [19]:
p = Plots.Linear(0:10, (0:10).^2, style="red, fill=blue, fill opacity=0.3", mark="none")


Out[19]:

If you want the tick marks to be equal, you can set axisEqual to true (equivalent to axis equal in LaTeX). Note that this will also change the limit sizes, over riding xmax, xmin, ymin, and ymax.


In [20]:
p = Plots.Linear(0:10, 2*(0:10))
a = Axis(p, axisEqual=true, xmin=0, xmax=10)   # note xmin and xmax are disregarded...


Out[20]:

If this flippant disregard of your axis limit authority displeases you, you can set axisEqualImage to true (equivalent to axis equal image). This will leave the limits alone, and let you modify them.


In [21]:
p = Plots.Linear(0:10, 2*(0:10))
a = Axis(p, axisEqualImage=true)


Out[21]:

You can change the size of the markers with the markSize argument. The default marker size is 2.


In [22]:
Plots.Linear(0:10, 2*(0:10), markSize=10)


Out[22]:

To eliminate the line and only use marks, you can set the onlyMarks argument to true.


In [23]:
Plots.Linear(0:10, 2*(0:10), onlyMarks=true)


Out[23]:

Scatter Plots

A simple scatter plot is just a linear plot with "only marks". The following code returns a Linear plot with "only marks" selected:


In [24]:
x = 1:10
y = 2x
Plots.Scatter(x, y)


Out[24]:

PGFPlots gives you the option of picking a color for each scatter point. You can provide a third vector with the desired color values. The following code returns a Scatter plot where points with smaller z-values are blue. Points redden as the z-values increase.


In [25]:
z = 3x
Plots.Scatter(x, y, z)


Out[25]:

To add a colorbar, you can set the colorbar argument to true.


In [26]:
p = Plots.Scatter(x, y, z)
a = Axis(p, colorbar=true)


Out[26]:

If you want non-numeric data to determine the coloration and marking of each scatter point, you must provide the scatterClasses argument and describe what each symbol means. This is the same string that would be passed into the tex file if you were writing it yourself. The following code colors points by their class ("a", "b", or "c").


In [27]:
z = ["a", "a", "a", "b", "b", "b", "b", "c", "c", "c"]
sc = "{a={mark=square,blue},b={mark=triangle,red},c={mark=o,black}}"
Plots.Scatter(x, y, z, scatterClasses=sc)


Out[27]:

You can add a legend using the legendentry keyword.


In [28]:
Plots.Scatter(x, y, z, scatterClasses=sc, legendentry=["A", "B", "C"])


Out[28]:

You can customize the legend using optionsto the Axis (since the legend style is a property of the Axis).


In [29]:
Axis(Plots.Scatter(x, y, z, scatterClasses=sc, legendentry=["A", "B", "C"]), style="legend columns=-1", legendPos="north west")


Out[29]:

Histograms

It is very easy to make histograms. It is just another type under the Plots module. You should be able to use autocompletion in your editor (e.g., IJulia) to see what Plots are supported.


In [30]:
d = randn(100)
Axis(Plots.Histogram(d, bins=10), ymin=0)


Out[30]:

You can even create a cumulative distribution function from the data.


In [31]:
Axis(Plots.Histogram(d, bins=20, cumulative=true, density=true), ymin=0)


Out[31]:

As with the other plots, you can control the style. The documentation on tikz and pgfplots can give you more information about what styles are supported.


In [32]:
Axis(Plots.Histogram(d, bins=10, style="red,fill=red!10"), ymin=0, ylabel="Counts")


Out[32]:

Sometimes you do not want to store your raw dataset in a Tikz file, especially when the dataset is large. The discretization option lets you specify what discretization algorithm to use.


In [33]:
Axis(Plots.Histogram(d, discretization=:auto), ymin=0)


Out[33]:

Several discretization algorithms are provided by Discretizers.jl.


In [34]:
discretizations = 
           [:default, # use PGFPlots for small data sizes and :auto for large
            :pgfplots, # use the PGFPlots histogram function (uses nbins, which defaults to 10)
            :specified, # use Discretizers.jl but with the specified number of bins (which defaults to 10)
            :auto, # max between :fd and :sturges. Good all-round performance
            :fd, # Freedman Diaconis Estimator, robust
            :sturges, # R's default method, only good for near-Gaussian data
            :sqrt, # used by Excel and others for its simplicity and speed
            :doane, # improves Sturges’ for non-normal datasets.
            :scott, # less robust estimator that that takes into account data variability and data size.
            ]

srand(0)
data = [randn(500).*1.8 .+ -5;
        randn(2000).*0.8 .+ -4;
        randn(500).*0.3 .+ -1;
        randn(1000).*0.8 .+ 2;
        randn(500).*1.5 .+ 4;
       ]
data = filter!(x->-15.0 <= x <= 15.0, data)

g = GroupPlot(3, 3, groupStyle = "horizontal sep = 1.75cm, vertical sep = 1.5cm")
for discretization in discretizations
    push!(g, Axis(Plots.Histogram(data, discretization=discretization), ymin=0, title=string(discretization)))
end
g


Out[34]:

Image

Image plots create a PNG bitmap and can be used to visualize functions. The second and third arguments below are tuples specifying the x and y ranges.


In [35]:
f = (x,y)->x*exp(-x^2-y^2)
Plots.Image(f, (-2,2), (-2,2))


Out[35]:

You can set the zmin and zmax. By default, it uses the minimum and maximum values of the data.


In [36]:
Plots.Image(f, (-2,2), (-2,2), zmin=-1, zmax=1)


Out[36]:

You can invert the Gray colormap.


In [37]:
Plots.Image(f, (-2,2), (-2,2), colormap = ColorMaps.Gray(invert = true))


Out[37]:

You can turn off the colorbar.


In [38]:
Plots.Image(f, (-2,2), (-2,2), colorbar = false)


Out[38]:

You can change the colormap.


In [39]:
Plots.Image(f, (-2,2), (-2,2), colormap = ColorMaps.Distinguishable(3))


Out[39]:

In [40]:
Plots.Image(f, (-2,2), (-2,2), colormap = ColorMaps.Distinguishable(4))


Out[40]:

In [41]:
Plots.Image(f, (-2,2), (-2,2), colormap = ColorMaps.Distinguishable(4, invert=true))


Out[41]:

You can use colormap names from the Color.jl package.


In [42]:
Plots.Image(f, (-2,2), (-2,2), colormap = ColorMaps.Named("Blues"))


Out[42]:

You can make a colormap out of any RGB array, such as those created from the Color.jl package.


In [43]:
using Colors
cm = colormap("RdBu")


Out[43]:

In [44]:
Plots.Image(f, (-2,2), (-2,2), colormap = ColorMaps.RGBArray(cm))


Out[44]:

You can also choose the Jet colormap (not currently part of Colors.jl).


In [45]:
Plots.Image(f, (-2,2), (-2,2), colormap = ColorMaps.Named("Jet"))


Out[45]:

You can also use colors from ColorBrewer.jl.


In [46]:
Plots.Image(f, (-2,2), (-2,2), colormap = ColorMaps.Brew("Set1", 3))


Out[46]:

And you can invert them.


In [47]:
Plots.Image(f, (-2,2), (-2,2), colormap = ColorMaps.Brew("Set1", 3, invert=true))


Out[47]:

Histogram2

You may produce 2-dimensional histograms from a set of (x,y) datapoints.


In [48]:
x = randn(10000)*2 + 1
y = randn(10000) - 2
Plots.Histogram2(x, y)


Out[48]:

You can customize the limits and the colormap.


In [49]:
Plots.Histogram2(x, y, xmin=-3, xmax=3, ymin=-3, ymax=3, zmin=-1, colormap=ColorMaps.Named("Jet"))


Out[49]:

You can also customize the bounds of the colormap.


In [50]:
Plots.Histogram2(x, y, xmin=-3, xmax=3, ymin=-3, ymax=3, zmin=5, zmax=15, colormap=ColorMaps.Named("Jet"))


Out[50]:

The axis image can be made equal.


In [51]:
Axis(Plots.Histogram2(x, y, density=true, xmin=-3, xmax=3, ymin=-3, ymax=3), axisEqualImage=true)


Out[51]:

Instead of counts, you can transform the scale to reflect a probability density.


In [52]:
Plots.Histogram2(x, y, density=true)


Out[52]:

Contour

The syntax for contours is similar to that of image.


In [53]:
Plots.Contour(f, (-2,2), (-2,2))


Out[53]:

You can specify the levels explicitly.


In [54]:
Plots.Contour(f, (-2,2), (-2,2), levels=-0.4:0.1:4)


Out[54]:

You can also just specify the number of contours you want.


In [55]:
Plots.Contour(f, (-2,2), (-2,2), number=20)


Out[55]:

You can specify styles.


In [56]:
Plots.Contour(f, (-2,2), (-2,2), style="very thick")


Out[56]:

Quiver


In [57]:
h(x,y) = [exp(-x^2-y^2)*(1-2*x^2), exp(-x^2-y^2)*(-2*x*y)]
Plots.Quiver(h,(-2,2),(-2,2))


Out[57]:

In [58]:
h(x,y) = [exp(-x^2-y^2)*(1-2*x^2), exp(-x^2-y^2)*(-2*x*y)]
Plots.Quiver(h,(-2,2),(-2,2), style="-stealth'")


Out[58]:

By default, the length of the arrows are normalized so that they do not overlap each other. This can be turned off.


In [59]:
Plots.Quiver(h,(-2,2),(-2,2), normalize=false)


Out[59]:

Group plots

A GroupPlot is just a container for plots. You can specify the number or columns and rows to use.


In [60]:
# generate 1000 samples
d = randn(1000)
# try out histograms with a variety of different number of bins
bins = [3 10 50 1000]
g = GroupPlot(2,2) # create a 2 x 2 group plot
for i = 1:length(bins)
    push!(g, Axis(Plots.Histogram(d, bins=bins[i]), ymin=0))
end
g


Out[60]:

You can set the group style.


In [61]:
g = GroupPlot(2, 2, groupStyle = "horizontal sep = 3cm") # create a 2 x 2 group plot
for i = 1:length(bins)
    push!(g, Axis(Plots.Histogram(d, bins=bins[i]), ymin=0))
end
g


Out[61]:

Multiple Axes

An alternative to group plots is to use multiple axes. This is not as user friendly as group plots, but it allows for more flexibility. For example, it is possible to embed one axis inside another to create insets as follows:


In [62]:
#Create the first axis and add to it two lines
a1 = PGFPlots.Axis(style="width=10cm, height=10cm, grid=both");
push!(a1, PGFPlots.Linear([1,2],[10, 10], style="blue"))
push!(a1, PGFPlots.Linear([1,2],[10, 3],  style="red"))

#Create another axis with smaller width.
#xshift and yshift are used to position the axis.
a2 = PGFPlots.Axis(style="width=4cm, xshift=1cm, yshift=1cm", title="xy reflection");
push!(a2, PGFPlots.Linear([10, 10], [1,2], style="no marks, blue, thick"))
push!(a2, PGFPlots.Linear([10, 3] , [1,2], style="no marks, red, thick"));

#Group the two axes together as a list
[a1, a2]


Out[62]:

Text Nodes


In [63]:
Axis([
    Plots.Image(f, (-2,2), (-2,2)),
    Plots.Node(L"\sqrt{2}",1,0)        
])


Out[63]:

In [64]:
Axis([
    Plots.Image(f, (-2,2), (-2,2)),
    Plots.Node(L"\sqrt{2}",-1,0,style="yellow"),        
    Plots.Node("Hi there!",1,0,style="right")        
])


Out[64]:

The coordinate system defaults to the axis coordinate system, axis cs. You can specify other coordinate systems as well.


In [65]:
Axis([
    Plots.Image(f, (-2,2), (-2,2)),
    Plots.Node(L"\sqrt{2}",0.9,0.9,axis="axis description cs")
])


Out[65]:

Circles and Ellipses

You can add circles and ellipses to your plots. To add a circle, you must specify the center x-coordinate, the center y-coordinate, and the radius, in that order. To add an ellipse, you must specify the center x-coordinate, the center y-coordinate, the x-radius, and the y-radius.


In [66]:
p1 = Plots.Circle(5,5,5)
p2 = Plots.Ellipse(5,5,3,5)
a = Axis([p1,p2], xmin=0,ymin=0,xmax=10,ymax=10)


Out[66]:

You can remove axes if you want to. Remove the axes (hide the axes) by setting hideAxis to true for the axis.


In [67]:
a = Axis([p1,p2], xmin=0,ymin=0,xmax=10,ymax=10, hideAxis=true)


Out[67]:

3d Plots

You can add 3d plots. To make a 3d plot with a linear scale, use the Linear3 type (equivalent to \addplot3 in PGF).


In [68]:
t = rad2deg(linspace(0,5pi,60))
x = sind(t)
y = cosd(t)
z = 2t/(5pi)
p = Plots.Linear3(x, y, z, mark="none")
Axis(p, xlabel="x", ylabel="y", zlabel="z")


Out[68]:

You can change the view by specifying the view parameter of the Axis type. This is a string representing what you would feed to PGF. The first parameter is the rotation about the azimuth (z-axis). This rotation is applied first. The second argument is the elevation, or the angle rotated about the (rotated) x-axis.


In [69]:
Axis(p, view="{60}{30}", xlabel="x", ylabel="y", zlabel="z")


Out[69]:

Polar Axes

You can specify a polar axis. In this case, the "x" coordinate corresponds to the angle (in degrees), and the "y" coordinate corresponds to the radius.


In [70]:
using TikzPictures
TikzPictures.tikzDeleteIntermediate(false)
angles = [0,90,180,270]
radii = ones(4)
p = Plots.Linear(angles, radii)
pa = PolarAxis(p)


Out[70]:

Color

You can define your own custom named colors using a variety of methods. You can pass it an array of FloatingPoint values in the range $[0,1]$; it uses RGB if there are three values, and it uses CMYK if there are four values.


In [71]:
define_color("myrgbcolor1", [1,0.2,0.3])
Plots.Linear(x, y, style="myrgbcolor1")


Out[71]:

In [72]:
define_color("mycmykcolor1", [1,0.2,0.3,0])
Plots.Linear(x, y, style="mycmykcolor1")


Out[72]:

If you pass in an array of integers (between 0 and 255), then it will use the integer-based RGB color space.


In [73]:
define_color("myRGBcolor", [82,227,246])
Plots.Linear(x, y, style="myRGBcolor")


Out[73]:

If you pass in a single scalar value between 0 and 1, it will interpret as a shade of gray. In this scale, 0 is black and 1 is white.


In [74]:
define_color("mylightgray", 0.9)
Plots.Linear(x, y, style="mylightgray")


Out[74]:

If you pass in a UInt32, you will get an HTML color.


In [75]:
define_color("myhtmlcolor", 0xff7f00)
Plots.Linear(x, y, style="myhtmlcolor")


Out[75]:

You can also pass in any color type from the Colors.jl and ColorTypes.jl packages.


In [76]:
define_color("mycolor", HSV(300, 0.2, 0.9))
Plots.Linear(x, y, style="mycolor, very thick")


Out[76]:

Commands

You can inject arbitrary latex commands within an axis using Plots.Command. Below is an example. Of course, in this particular example, it is easier to use the legendentry keyword.


In [77]:
Axis([
    Plots.Linear(x, y, style="mycolor, very thick"),
    Plots.Command("\\legend{Test}")
    ])


Out[77]:

Customizing Preamble

In order to customize the $\LaTeX$ preamble in the current context, you can call pushPGFPlotsPreamble. For example, suppose you want to use the "cmbright package":


In [78]:
pushPGFPlotsPreamble("\\usepackage{cmbright}")
Plots.Linear(x, y, legendentry = "Test")


Out[78]:

To remove the latest option, just call popPGFPlotsPreamble(). All options can be reset with resetPGFPlotsPreamble()


In [79]:
popPGFPlotsPreamble()
Plots.Linear(x, y, legendentry = "Test")


Out[79]:

Saving

All of the images above can be saved in tex, pdf, or svg format.


In [80]:
p = Plots.Histogram(rand(10))
save("myfile.tex", p)
save("myfile.pdf", p)
save("myfile.svg", p)

The preamble around tikzpicture can be ignored. This is useful if the plot will be \input{} in another document.


In [81]:
p = Plots.Histogram(rand(10))
save("myfile.tex", p, include_preamble=false)

Future Plans

Gradually, more and more functionality from pgfplots will be migrated into this package. Eventually, this package will have stacked plots, area plots, etc. It will also eventually expose more control over error bars, tick marks, etc.