Tutorial

Gadfly is an implementation of a "grammar of graphics" style statistical graphics system for Julia. This tutorial will outline general usage patterns and will give you a feel for the overall system.

To begin, we need some data. Gadfly can work with data supplied as either a DataFrame or as plain AbstractArrays. In this tutorial, we'll pick and choose some examples from the RDatasets package.

Let us use Fisher's iris dataset as a starting point.

using Gadfly, RDatasets
iris = dataset("datasets", "iris")
RowSepalLengthSepalWidthPetalLengthPetalWidthSpecies
15.13.51.40.2setosa
24.93.01.40.2setosa
34.73.21.30.2setosa
44.63.11.50.2setosa
55.03.61.40.2setosa
65.43.91.70.4setosa
..................

DataFrames

When used with a DataFrame, the plot function in Gadfly is of the form:

plot(data::AbstractDataFrame, elements::Element...; mapping...)

The first argument is the data to be plotted and the keyword arguments at the end map "aesthetics" to columns in the data frame. All input arguments between data and mapping are some number of "elements", which are the nouns and verbs, so to speak, that form the grammar.

Let's get to it.

p = plot(iris, x=:SepalLength, y=:SepalWidth, Geom.point);

First note that we've taken advantage of the flexibility of Julia's handling of function signatures and put the keyword arguments in the midst of the positional arguments. This is purely for ease of reading.

The example above produces a Plot object. It can be saved to a file by drawing to one or more backends using draw.

img = SVG("iris_plot.svg", 14cm, 8cm)
draw(img, p)

Now we have the following charming little SVG image.

SepalLength -1 0 1 2 3 4 5 6 7 8 9 10 11 12 13 0.0 0.5 1.0 1.5 2.0 2.5 3.0 3.5 4.0 4.5 5.0 5.5 6.0 6.5 7.0 7.5 8.0 8.5 9.0 9.5 10.0 10.5 11.0 11.5 12.0 0 5 10 15 0.0 0.2 0.4 0.6 0.8 1.0 1.2 1.4 1.6 1.8 2.0 2.2 2.4 2.6 2.8 3.0 3.2 3.4 3.6 3.8 4.0 4.2 4.4 4.6 4.8 5.0 5.2 5.4 5.6 5.8 6.0 6.2 6.4 6.6 6.8 7.0 7.2 7.4 7.6 7.8 8.0 8.2 8.4 8.6 8.8 9.0 9.2 9.4 9.6 9.8 10.0 10.2 10.4 10.6 10.8 11.0 11.2 11.4 11.6 11.8 12.0 h,j,k,l,arrows,drag to pan i,o,+,-,scroll,shift-drag to zoom r,dbl-click to reset c for coordinates ? for help ? -1.0 -0.5 0.0 0.5 1.0 1.5 2.0 2.5 3.0 3.5 4.0 4.5 5.0 5.5 6.0 6.5 7.0 7.5 -0.6 -0.4 -0.2 0.0 0.2 0.4 0.6 0.8 1.0 1.2 1.4 1.6 1.8 2.0 2.2 2.4 2.6 2.8 3.0 3.2 3.4 3.6 3.8 4.0 4.2 4.4 4.6 4.8 5.0 5.2 5.4 5.6 5.8 6.0 6.2 6.4 6.6 6.8 7.0 -2.5 0.0 2.5 5.0 7.5 -0.5 -0.4 -0.3 -0.2 -0.1 0.0 0.1 0.2 0.3 0.4 0.5 0.6 0.7 0.8 0.9 1.0 1.1 1.2 1.3 1.4 1.5 1.6 1.7 1.8 1.9 2.0 2.1 2.2 2.3 2.4 2.5 2.6 2.7 2.8 2.9 3.0 3.1 3.2 3.3 3.4 3.5 3.6 3.7 3.8 3.9 4.0 4.1 4.2 4.3 4.4 4.5 4.6 4.7 4.8 4.9 5.0 5.1 5.2 5.3 5.4 5.5 5.6 5.7 5.8 5.9 6.0 6.1 6.2 6.3 6.4 6.5 6.6 6.7 6.8 6.9 7.0 SepalWidth

If some of the text in this image is overlapping other text, your browser likely has a minimum font size set. You will need to unset this option for the plots to render correctly in your web browser.

If you are working at the REPL, a quicker way to see the image is to omit the semi-colon trailing plot. This automatically renders the image to your default multimedia display, typically an internet browser. No need to capture the output argument in this case.

plot(iris, x=:SepalLength, y=:SepalWidth)

Note that Geom.point will be automatically supplied if no other geometries are given.

Alternatively one can manually call display on a Plot object. This workflow is necessary when display would not otherwise be called automatically.

function get_to_it(d)
  ppoint = plot(d, x=:SepalLength, y=:SepalWidth, Geom.point)
  pline = plot(d, x=:SepalLength, y=:SepalWidth, Geom.line)
  ppoint, pline
end
ps = get_to_it(iris)
map(display, ps)

For the rest of the demonstrations, we'll simply omit the trailing semi-colon for brevity.

In this plot we've mapped the x aesthetic to the SepalLength column and the y aesthetic to the SepalWidth. The last argument, Geom.point, is a geometry element which takes bound aesthetics and renders delightful figures. Adding other geometries produces layers, which may or may not result in a coherent plot.

