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")
Row SepalLength SepalWidth PetalLength PetalWidth Species 1 5.1 3.5 1.4 0.2 setosa 2 4.9 3.0 1.4 0.2 setosa 3 4.7 3.2 1.3 0.2 setosa 4 4.6 3.1 1.5 0.2 setosa 5 5.0 3.6 1.4 0.2 setosa 6 5.4 3.9 1.7 0.4 setosa ... ... ... ... ... ...
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.
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.
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()
.
Aesthetic Scale. Guide. Theme palette x
x_continuous
xticks
y
y_continuous
yticks
color
color_continuous
colorkey
(tbd) size
size_continuous
–- point_size_min
, point_size_max
size_radius
sizekey
continuous_sizemap
alpha
alpha_continuous
alphakey (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
Aesthetic Scale. Guide. Theme palette x
x_discrete
xticks
y
y_discrete
yticks
color
color_discrete
colorkey
(tbd) shape
shape_discrete
shapekey
point_shapes
size
size_discrete
–- point_size_min
, point_size_max
size_discrete2
sizekey
discrete_sizemap
linestyle
linestyle_discrete
linekey (tbd) line_style
alpha
alpha_discrete
alphakey (tbd) alphas
group
group_discrete
xgroup
xgroup
ygroup
ygroup
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
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.
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.
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.