Gadfly is a plotting and data visualization system written in Julia.
It's influenced heavily by Leland Wilkinson's book The Grammar of Graphics and Hadley Wickham's refinment of that grammar in ggplot2.
It renders publication quality graphics to PNG, Postscript, PDF, SVG. The SVG backend uses embedded javascript, powered by Snap.svg to add interactivity like panning, zooming, and toggling.
Check out the manual for more details and examples.
From the Julia REPL a reasonably up to date version can be installed with
Pkg.add("Gadfly")
This will likely result in two dozen or so other packages also being installed.
Gadfly works best with the C libraries cairo, pango, and fontconfig installed.
The PNG, PS, and PDF backends require cairo, but without it the SVG backends
(SVG
and SVGJS
) are still available.
Complex layouts involving text are also somewhat more accurate when pango and fontconfig are available.
Julia's Cairo bindings can be installed with
Pkg.add("Cairo")
All interaction with Gadfly is through the plot
function, which takes three
major forms.
plot(data::AbstractDataFrame, elements::Element...; mapping...)
This form is the standard "grammar of graphics" method of plotting. Data is supplied in the form of a dataframe, columns of the data are bound to aesthetics, and plot elements including scales, coordinates, statistics, guides, and geometries are added to the plot.
All of the examples that follow will be plotting data from RDatasets.
To render these plots to a file, call draw
on the resulting plot.
draw(SVG("myplot.svg", 6inch, 3inch), plot(...))
A few examples now.
# E.g.
plot(dataset("datasets", "iris"),x="SepalLength", y="SepalWidth", Geom.point)
# E.g.
plot(dataset("car", "SLID"), x="Wages", color="Language", Geom.histogram)
A catalog of plot elements is given later in this document.
plot(elements::Element...; mapping...)
Along with the orthodox invocation of plot
, some relaxed invocations of the
grammar exist as a "slang of graphics". This form of plot
omits the the data
frame. Instead, plain old arrays are bound to aesthetics.
# E.g.
plot(x=collect(1:100), y=sort(rand(100)))
If no geometry is specified, like in the example above, a Geom.point
is stuck
into your plot.
This plot
otherwise works the same. We might want to name these axis, for
example.
# E.g.
plot(x=collect(1:100), y=sort(rand(100)),
Guide.XLabel("Index"), Guide.YLabel("Step"))
plot(f::Function, a, b, elements::Element...)
plot(fs::Array, a, b, elements::Element...)
Some special forms of plot
exist for quickly generating 2d plots of functions.
# E.g.
plot([sin, cos], 0, 25)
Plot elements in Gadfly are statistics, scales, geometries, and guides. Each operates on data bound to aesthetics, but in different ways.
Statistics are functions taking as input one or more aesthetics, operating on
those values, then output to one or more aesthetics. For example, drawing of
boxplots typically uses the boxplot statistic (Stat.boxplot) that takes as input
the x
and y
aesthetic, and outputs the middle, and upper and lower hinge,
and upper and lower fence aesthetics.
Scales, similarly to statistics, apply a transformation to the original data,
typically mapping one aesthetic to the same aesthetic, while retaining the
original value. The Scale.x_log10
aesthetic maps the x
aesthetic back to
the x
aesthetic after applying a log10 transformation, but keeps track of
the original value so that data points are properly identified.
Finally, geometries are responsible for actually doing the drawing. A geometry
takes as input one or more aesthetics, and used data bound to these aesthetics
to draw things. The Geom.point
geometry draws points using the x
and y
aesthetics, the Geom.line
geometry draws lines, and so on.
Very similar to geometries are guides, which draw graphics supporting the actual visualization, such as axis ticks and labels and color keys. The major distinction is that geometries always draw within the rectangular plot frame, while guides have some special layout considerations.
Gadfly plots can be rendered to number of formats. Without cairo, or any
non-julia libraries, it can produce SVG. Installing cairo gives you access to
the PNG
, PDF
, and PS
backends. Rendering to a backend works the same for
any of these.
some_plot = plot(x=[1,2,3], y=[4,5,6])
draw(PNG("myplot.png", 6inch, 3inch), some_plot)
The SVGJS
backend writes SVG with embedded javascript. There are a couple
subtleties with using the output from this backend.
Drawing to the backend works like any other.
draw(SVGJS("mammals.js.svg", 6inch, 6inch), p)
If included with an <img>
tag, it will display as a static SVG image.
<img src="mammals.js.svg"/>
For the interactive javascript features to be enabled, the output either needs to be included inline in the HTML page, or included with an object tag, like.
<object data="mammals.js.svg" type="image/svg+xml"></object>
This is a new and fairly complex piece of software. Filing an issue to report a bug, counterintuitive behavior, or even to request a feature is extremely valuable in helping me prioritize what to work on, so don't hestitate.