plot(iris, x=:SepalLength, y=:SepalWidth, Geom.point, Geom.line)
SepalLength -1 0 1 2 3 4 5 6 7 8 9 10 11 12 13 0.0 0.5 1.0 1.5 2.0 2.5 3.0 3.5 4.0 4.5 5.0 5.5 6.0 6.5 7.0 7.5 8.0 8.5 9.0 9.5 10.0 10.5 11.0 11.5 12.0 0 5 10 15 0.0 0.2 0.4 0.6 0.8 1.0 1.2 1.4 1.6 1.8 2.0 2.2 2.4 2.6 2.8 3.0 3.2 3.4 3.6 3.8 4.0 4.2 4.4 4.6 4.8 5.0 5.2 5.4 5.6 5.8 6.0 6.2 6.4 6.6 6.8 7.0 7.2 7.4 7.6 7.8 8.0 8.2 8.4 8.6 8.8 9.0 9.2 9.4 9.6 9.8 10.0 10.2 10.4 10.6 10.8 11.0 11.2 11.4 11.6 11.8 12.0 h,j,k,l,arrows,drag to pan i,o,+,-,scroll,shift-drag to zoom r,dbl-click to reset c for coordinates ? for help ? -1.0 -0.5 0.0 0.5 1.0 1.5 2.0 2.5 3.0 3.5 4.0 4.5 5.0 5.5 6.0 6.5 7.0 7.5 -0.6 -0.4 -0.2 0.0 0.2 0.4 0.6 0.8 1.0 1.2 1.4 1.6 1.8 2.0 2.2 2.4 2.6 2.8 3.0 3.2 3.4 3.6 3.8 4.0 4.2 4.4 4.6 4.8 5.0 5.2 5.4 5.6 5.8 6.0 6.2 6.4 6.6 6.8 7.0 -2.5 0.0 2.5 5.0 7.5 -0.5 -0.4 -0.3 -0.2 -0.1 0.0 0.1 0.2 0.3 0.4 0.5 0.6 0.7 0.8 0.9 1.0 1.1 1.2 1.3 1.4 1.5 1.6 1.7 1.8 1.9 2.0 2.1 2.2 2.3 2.4 2.5 2.6 2.7 2.8 2.9 3.0 3.1 3.2 3.3 3.4 3.5 3.6 3.7 3.8 3.9 4.0 4.1 4.2 4.3 4.4 4.5 4.6 4.7 4.8 4.9 5.0 5.1 5.2 5.3 5.4 5.5 5.6 5.7 5.8 5.9 6.0 6.1 6.2 6.3 6.4 6.5 6.6 6.7 6.8 6.9 7.0 SepalWidth

This is the grammar of graphics equivalent of "colorless green ideas sleep furiously". It is valid grammar, but not particularly meaningful.

Arrays

If by chance your data are stored in Arrays instead of a DataFrame, fear not, identical plots can be created using an alternate plot signature:

plot(elements::Element...; aesthetics...)

Here, the keyword arguments directly supply the data to be plotted, instead of using them to indicate which columns of a DataFrame to use.

SepalLength = iris.SepalLength
SepalWidth = iris.SepalWidth
plot(x=SepalLength, y=SepalWidth, Geom.point,
     Guide.xlabel("SepalLength"), Guide.ylabel("SepalWidth"))

Note that with the Array interface, extra elements must be included to specify the axis labels, whereas with a DataFrame they default to the column names.

Aesthetics

Let's do add something meaningful by mapping the color aesthetic.

plot(iris, x=:SepalLength, y=:SepalWidth, color=:Species, Geom.point);

# or equivalently for Arrays:
Color = iris.Species
plot(x=SepalLength, y=SepalWidth, color=Color, Geom.point,
     Guide.xlabel("SepalLength"), Guide.ylabel("SepalWidth"),
     Guide.colorkey(title="Species"))
SepalLength -1 0 1 2 3 4 5 6 7 8 9 10 11 12 13 0.0 0.5 1.0 1.5 2.0 2.5 3.0 3.5 4.0 4.5 5.0 5.5 6.0 6.5 7.0 7.5 8.0 8.5 9.0 9.5 10.0 10.5 11.0 11.5 12.0 0 5 10 15 0.0 0.2 0.4 0.6 0.8 1.0 1.2 1.4 1.6 1.8 2.0 2.2 2.4 2.6 2.8 3.0 3.2 3.4 3.6 3.8 4.0 4.2 4.4 4.6 4.8 5.0 5.2 5.4 5.6 5.8 6.0 6.2 6.4 6.6 6.8 7.0 7.2 7.4 7.6 7.8 8.0 8.2 8.4 8.6 8.8 9.0 9.2 9.4 9.6 9.8 10.0 10.2 10.4 10.6 10.8 11.0 11.2 11.4 11.6 11.8 12.0 setosa versicolor virginica Species h,j,k,l,arrows,drag to pan i,o,+,-,scroll,shift-drag to zoom r,dbl-click to reset c for coordinates ? for help ? -1.0 -0.5 0.0 0.5 1.0 1.5 2.0 2.5 3.0 3.5 4.0 4.5 5.0 5.5 6.0 6.5 7.0 7.5 -0.6 -0.4 -0.2 0.0 0.2 0.4 0.6 0.8 1.0 1.2 1.4 1.6 1.8 2.0 2.2 2.4 2.6 2.8 3.0 3.2 3.4 3.6 3.8 4.0 4.2 4.4 4.6 4.8 5.0 5.2 5.4 5.6 5.8 6.0 6.2 6.4 6.6 6.8 7.0 -2.5 0.0 2.5 5.0 7.5 -0.5 -0.4 -0.3 -0.2 -0.1 0.0 0.1 0.2 0.3 0.4 0.5 0.6 0.7 0.8 0.9 1.0 1.1 1.2 1.3 1.4 1.5 1.6 1.7 1.8 1.9 2.0 2.1 2.2 2.3 2.4 2.5 2.6 2.7 2.8 2.9 3.0 3.1 3.2 3.3 3.4 3.5 3.6 3.7 3.8 3.9 4.0 4.1 4.2 4.3 4.4 4.5 4.6 4.7 4.8 4.9 5.0 5.1 5.2 5.3 5.4 5.5 5.6 5.7 5.8 5.9 6.0 6.1 6.2 6.3 6.4 6.5 6.6 6.7 6.8 6.9 7.0 SepalWidth

Ah, a scientific discovery: Setosa has short but wide sepals!

Color scales in Gadfly by default are produced from perceptually uniform colorspaces (LUV/LCHuv or LAB/LCHab), though it supports RGB, HSV, HLS, XYZ, and converts arbitrarily between these. Color values can also be specified by most names common to CSS or X11, e.g. "oldlace" or "aliceblue". The full list of valid color names is defined in the Colors.jl library.

Color, and other aesthetics, can also be mapped by using arrays with group labels or functional types e.g. ["group label"] or [colorant"red"]. ["Group labels"] are added to the key.

y1 = [0.1, 0.26, NaN, 0.5, 0.4, NaN, 0.48, 0.58, 0.83]
plot(x=1:9, y=y1, Geom.line, Geom.point,
        color=["Item 1"], linestyle=[:dash], size=[3pt],
    layer(x=1:10, y=rand(10), Geom.line, Geom.point,
        color=["Item 2"], size=[5pt], shape=[Shape.square]),
    layer(x=1:10, y=rand(10), color=[colorant"hotpink"],
        linestyle=[[8pt, 3pt, 2pt, 3pt]], Geom.line))
x -12.5 -10.0 -7.5 -5.0 -2.5 0.0 2.5 5.0 7.5 10.0 12.5 15.0 17.5 20.0 22.5 -10 -9 -8 -7 -6 -5 -4 -3 -2 -1 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 -10 0 10 20 -10.0 -9.5 -9.0 -8.5 -8.0 -7.5 -7.0 -6.5 -6.0 -5.5 -5.0 -4.5 -4.0 -3.5 -3.0 -2.5 -2.0 -1.5 -1.0 -0.5 0.0 0.5 1.0 1.5 2.0 2.5 3.0 3.5 4.0 4.5 5.0 5.5 6.0 6.5 7.0 7.5 8.0 8.5 9.0 9.5 10.0 10.5 11.0 11.5 12.0 12.5 13.0 13.5 14.0 14.5 15.0 15.5 16.0 16.5 17.0 17.5 18.0 18.5 19.0 19.5 20.0 Item 1 Item 2 Color h,j,k,l,arrows,drag to pan i,o,+,-,scroll,shift-drag to zoom r,dbl-click to reset c for coordinates ? for help ? -1.25 -1.00 -0.75 -0.50 -0.25 0.00 0.25 0.50 0.75 1.00 1.25 1.50 1.75 2.00 2.25 -1.0 -0.9 -0.8 -0.7 -0.6 -0.5 -0.4 -0.3 -0.2 -0.1 0.0 0.1 0.2 0.3 0.4 0.5 0.6 0.7 0.8 0.9 1.0 1.1 1.2 1.3 1.4 1.5 1.6 1.7 1.8 1.9 2.0 -1 0 1 2 -1.00 -0.95 -0.90 -0.85 -0.80 -0.75 -0.70 -0.65 -0.60 -0.55 -0.50 -0.45 -0.40 -0.35 -0.30 -0.25 -0.20 -0.15 -0.10 -0.05 0.00 0.05 0.10 0.15 0.20 0.25 0.30 0.35 0.40 0.45 0.50 0.55 0.60 0.65 0.70 0.75 0.80 0.85 0.90 0.95 1.00 1.05 1.10 1.15 1.20 1.25 1.30 1.35 1.40 1.45 1.50 1.55 1.60 1.65 1.70 1.75 1.80 1.85 1.90 1.95 2.00 y

All aesthetics have a Scale e.g. Scale.x_continuous() and some have a Guide e.g. Guide.xticks(). Scales can be continuous or discrete. Some Scales also have a corresponding palette in Theme().

Continuous Scales

AestheticScale.Guide.Theme palette
xx_continuousxticks
yy_continuousyticks
colorcolor_continuouscolorkey(tbd)
sizesize_continuous–-point_size_min, point_size_max
size_radiussizekeycontinuous_sizemap
alphaalpha_continuousalphakey (tbd)

e.g. Scale.x_continuous(format= , minvalue= , maxvalue= )
format can be: :plain, :scientific, :engineering, or :auto.

Continuous scales can be transformed. In the next plot, the large animals are ruining things for us. Putting both axes on a log-scale clears things up.

set_default_plot_size(21cm ,8cm)
mammals = dataset("MASS", "mammals")
p1 = plot(mammals, x=:Body, y=:Brain, label=:Mammal, Geom.point, Geom.label)
p2 = plot(mammals, x=:Body, y=:Brain, label=:Mammal, Geom.point, Geom.label,
     Scale.x_log10, Scale.y_log10)
hstack(p1, p2)
Body 10-14 10-12 10-10 10-8 10-6 10-4 10-2 100 102 104 106 108 1010 1012 1014 10-12.0 10-11.5 10-11.0 10-10.5 10-10.0 10-9.5 10-9.0 10-8.5 10-8.0 10-7.5 10-7.0 10-6.5 10-6.0 10-5.5 10-5.0 10-4.5 10-4.0 10-3.5 10-3.0 10-2.5 10-2.0 10-1.5 10-1.0 10-0.5 100.0 100.5 101.0 101.5 102.0 102.5 103.0 103.5 104.0 104.5 105.0 105.5 106.0 106.5 107.0 107.5 108.0 108.5 109.0 109.5 1010.0 1010.5 1011.0 1011.5 1012.0 10-20 10-10 100 1010 1020 10-12.0 10-11.5 10-11.0 10-10.5 10-10.0 10-9.5 10-9.0 10-8.5 10-8.0 10-7.5 10-7.0 10-6.5 10-6.0 10-5.5 10-5.0 10-4.5 10-4.0 10-3.5 10-3.0 10-2.5 10-2.0 10-1.5 10-1.0 10-0.5 100.0 100.5 101.0 101.5 102.0 102.5 103.0 103.5 104.0 104.5 105.0 105.5 106.0 106.5 107.0 107.5 108.0 108.5 109.0 109.5 1010.0 1010.5 1011.0 1011.5 1012.0 Arctic fox Owl monkey Mountain beaver Cow Grey wolf Goat Roe deer Guinea pig Verbet Chinchilla Ground squirrel Arctic ground squirrel African giant pouched rat Lesser short-tailed shrew Star-nosed mole Nine-banded armadillo Tree hyrax N.A. opossum Asian elephant Big brown bat Donkey Horse European hedgehog Patas monkey Cat Galago Genet Giraffe Gorilla Grey seal Rock hyrax-a Human African elephant Water opossum Rhesus monkey Kangaroo Yellow-bellied marmot Golden hamster Mouse Little brown bat Slow loris Okapi Rabbit Sheep Jaguar Chimpanzee Baboon Desert hedgehog Giant armadillo Rock hyrax-b Raccoon Rat E. American mole Mole rat Musk shrew Pig Echidna Brazilian tapir Tenrec Phalanger Tree shrew Red fox h,j,k,l,arrows,drag to pan i,o,+,-,scroll,shift-drag to zoom r,dbl-click to reset c for coordinates ? for help ? 10-7 10-6 10-5 10-4 10-3 10-2 10-1 100 101 102 103 104 105 106 107 108 109 1010 10-6.0 10-5.5 10-5.0 10-4.5 10-4.0 10-3.5 10-3.0 10-2.5 10-2.0 10-1.5 10-1.0 10-0.5 100.0 100.5 101.0 101.5 102.0 102.5 103.0 103.5 104.0 104.5 105.0 105.5 106.0 106.5 107.0 107.5 108.0 108.5 109.0 10-10 10-5 100 105 1010 10-6.0 10-5.8 10-5.6 10-5.4 10-5.2 10-5.0 10-4.8 10-4.6 10-4.4 10-4.2 10-4.0 10-3.8 10-3.6 10-3.4 10-3.2 10-3.0 10-2.8 10-2.6 10-2.4 10-2.2 10-2.0 10-1.8 10-1.6 10-1.4 10-1.2 10-1.0 10-0.8 10-0.6 10-0.4 10-0.2 100.0 100.2 100.4 100.6 100.8 101.0 101.2 101.4 101.6 101.8 102.0 102.2 102.4 102.6 102.8 103.0 103.2 103.4 103.6 103.8 104.0 104.2 104.4 104.6 104.8 105.0 105.2 105.4 105.6 105.8 106.0 106.2 106.4 106.6 106.8 107.0 107.2 107.4 107.6 107.8 108.0 108.2 108.4 108.6 108.8 109.0 Brain Body -1.00×10⁴ -8.00×10³ -6.00×10³ -4.00×10³ -2.00×10³ 0 2.00×10³ 4.00×10³ 6.00×10³ 8.00×10³ 1.00×10⁴ 1.20×10⁴ 1.40×10⁴ 1.60×10⁴ 1.80×10⁴ -8.000×10³ -7.500×10³ -7.000×10³ -6.500×10³ -6.000×10³ -5.500×10³ -5.000×10³ -4.500×10³ -4.000×10³ -3.500×10³ -3.000×10³ -2.500×10³ -2.000×10³ -1.500×10³ -1.000×10³ -5.000×10² 0 5.000×10² 1.000×10³ 1.500×10³ 2.000×10³ 2.500×10³ 3.000×10³ 3.500×10³ 4.000×10³ 4.500×10³ 5.000×10³ 5.500×10³ 6.000×10³ 6.500×10³ 7.000×10³ 7.500×10³ 8.000×10³ 8.500×10³ 9.000×10³ 9.500×10³ 1.000×10⁴ 1.050×10⁴ 1.100×10⁴ 1.150×10⁴ 1.200×10⁴ 1.250×10⁴ 1.300×10⁴ 1.350×10⁴ 1.400×10⁴ 1.450×10⁴ 1.500×10⁴ 1.550×10⁴ 1.600×10⁴ -1.0×10⁴ 0 1.0×10⁴ 2.0×10⁴ -8.000×10³ -7.500×10³ -7.000×10³ -6.500×10³ -6.000×10³ -5.500×10³ -5.000×10³ -4.500×10³ -4.000×10³ -3.500×10³ -3.000×10³ -2.500×10³ -2.000×10³ -1.500×10³ -1.000×10³ -5.000×10² 0 5.000×10² 1.000×10³ 1.500×10³ 2.000×10³ 2.500×10³ 3.000×10³ 3.500×10³ 4.000×10³ 4.500×10³ 5.000×10³ 5.500×10³ 6.000×10³ 6.500×10³ 7.000×10³ 7.500×10³ 8.000×10³ 8.500×10³ 9.000×10³ 9.500×10³ 1.000×10⁴ 1.050×10⁴ 1.100×10⁴ 1.150×10⁴ 1.200×10⁴ 1.250×10⁴ 1.300×10⁴ 1.350×10⁴ 1.400×10⁴ 1.450×10⁴ 1.500×10⁴ 1.550×10⁴ 1.600×10⁴ Arctic fox Owl monkey Mountain beaver Cow Grey wolf Goat Roe deer Guinea pig Verbet Chinchilla Ground squirrel Arctic ground squirrel African giant pouched rat Lesser short-tailed shrew Star-nosed mole Nine-banded armadillo Tree hyrax N.A. opossum Asian elephant Big brown bat Donkey Horse European hedgehog Patas monkey Cat Galago Genet Giraffe Gorilla Grey seal Rock hyrax-a Human African elephant Water opossum Rhesus monkey Kangaroo Yellow-bellied marmot Golden hamster Mouse Little brown bat Slow loris Okapi Rabbit Sheep Jaguar Chimpanzee Baboon Desert hedgehog Giant armadillo Rock hyrax-b Raccoon Rat E. American mole Mole rat Musk shrew Pig Echidna Brazilian tapir Tenrec Phalanger Tree shrew Red fox h,j,k,l,arrows,drag to pan i,o,+,-,scroll,shift-drag to zoom r,dbl-click to reset c for coordinates ? for help ? -7.00×10³ -6.00×10³ -5.00×10³ -4.00×10³ -3.00×10³ -2.00×10³ -1.00×10³ 0 1.00×10³ 2.00×10³ 3.00×10³ 4.00×10³ 5.00×10³ 6.00×10³ 7.00×10³ 8.00×10³ 9.00×10³ 1.00×10⁴ 1.10×10⁴ 1.20×10⁴ 1.30×10⁴ -6.000×10³ -5.500×10³ -5.000×10³ -4.500×10³ -4.000×10³ -3.500×10³ -3.000×10³ -2.500×10³ -2.000×10³ -1.500×10³ -1.000×10³ -5.000×10² 0 5.000×10² 1.000×10³ 1.500×10³ 2.000×10³ 2.500×10³ 3.000×10³ 3.500×10³ 4.000×10³ 4.500×10³ 5.000×10³ 5.500×10³ 6.000×10³ 6.500×10³ 7.000×10³ 7.500×10³ 8.000×10³ 8.500×10³ 9.000×10³ 9.500×10³ 1.000×10⁴ 1.050×10⁴ 1.100×10⁴ 1.150×10⁴ 1.200×10⁴ -1.0×10⁴ 0 1.0×10⁴ 2.0×10⁴ -6.000×10³ -5.800×10³ -5.600×10³ -5.400×10³ -5.200×10³ -5.000×10³ -4.800×10³ -4.600×10³ -4.400×10³ -4.200×10³ -4.000×10³ -3.800×10³ -3.600×10³ -3.400×10³ -3.200×10³ -3.000×10³ -2.800×10³ -2.600×10³ -2.400×10³ -2.200×10³ -2.000×10³ -1.800×10³ -1.600×10³ -1.400×10³ -1.200×10³ -1.000×10³ -8.000×10² -6.000×10² -4.000×10² -2.000×10² 0 2.000×10² 4.000×10² 6.000×10² 8.000×10² 1.000×10³ 1.200×10³ 1.400×10³ 1.600×10³ 1.800×10³ 2.000×10³ 2.200×10³ 2.400×10³ 2.600×10³ 2.800×10³ 3.000×10³ 3.200×10³ 3.400×10³ 3.600×10³ 3.800×10³ 4.000×10³ 4.200×10³ 4.400×10³ 4.600×10³ 4.800×10³ 5.000×10³ 5.200×10³ 5.400×10³ 5.600×10³ 5.800×10³ 6.000×10³ 6.200×10³ 6.400×10³ 6.600×10³ 6.800×10³ 7.000×10³ 7.200×10³ 7.400×10³ 7.600×10³ 7.800×10³ 8.000×10³ 8.200×10³ 8.400×10³ 8.600×10³ 8.800×10³ 9.000×10³ 9.200×10³ 9.400×10³ 9.600×10³ 9.800×10³ 1.000×10⁴ 1.020×10⁴ 1.040×10⁴ 1.060×10⁴ 1.080×10⁴ 1.100×10⁴ 1.120×10⁴ 1.140×10⁴ 1.160×10⁴ 1.180×10⁴ 1.200×10⁴ Brain

Scale transformations include: _sqrt, _log, _log2, _log10, _asinh for the x, y, color aesthetics, and _area for the size aesthetic.

using Printf
Diamonds = dataset("ggplot2","diamonds")
p3= plot(Diamonds, x=:Price, y=:Carat, Geom.histogram2d(xbincount=25, ybincount=25),
    Scale.x_continuous(format=:engineering) )
p4= plot(Diamonds, x=:Price, y=:Carat, Geom.histogram2d(xbincount=25, ybincount=25),
    Scale.x_continuous(format=:plain),
    Scale.y_sqrt(labels=y->@sprintf("%i", y^2)),
    Scale.color_log10(minvalue=1.0, maxvalue=10^4),
    Guide.yticks(ticks=sqrt.(0:5)) )
hstack(p3, p4)
Price -25000 -20000 -15000 -10000 -5000 0 5000 10000 15000 20000 25000 30000 35000 40000 45000 -20000 -18000 -16000 -14000 -12000 -10000 -8000 -6000 -4000 -2000 0 2000 4000 6000 8000 10000 12000 14000 16000 18000 20000 22000 24000 26000 28000 30000 32000 34000 36000 38000 40000 -20000 0 20000 40000 -20000 -19000 -18000 -17000 -16000 -15000 -14000 -13000 -12000 -11000 -10000 -9000 -8000 -7000 -6000 -5000 -4000 -3000 -2000 -1000 0 1000 2000 3000 4000 5000 6000 7000 8000 9000 10000 11000 12000 13000 14000 15000 16000 17000 18000 19000 20000 21000 22000 23000 24000 25000 26000 27000 28000 29000 30000 31000 32000 33000 34000 35000 36000 37000 38000 39000 40000 100 101 102 103 104 Count h,j,k,l,arrows,drag to pan i,o,+,-,scroll,shift-drag to zoom r,dbl-click to reset c for coordinates ? for help ? 0 1 2 3 4 5 Carat Price -25.0×10³ -20.0×10³ -15.0×10³ -10.0×10³ -5.00×10³ 0 5.00×10³ 10.0×10³ 15.0×10³ 20.0×10³ 25.0×10³ 30.0×10³ 35.0×10³ 40.0×10³ 45.0×10³ -20.0×10³ -18.0×10³ -16.0×10³ -14.0×10³ -12.0×10³ -10.0×10³ -8.00×10³ -6.00×10³ -4.00×10³ -2.00×10³ 0 2.00×10³ 4.00×10³ 6.00×10³ 8.00×10³ 10.0×10³ 12.0×10³ 14.0×10³ 16.0×10³ 18.0×10³ 20.0×10³ 22.0×10³ 24.0×10³ 26.0×10³ 28.0×10³ 30.0×10³ 32.0×10³ 34.0×10³ 36.0×10³ 38.0×10³ 40.0×10³ -20.×10³ 0 20.×10³ 40.×10³ -20.0×10³ -19.0×10³ -18.0×10³ -17.0×10³ -16.0×10³ -15.0×10³ -14.0×10³ -13.0×10³ -12.0×10³ -11.0×10³ -10.0×10³ -9.00×10³ -8.00×10³ -7.00×10³ -6.00×10³ -5.00×10³ -4.00×10³ -3.00×10³ -2.00×10³ -1.00×10³ 0 1.00×10³ 2.00×10³ 3.00×10³ 4.00×10³ 5.00×10³ 6.00×10³ 7.00×10³ 8.00×10³ 9.00×10³ 10.0×10³ 11.0×10³ 12.0×10³ 13.0×10³ 14.0×10³ 15.0×10³ 16.0×10³ 17.0×10³ 18.0×10³ 19.0×10³ 20.0×10³ 21.0×10³ 22.0×10³ 23.0×10³ 24.0×10³ 25.0×10³ 26.0×10³ 27.0×10³ 28.0×10³ 29.0×10³ 30.0×10³ 31.0×10³ 32.0×10³ 33.0×10³ 34.0×10³ 35.0×10³ 36.0×10³ 37.0×10³ 38.0×10³ 39.0×10³ 40.0×10³ 1.00×10⁰ 5.00×10³ 1.00×10⁴ 1.50×10⁴ Count h,j,k,l,arrows,drag to pan i,o,+,-,scroll,shift-drag to zoom r,dbl-click to reset c for coordinates ? for help ? -7 -6 -5 -4 -3 -2 -1 0 1 2 3 4 5 6 7 8 9 10 11 12 13 -6.0 -5.5 -5.0 -4.5 -4.0 -3.5 -3.0 -2.5 -2.0 -1.5 -1.0 -0.5 0.0 0.5 1.0 1.5 2.0 2.5 3.0 3.5 4.0 4.5 5.0 5.5 6.0 6.5 7.0 7.5 8.0 8.5 9.0 9.5 10.0 10.5 11.0 11.5 12.0 -10 0 10 20 -6.0 -5.8 -5.6 -5.4 -5.2 -5.0 -4.8 -4.6 -4.4 -4.2 -4.0 -3.8 -3.6 -3.4 -3.2 -3.0 -2.8 -2.6 -2.4 -2.2 -2.0 -1.8 -1.6 -1.4 -1.2 -1.0 -0.8 -0.6 -0.4 -0.2 0.0 0.2 0.4 0.6 0.8 1.0 1.2 1.4 1.6 1.8 2.0 2.2 2.4 2.6 2.8 3.0 3.2 3.4 3.6 3.8 4.0 4.2 4.4 4.6 4.8 5.0 5.2 5.4 5.6 5.8 6.0 6.2 6.4 6.6 6.8 7.0 7.2 7.4 7.6 7.8 8.0 8.2 8.4 8.6 8.8 9.0 9.2 9.4 9.6 9.8 10.0 10.2 10.4 10.6 10.8 11.0 11.2 11.4 11.6 11.8 12.0 Carat

Discrete Scales

AestheticScale.Guide.Theme palette
xx_discretexticks
yy_discreteyticks
colorcolor_discretecolorkey(tbd)
shapeshape_discreteshapekeypoint_shapes
sizesize_discrete–-point_size_min, point_size_max
size_discrete2sizekeydiscrete_sizemap
linestylelinestyle_discretelinekey (tbd)line_style
alphaalpha_discretealphakey (tbd)alphas
groupgroup_discrete
xgroupxgroup
ygroupygroup

e.g. Scale.shape_discrete(labels= , levels= , order= )

mtcars = dataset("datasets","mtcars")
 labeldict = Dict(4=>"four", 6=>"six", 8=>"eight")
p5 = plot(mtcars, x=:Cyl, color=:Cyl, Geom.histogram,
    Scale.x_discrete(levels=[4,6,8]), Scale.color_discrete(levels=[4,6,8]) )
p6 = plot(mtcars, x=:Cyl, color=:Cyl, Geom.histogram,
    Scale.x_discrete(labels=i->labeldict[i], levels=[8,6,4]),
    Scale.color_discrete(levels=[8,6,4]) )
hstack(p5, p6)
Cyl eight six four 8 6 4 Cyl h,j,k,l,arrows,drag to pan i,o,+,-,scroll,shift-drag to zoom r,dbl-click to reset c for coordinates ? for help ? -20 -15 -10 -5 0 5 10 15 20 25 30 35 -15 -14 -13 -12 -11 -10 -9 -8 -7 -6 -5 -4 -3 -2 -1 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 -20 0 20 40 -15.0 -14.5 -14.0 -13.5 -13.0 -12.5 -12.0 -11.5 -11.0 -10.5 -10.0 -9.5 -9.0 -8.5 -8.0 -7.5 -7.0 -6.5 -6.0 -5.5 -5.0 -4.5 -4.0 -3.5 -3.0 -2.5 -2.0 -1.5 -1.0 -0.5 0.0 0.5 1.0 1.5 2.0 2.5 3.0 3.5 4.0 4.5 5.0 5.5 6.0 6.5 7.0 7.5 8.0 8.5 9.0 9.5 10.0 10.5 11.0 11.5 12.0 12.5 13.0 13.5 14.0 14.5 15.0 15.5 16.0 16.5 17.0 17.5 18.0 18.5 19.0 19.5 20.0 20.5 21.0 21.5 22.0 22.5 23.0 23.5 24.0 24.5 25.0 25.5 26.0 26.5 27.0 27.5 28.0 28.5 29.0 29.5 30.0 Cyl 4 6 8 4 6 8 Cyl h,j,k,l,arrows,drag to pan i,o,+,-,scroll,shift-drag to zoom r,dbl-click to reset c for coordinates ? for help ? -20 -15 -10 -5 0 5 10 15 20 25 30 35 -15 -14 -13 -12 -11 -10 -9 -8 -7 -6 -5 -4 -3 -2 -1 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 -20 0 20 40 -15.0 -14.5 -14.0 -13.5 -13.0 -12.5 -12.0 -11.5 -11.0 -10.5 -10.0 -9.5 -9.0 -8.5 -8.0 -7.5 -7.0 -6.5 -6.0 -5.5 -5.0 -4.5 -4.0 -3.5 -3.0 -2.5 -2.0 -1.5 -1.0 -0.5 0.0 0.5 1.0 1.5 2.0 2.5 3.0 3.5 4.0 4.5 5.0 5.5 6.0 6.5 7.0 7.5 8.0 8.5 9.0 9.5 10.0 10.5 11.0 11.5 12.0 12.5 13.0 13.5 14.0 14.5 15.0 15.5 16.0 16.5 17.0 17.5 18.0 18.5 19.0 19.5 20.0 20.5 21.0 21.5 22.0 22.5 23.0 23.5 24.0 24.5 25.0 25.5 26.0 26.5 27.0 27.5 28.0 28.5 29.0 29.5 30.0

For discrete scales with a Theme palette, the order of levels and the order of the Theme palette match.

x, y = 0.55*rand(4), 0.55*rand(4)
plot( Coord.cartesian(xmin=0, ymin=0, xmax=1.0, ymax=1.0),
    layer(x=x, y=y, shape=["A"], alpha=["day","day","day","night"]),
    layer(x=1.0.-y[1:3], y=1.0.-x[1:3], shape=["B", "C","C"], alpha=["night"]),
    Scale.shape_discrete(levels=["A","B","C"]),
    Scale.alpha_discrete(levels=["day","night"]),
    Theme(discrete_highlight_color=identity, point_size=12pt,
   point_shapes=[Shape.circle, Shape.star1, Shape.star2], alphas=[0, 1.0],
         default_color="midnightblue" )
)
x -1.5 -1.0 -0.5 0.0 0.5 1.0 1.5 2.0 2.5 -1.0 -0.9 -0.8 -0.7 -0.6 -0.5 -0.4 -0.3 -0.2 -0.1 0.0 0.1 0.2 0.3 0.4 0.5 0.6 0.7 0.8 0.9 1.0 1.1 1.2 1.3 1.4 1.5 1.6 1.7 1.8 1.9 2.0 -1 0 1 2 -1.00 -0.95 -0.90 -0.85 -0.80 -0.75 -0.70 -0.65 -0.60 -0.55 -0.50 -0.45 -0.40 -0.35 -0.30 -0.25 -0.20 -0.15 -0.10 -0.05 0.00 0.05 0.10 0.15 0.20 0.25 0.30 0.35 0.40 0.45 0.50 0.55 0.60 0.65 0.70 0.75 0.80 0.85 0.90 0.95 1.00 1.05 1.10 1.15 1.20 1.25 1.30 1.35 1.40 1.45 1.50 1.55 1.60 1.65 1.70 1.75 1.80 1.85 1.90 1.95 2.00 A B C Shape h,j,k,l,arrows,drag to pan i,o,+,-,scroll,shift-drag to zoom r,dbl-click to reset c for coordinates ? for help ? -1.5 -1.0 -0.5 0.0 0.5 1.0 1.5 2.0 2.5 -1.0 -0.9 -0.8 -0.7 -0.6 -0.5 -0.4 -0.3 -0.2 -0.1 0.0 0.1 0.2 0.3 0.4 0.5 0.6 0.7 0.8 0.9 1.0 1.1 1.2 1.3 1.4 1.5 1.6 1.7 1.8 1.9 2.0 -1 0 1 2 -1.00 -0.95 -0.90 -0.85 -0.80 -0.75 -0.70 -0.65 -0.60 -0.55 -0.50 -0.45 -0.40 -0.35 -0.30 -0.25 -0.20 -0.15 -0.10 -0.05 0.00 0.05 0.10 0.15 0.20 0.25 0.30 0.35 0.40 0.45 0.50 0.55 0.60 0.65 0.70 0.75 0.80 0.85 0.90 0.95 1.00 1.05 1.10 1.15 1.20 1.25 1.30 1.35 1.40 1.45 1.50 1.55 1.60 1.65 1.70 1.75 1.80 1.85 1.90 1.95 2.00 y

Gadfly defaults

If you don't supply Scales or Guides, Gadfly will make an educated guess.

gasoline = dataset("Ecdat", "Gasoline")
plot(gasoline, x=:Year, y=:LGasPCar, color=:Country, Geom.point, Geom.line)
Year 1935 1940 1945 1950 1955 1960 1965 1970 1975 1980 1985 1990 1995 2000 2005 1940 1942 1944 1946 1948 1950 1952 1954 1956 1958 1960 1962 1964 1966 1968 1970 1972 1974 1976 1978 1980 1982 1984 1986 1988 1990 1992 1994 1996 1998 2000 1940 1960 1980 2000 1940 1941 1942 1943 1944 1945 1946 1947 1948 1949 1950 1951 1952 1953 1954 1955 1956 1957 1958 1959 1960 1961 1962 1963 1964 1965 1966 1967 1968 1969 1970 1971 1972 1973 1974 1975 1976 1977 1978 1979 1980 1981 1982 1983 1984 1985 1986 1987 1988 1989 1990 1991 1992 1993 1994 1995 1996 1997 1998 1999 2000 JAPAN NETHERLA NORWAY SPAIN SWEDEN SWITZERL TURKEY U.K. U.S.A. AUSTRIA BELGIUM CANADA DENMARK FRANCE GERMANY GREECE IRELAND ITALY Country h,j,k,l,arrows,drag to pan i,o,+,-,scroll,shift-drag to zoom r,dbl-click to reset c for coordinates ? for help ? -2 -1 0 1 2 3 4 5 6 7 8 9 10 11 12 -1.0 -0.5 0.0 0.5 1.0 1.5 2.0 2.5 3.0 3.5 4.0 4.5 5.0 5.5 6.0 6.5 7.0 7.5 8.0 8.5 9.0 9.5 10.0 10.5 11.0 -5 0 5 10 15 -1.0 -0.8 -0.6 -0.4 -0.2 0.0 0.2 0.4 0.6 0.8 1.0 1.2 1.4 1.6 1.8 2.0 2.2 2.4 2.6 2.8 3.0 3.2 3.4 3.6 3.8 4.0 4.2 4.4 4.6 4.8 5.0 5.2 5.4 5.6 5.8 6.0 6.2 6.4 6.6 6.8 7.0 7.2 7.4 7.6 7.8 8.0 8.2 8.4 8.6 8.8 9.0 9.2 9.4 9.6 9.8 10.0 10.2 10.4 10.6 10.8 11.0 LGasPCar

We could have added Scale.x_discrete explicitly, but this is detected and the right default is chosen. This is the case with most of the elements in the grammar. When we've omitted Scale.x_continuous and Scale.y_continuous in the plots above, as well as Coord.cartesian, and guide elements such as Guide.xticks, Guide.xlabel and so on, Gadfly tries to fill in the gaps with reasonable defaults.

Rendering

Gadfly uses a custom graphics library called Compose, which is an attempt at a more elegant, purely functional take on the R grid package. It allows mixing of absolute and relative units and complex coordinate transforms. The primary backend is a native SVG generator (almost native: it uses pango to precompute text extents), though there is also a Cairo backend for PDF and PNG. See Backends for more details.

Building graphics declaratively let's you do some fun things. Like stick two plots together:

fig1a = plot(iris, x=:SepalLength, y=:SepalWidth, Geom.point)
fig1b = plot(iris, x=:SepalWidth, Geom.bar)
fig1 = hstack(fig1a, fig1b)
SepalWidth -4 -3 -2 -1 0 1 2 3 4 5 6 7 8 9 10 -3.0 -2.5 -2.0 -1.5 -1.0 -0.5 0.0 0.5 1.0 1.5 2.0 2.5 3.0 3.5 4.0 4.5 5.0 5.5 6.0 6.5 7.0 7.5 8.0 8.5 9.0 -5 0 5 10 -3.0 -2.8 -2.6 -2.4 -2.2 -2.0 -1.8 -1.6 -1.4 -1.2 -1.0 -0.8 -0.6 -0.4 -0.2 0.0 0.2 0.4 0.6 0.8 1.0 1.2 1.4 1.6 1.8 2.0 2.2 2.4 2.6 2.8 3.0 3.2 3.4 3.6 3.8 4.0 4.2 4.4 4.6 4.8 5.0 5.2 5.4 5.6 5.8 6.0 6.2 6.4 6.6 6.8 7.0 7.2 7.4 7.6 7.8 8.0 8.2 8.4 8.6 8.8 9.0 h,j,k,l,arrows,drag to pan i,o,+,-,scroll,shift-drag to zoom r,dbl-click to reset c for coordinates ? for help ? -200 -150 -100 -50 0 50 100 150 200 250 300 350 -150 -140 -130 -120 -110 -100 -90 -80 -70 -60 -50 -40 -30 -20 -10 0 10 20 30 40 50 60 70 80 90 100 110 120 130 140 150 160 170 180 190 200 210 220 230 240 250 260 270 280 290 300 -200 0 200 400 -150 -145 -140 -135 -130 -125 -120 -115 -110 -105 -100 -95 -90 -85 -80 -75 -70 -65 -60 -55 -50 -45 -40 -35 -30 -25 -20 -15 -10 -5 0 5 10 15 20 25 30 35 40 45 50 55 60 65 70 75 80 85 90 95 100 105 110 115 120 125 130 135 140 145 150 155 160 165 170 175 180 185 190 195 200 205 210 215 220 225 230 235 240 245 250 255 260 265 270 275 280 285 290 295 300 SepalLength -1 0 1 2 3 4 5 6 7 8 9 10 11 12 13 0.0 0.5 1.0 1.5 2.0 2.5 3.0 3.5 4.0 4.5 5.0 5.5 6.0 6.5 7.0 7.5 8.0 8.5 9.0 9.5 10.0 10.5 11.0 11.5 12.0 0 5 10 15 0.0 0.2 0.4 0.6 0.8 1.0 1.2 1.4 1.6 1.8 2.0 2.2 2.4 2.6 2.8 3.0 3.2 3.4 3.6 3.8 4.0 4.2 4.4 4.6 4.8 5.0 5.2 5.4 5.6 5.8 6.0 6.2 6.4 6.6 6.8 7.0 7.2 7.4 7.6 7.8 8.0 8.2 8.4 8.6 8.8 9.0 9.2 9.4 9.6 9.8 10.0 10.2 10.4 10.6 10.8 11.0 11.2 11.4 11.6 11.8 12.0 h,j,k,l,arrows,drag to pan i,o,+,-,scroll,shift-drag to zoom r,dbl-click to reset c for coordinates ? for help ? -1.0 -0.5 0.0 0.5 1.0 1.5 2.0 2.5 3.0 3.5 4.0 4.5 5.0 5.5 6.0 6.5 7.0 7.5 -0.6 -0.4 -0.2 0.0 0.2 0.4 0.6 0.8 1.0 1.2 1.4 1.6 1.8 2.0 2.2 2.4 2.6 2.8 3.0 3.2 3.4 3.6 3.8 4.0 4.2 4.4 4.6 4.8 5.0 5.2 5.4 5.6 5.8 6.0 6.2 6.4 6.6 6.8 7.0 -2.5 0.0 2.5 5.0 7.5 -0.5 -0.4 -0.3 -0.2 -0.1 0.0 0.1 0.2 0.3 0.4 0.5 0.6 0.7 0.8 0.9 1.0 1.1 1.2 1.3 1.4 1.5 1.6 1.7 1.8 1.9 2.0 2.1 2.2 2.3 2.4 2.5 2.6 2.7 2.8 2.9 3.0 3.1 3.2 3.3 3.4 3.5 3.6 3.7 3.8 3.9 4.0 4.1 4.2 4.3 4.4 4.5 4.6 4.7 4.8 4.9 5.0 5.1 5.2 5.3 5.4 5.5 5.6 5.7 5.8 5.9 6.0 6.1 6.2 6.3 6.4 6.5 6.6 6.7 6.8 6.9 7.0 SepalWidth

Ultimately this will make more complex visualizations easier to build. For example, facets, plots within plots, and so on. See Compositing for more details.

Interactivity

One advantage of generating our own SVG is that we can annotate our SVG output and embed Javascript code to provide some level of dynamism. Though not a replacement for full-fledged custom interactive visualizations of the sort produced by D3, this sort of mild interactivity can improve a lot of standard plots.

The fuel efficiency plot is made more clear by toggling off some of the countries, for example. To do so, first render the plot using the SVGJS backend, which was not used to generate this webpage but is the default at the REPL, then simply click or shift-click in the colored squares in the table of keys to the right.

One can also zoom in and out by pressing the shift key while either scrolling the mouse wheel or clicking and dragging a box. Should your mouse not work, try the plus, minus, I, and O, keys. Panning is similarly easy: click and drag without depressing the shift key, or use the arrow keys. For Vim enthusiasts, the H, J, K, and L keys pan as expected. To reset the plot to it's initial state, double click it or hit R. Lastly, press C to toggle on and off a numerical display of the cursor coordinates.