This vignette details all the plotting options available in arphit
. If you are learning how to use arphit
, you should read the getting started guide first.
library(arphit) set.seed(42)
simple_data <- data.frame(date = seq.Date(from = as.Date("2000-03-01"), length.out = 10, by = "quarter"), y1 = rnorm(10), y2 = rnorm(10), y3 = rnorm(10), y4 = rnorm(10)) long_data <- data.frame(date = rep(seq.Date(from = as.Date("2000-03-01"), length.out = 10, by = "quarter"), 2), y1 = rnorm(20), y2 = rnorm(20), group_var = c(rep("A", 10), rep("B", 10))) scatter_data <- data.frame(x = rnorm(10), y = rnorm(10))
Here we create a time series starting in 2000Q1 (frequency = 4
means quarterly) with 10 random observations for two variables: x1
and x2
.
ts_data <- ts(data.frame(x1 = rnorm(10), x2 = rnorm(10)), frequency = 4, start = c(2000, 1))
There are ten supported layouts, with up to 8 panels. Right hand side axes count as separate panels in some layouts. Panels are numbered from left to right, top to bottom.
layout
. Despite its name this layout has two panels. Panel "1" corresponds to the left axis; panel "2" corresponds to the right axis.arphitgg(layout = "1")
library(arphit) agg_draw(arphitgg(layout = "1"), filename = "layout_1.png")
knitr::include_graphics("layout_1.png")
arphitgg(layout = "2v")
agg_draw(arphitgg(layout = "2v"), filename = "layout_2v.png")
knitr::include_graphics("layout_2v.png")
arphitgg(layout = "2h")
agg_draw(arphitgg(layout = "2h"), filename = "layout_2h.png")
knitr::include_graphics("layout_2h.png")
arphitgg(layout = "2b2")
agg_draw(arphitgg(layout = "2b2"), filename = "layout_2b2.png")
knitr::include_graphics("layout_2b2.png")
arphitgg(layout = "3v")
agg_draw(arphitgg(layout = "3v"), filename = "layout_3v.png")
knitr::include_graphics("layout_3v.png")
arphitgg(layout = "3h")
agg_draw(arphitgg(layout = "3h"), filename = "layout_3h.png")
knitr::include_graphics("layout_3h.png")
arphitgg(layout = "3b2")
agg_draw(arphitgg(layout = "3b2"), filename = "layout_3b2.png")
knitr::include_graphics("layout_3b2.png")
arphitgg(layout = "4h")
agg_draw(arphitgg(layout = "4h"), filename = "layout_4h.png")
knitr::include_graphics("layout_4h.png")
arphitgg(layout = "4b2")
agg_draw(arphitgg(layout = "4b2"), filename = "layout_4b2.png")
knitr::include_graphics("layout_4b2.png")
arphitgg(data.frame(x=1:10), agg_aes(x,x), layout = "1h") + agg_col()
p <- arphitgg(data.frame(x=1:10), agg_aes(x,x), layout = "1h") + agg_col() agg_draw(p, filename = "layout_1h.png")
knitr::include_graphics("layout_1h.png")
If you want a larger, portrait size layout, simply pass in portait = TRUE
. This works with any of the layouts.
p <- arphitgg(portrait = TRUE)
agg_draw(p, filename = "layout_portrait.png")
knitr::include_graphics("layout_portrait.png")
You can also manually specify the plot size if you want greater control. This size is for the whole graph - i.e. the size of the graph, not the size of a panel. Units are inches (the graphs have been scaled to half original size when included in this document).
p <- arphitgg(plotsize = c(2,10))
agg_draw(p, filename = "plotsize.png")
knitr::include_graphics("plotsize.png")
An aesthetic is the definition of a layer. It tells arphit how to display the data.
x
and y
The x
and y
variables speak for themselves. They must be variables
in your dataset. (x
values can be categorical). Aesthetics can also be
expressions, rather than single variables - see the section on tidy evaluation
below.
p <- arphitgg() + agg_line(data = simple_data, aes = agg_aes(x = date, y = y1))
agg_draw(p, filename = "no-group-aes.png")
knitr::include_graphics("no-group-aes.png")
If your data are a ts
, the x
aesthetic does not need to specified, it is automatically the dates in the time series.
Aesthetics inherit from their parent. That is, if you omit part of an aesthetic in the definition of a layer, it will inherit from the parent (if it exists). If you specify both a parent aesthetic and a layer aesthetic, the layer aesthetic overrides.
In this example, the whole aesthetic is inherited:
p <- arphitgg(data = simple_data, aes = agg_aes(x = date, y = y1)) + agg_line()
agg_draw(p, filename = "inherit-aes-all.png")
knitr::include_graphics("inherit-aes-all.png")
In this example, we specify thex
aesthetic in the parent, but specify the y aesthetic in the layer. This is helpful if, for instance, you have many y
variables you want to plot that all have the same x
variable.
p <- arphitgg(data = simple_data, aes = agg_aes(x = date)) + agg_line(aes = agg_aes(y = y1))
agg_draw(p, filename = "inherit-aes-some.png")
knitr::include_graphics("inherit-aes-some.png")
An aesthetic can also specify a group
variable. This is used when your data is in long form and you have multiple observations on each x
observation, corresponding to different variables. For instance, x
might be the date column, y
the column containing observations of the unemployment rate and group
the column containing state identifiers.
p <- arphitgg() + agg_line(data = long_data, aes = agg_aes(x = date, y = y1, group = group_var))
agg_draw(p, filename = "group-aes.png")
knitr::include_graphics("group-aes.png")
candle <- data.frame(x=rep(letters[1:10],3),y=1:30) p <- arphitgg() + agg_line(data = candle, aes = agg_aes(x = x, y = y, group = x))
agg_draw(p, filename = "group-by-x.png")
knitr::include_graphics("group-by-x.png")
An aesthetic can also specify a facet
variable. facet
s work like group
s, except that facets are split across panels (and so layers ignore if you give them a panel).
p <- arphitgg() + agg_line(data = long_data, aes = agg_aes(x = date, y = y1, facet = group_var))
agg_draw(p, filename = "facet.png")
knitr::include_graphics("facet.png")
Data can have both group
s and facet
s.
facet_data <- data.frame(x = rep(c(1,2),4), y = rnorm(8), age = c(rep("A", 4), rep("B", 4)), sex = rep(c("F","F","M","M"), 2)) p <- arphitgg() + agg_line(data = facet_data, aes = agg_aes(x = x, y = y, group = sex, facet = age))
agg_draw(p, filename = "facet-group.png")
knitr::include_graphics("facet-group.png")
By default, graphs are ordered by the value of their x-ticks (that is, either numerically or alphabetically, depending on what your x-ticks are).
You can instead specify a variable to order the graph by using the order
part of the aesthetic.
Ordering a bar chart by value:
order_data <- data.frame(x=letters[1:10], y=rnorm(10)) p <- arphitgg(order_data, agg_aes(x=x,y=y,order=y))
agg_draw(p, filename = "aes-order-value.png")
knitr::include_graphics("aes-order-value.png")
If you have groups and want to order by value, you need to specify which group's value you want to use as the order. This will apply that order to every group.
order_data <- data.frame(x=letters[1:10], y=rnorm(10), group = c(rep("A",5),rep("B",5))) p <- arphitgg(order_data, agg_aes(x=x,y=y,group=group,order=A))
agg_draw(p, filename = "aes-order-value-group.png")
knitr::include_graphics("aes-order-value-group.png")
You can order in descending value using the desc
function - see the section
on tidy evaluation below. E.g.:
order_data <- data.frame(x=letters[1:10], y=rnorm(10)) p <- arphitgg(order_data, agg_aes(x=x,y=y,order=dplyr::desc(y))) + agg_col()
agg_draw(p, filename = "aes-order-value-desc.png")
knitr::include_graphics("aes-order-value-desc.png")
A third alternative way is to use another variable to define the order. In this
example we take data and order it by a variable order
that is the reverse
of the x variable.
order_data <- data.frame(x = rep(letters[1:10], 2), y = rep(1:10, 2), group = c(rep("A", 10), rep("B", 10)), order = rep(letters[10:1], 2), stringsAsFactors = FALSE) p <- arphitgg(order_data, agg_aes(x=x,y=y,group=group,order=order)) + agg_col(stacked = FALSE)
agg_draw(p, filename = "aes-order.png")
knitr::include_graphics("aes-order.png")
You can use a separate order variable with groups, but the ordering variable must uniquely associate with each x value and this ordering must be consistent across all groups. If not, otherwise the ordering of x values is ambiguous.
You can also control the order of bars within a layer (i.e. which bar appears
closest to the axis) using the argument reorder_bars
to agg_col
. This is covered
in detail under the agg_col
section of the section 'Layers' below.
Aesthetics support tidy evaluation. This means that your aesthetic can actually be an expression, which is evaluated in the environment of your data. This means you can undertake transformations of your data within how you define the aesthetic. The most common use for this is to order graphs in descending order:
order_data <- data.frame(x=letters[1:10], y=rnorm(10), group = c(rep("A",5),rep("B",5))) p <- arphitgg(order_data, agg_aes(x=x,y=y,group=group,order=desc(A)))
#this is created above knitr::include_graphics("aes-order-value-desc.png")
But you can use any expression you like, in any part of the aesthetic. For instance, we can easily create a quadratic:
p <- arphitgg(data.frame(x=-10:10), agg_aes(x=x,y=x^2))+agg_line()
agg_draw(p, filename = "aes-tidy-quadratic.png")
knitr::include_graphics("aes-tidy-quadratic.png")
Or we could group by a combination of two variables:
two_group_data <- data.frame(x=rep(c(1,2),4), y=rnorm(8), g1=c(rep("a",4),rep("b",4)), g2=rep(c(1,1,2,2),2))
Here g1
and g2
together define a unique group, so we set the group aesthetic
to the interaction of both variables:
p <- arphitgg(two_group_data, agg_aes(x=x,y=y,group=paste(g1,g2))) + agg_col(stacked = FALSE) + agg_legend()
agg_draw(p, filename = "aes-tidy-double-group.png")
knitr::include_graphics("aes-tidy-double-group.png")
A layer is a series (or group of series) built from the same aesthetic. In arphit
, layers must be assigned to a panel. You can have more than one layer per panel.
All layer types have four common arguments, and some layers have extra options to define their look:
NB: Layers will inherit data and aesthetic from their parent if omitted. This is helpful if you want to define multiple layers from the one dataset. (Example below)
You can assign the same layer to multiple panels in one call by specifying a vector
of panel names. E.g. panel = c("1","2")
.
There are three types of basic layers, agg_line
, agg_col
, and agg_point
. These are used nearly identically to produce line, column, and scatter graphs respectively. There are also two types of specialised layers, discussed below.
p <- arphitgg(layout = "2h") + agg_line(data = long_data, aes = agg_aes(x = date, y = y1, group = group_var), panel = "1") + agg_col(data = long_data, aes = agg_aes(x = date, y = y2, group = group_var), panel = "3")
agg_draw(p, filename = "layers.png")
knitr::include_graphics("layers.png")
p <- arphitgg(layout = "1") + agg_point(data = data.frame(x = rnorm(10), y = rnorm(10)), aes = agg_aes(x = x, y = y), panel = "1")
agg_draw(p, filename = "scatter.png")
knitr::include_graphics("scatter.png")
Layers will inherit data and aesthetic (or parts of the aesthetic) if these are left null in the layer specification. This is handy to save you from having to repeat yourself:
p <- arphitgg(long_data, aes = agg_aes(x = date, group = group_var), layout = "2h") + agg_line(aes = agg_aes(y = y1), panel = "1") + agg_col(aes = agg_aes(y = y2), panel = "3")
agg_draw(p, filename = "inherit.png")
knitr::include_graphics("inherit.png")
agg_line
layers convert data and an aesthetic into line series in the chosen panel (or, panels if you set a facet variable in the aesthetic).
There are 7 options for line layers. What the options do is covered in more detail below.
data
)aes
)colour
)pch
)lty
)lwd
)pointsize
). Only has any effect if pch
is not NA.panel
). This is ignored if the aesthetic defines a facet variable.agg_col
layers plot data as a vertical column graph. They have 6 options. What the options do is covered in more detail below.
aes
)data
)colour
)barcol
)panel
). This is ignored if the aesthetic defines a facet variable.stacked
). This is a global option; you cannot combine stacked and grouped layers.You can use the layout option layout = "1h"
to create horizontal bar graphs -
where the x axis on the left side. This type of graph has only one panel. (NB: You
can make any layer type a horizontal graph, but it is most useful for column
graphs.) See the section "Layouts and panels" above.
Bars are ordered left-to-right (if not stacked) or closest to axis (if stacked)
based on the order they are added to the graph. For layers with group aesthetics,
the bars within a layer are ordered alphabetically;^[Series without a name (i.e.
value of grouping variable equal to NA
) appear last.] but later layers always
appear after earlier layers:
p <- arphitgg() + agg_col(data = simple_data, aes = agg_aes(x = date, y = y1), stacked = FALSE) + # appears left-most agg_col(data = long_data, aes = agg_aes(x = date, y = y2, group = group_var), stacked = FALSE) + # appears to the right the first layer, with the groups in alphabetical order agg_legend()
agg_draw(p, filename = "bar-order.png")
knitr::include_graphics("bar-order.png")
You can manually control the order of bars using the argument reorder_bars
. All bar series
added to a panel up to that point can be reordered within that layer. As such, you
should always reorder in the last layer you add to a panel:
p <- arphitgg() + agg_col(data = simple_data, aes = agg_aes(x = date, y = y1), stacked = FALSE) + # appears left-most agg_col(data = long_data, aes = agg_aes(x = date, y = y2, group = group_var), stacked = FALSE, reorder_bars = c("B","y1", "A")) + # reorder the series so that B appears left-most then y1 (added in a previous layer) and then A agg_legend()
agg_draw(p, filename = "bar-reorder.png")
knitr::include_graphics("bar-reorder.png")
You do not have to specify a full order. If you leave out series, these are ordered after those you manually order (in alphabetical order). You will get a warning telling you this (in case it was a mistake).
agg_point
layers are just a wrapper around agg_line
that set the line to NA, and the point marker (pch
) to 19
for solid dots. Naturally, this layer type is best for scatter graphs, as they quicker and easier than constructing your own agg_line
layer.
agg_point
has only 5 options: Data (data
), aesthetic (aes
), panel (panel
), colour for the markers (colour
) and a size for the points (pointsize
). As with other layer types, data and aesthetic (including parts of an aesthetic) will be inherited from the parent if omitted.
agg_step
layers are a special type of line layer that 'step' to each point rather
than connecting the two with a straight line. What this means is that the line is
held constant from the previous observation and then 'steps' up to the next
observation. The final observation has only the vertical part of the step.
step_data <- data.frame(x=1:10,y=1:10) p <- arphitgg(step_data, aes = agg_aes(x = x, y = y)) + agg_step()
agg_draw(p, filename = "step.png")
knitr::include_graphics("step.png")
Otherwise, agg_step
layers are identical to line layers. They have same arguments
and attributes (such as colour, line type etc).
agg_waterfall
creates waterfall graphs. These are a specialised bar graph where
the bars (except for the last one) step from where the previous one ends. These work
largely identically to agg_col
layers. The first and last bars (determined by
the order aesthetic) are always anchored to zero; but every other colubarmn is anchored
to where the previous bar ended. X-ticks can have multiple observations, using
groups. In this case, the net of the bar is where the next bar(s) start.
waterfall_data <- data.frame(x = letters[1:6], y = c(1,0.5,-0.2,0.3,-0.5,1.1)) p <- arphitgg(waterfall_data, agg_aes(x,y)) + agg_waterfall()
agg_draw(p, filename = "waterfall.png")
knitr::include_graphics("waterfall.png")
Waterfall layers work with groups. This can be helpful for highlighting positive and negative changes, but can also be used when you have multiple observations per x-tick:
library(dplyr) waterfall_data <- data.frame(x = letters[1:6], y = c(1,0.5,-0.2,0.3,-0.5,1.1)) p <- arphitgg(waterfall_data, agg_aes(x = x, y = y, group = case_when(x == "a" ~ "start", x == "f" ~ "end", y > 0 ~ "plus", y <=0 ~ "minus"))) + agg_waterfall(colour = c("grey","red","blue","black"))
agg_draw(p, filename = "waterfall-plusminus.png")
knitr::include_graphics("waterfall-plusminus.png")
data <- data.frame(x = c('start','a','a','b','b','end'), y = c(1, 0.5, -0.4, 0.2, 0.1, 1.4), group = c(1, 2, 3, 2, 3, 4), order = c(1,2,2,3,3,4)) p <- arphitgg(data) + agg_waterfall(agg_aes(x=x,y=y,group=group,order=order))
agg_draw(p, filename = "waterfall-group.png")
knitr::include_graphics("waterfall-group.png")
Specifying line, bar or point (depending on layer type) colours for series is done when creating a layer. For instance:
p <- arphitgg() + agg_line(data = simple_data, aes = agg_aes(x = date, y = y1), colour = RBA["Red1"])
agg_draw(p, filename = "simplecolour.png")
knitr::include_graphics("simplecolour.png")
This colour is applied to all series in the layer. This is less helpful when you have a group variable, since they will all show up as the same colour (which is unlikely to be what you want). E.g. this is not helpful:
p <- arphitgg() + agg_line(data = long_data, aes = agg_aes(x = date, y = y1, group = group_var), colour = RBA["Red1"])
agg_draw(p, filename = "group-single-colour.png")
knitr::include_graphics("group-single-colour.png")
To specify for different colours for different series in a grouped layer, you can instead specify a vector of colours:
p <- arphitgg() + agg_line(data = long_data, aes = agg_aes(x = date, y = y1, group = group_var), colour = c(RBA["Red1"], RBA["Blue4"]))
agg_draw(p, filename = "group-multi-colour.png")
knitr::include_graphics("group-multi-colour.png")
(NB: arphit
will cycle through the supplied vector colours if there aren't enough in the vector to cover the number of series in the layer.)
To see the full list of availble colours type vignette("rba-colours", package = "arphit")
.
Alternatively, you can use any colour that R recognises.
If you don't specify colours, arphit cycles through a set of default colours. Should you need to (e.g. for labels) you can access the default colours using the alias RBA["Default1"]
etc.
If you want to define your own set of default colours to be used set the option arphit.user_colours
with a vector of colours. Putting this into your .Rprofile
is sensible.
options(arphit.user_colours = c(RBA["Red1"],RBA["Blue10"],RBA["Olive1"]))
pch
allows you to add markers to your series. These directly follow the R options. These are specified like colours (setting one will apply it to all series in the layer, a vector will be cycled through).
p <- arphitgg(simple_data) + agg_line(agg_aes(x = date, y = y1), pch = 19)
agg_draw(p, filename = "pch.png")
knitr::include_graphics("pch.png")
lty
allows you to control the line type - e.g. add dashing. These directly follow the R options. These are specified like colours (setting one will apply it to all series in the layer, a vector will be cycled through).
p <- arphitgg(simple_data) + agg_line(agg_aes(x = date, y = y1), lty = 2)
agg_draw(p, filename = "lty.png")
knitr::include_graphics("lty.png")
lwd
controls the width of the line. 1 corresponds to default. 2 to twice default, 0.5 half it, etc. These are specified like colours (setting one will apply it to all series in the layer, a vector will be cycled through).
p <- arphitgg(simple_data) + agg_line(agg_aes(x = date, y = y1), lwd = 3)
agg_draw(p, filename = "lwd.png")
knitr::include_graphics("lwd.png")
barcol
lets you set the colour of the bar outline for agg_col
layers. By default, this is NA
, meaning no outline. These are specified like colours (setting one will apply it to all series in the layer, a vector will be cycled through).
p <- arphitgg(simple_data) + agg_col(agg_aes(x = date, y = y1), barcol = "black")
agg_draw(p, filename = "barcol.png")
knitr::include_graphics("barcol.png")
pointsize
lets change the size of plot markers on agg_line
or agg_point
layers. By default, this is 1, meaning the default size. These are specified like colours (setting one will apply it to all series in the layer, a vector will be cycled through).
p <- arphitgg(data.frame(x=rnorm(15),y=rnorm(15))) + agg_point(agg_aes(x = x, y = y), pointsize = 2) + agg_point(agg_aes(x = x, y = y))
agg_draw(p, filename = "pointsize.png")
knitr::include_graphics("pointsize.png")
Titles and subtitles are added using agg_title
and agg_subtitle
respectively. The only required argument is the text for the title/subtitle:
p <- arphitgg() + agg_title("Graph Title Goes Here") + agg_subtitle("Or a subtitle, if you like")
agg_draw(p, filename = "title.png")
knitr::include_graphics("title.png")
arphit
will automatically place linebreaks in long titles but may not be smart enough in all cases. You can insert linebreaks yourself as necessary by using "\n".
p <- arphitgg() + agg_title("Here is a very very very long title that arphit will automatically put a break in") + agg_subtitle("And a subtitle\nwith a manual break too")
agg_draw(p, filename = "longtitle.png")
knitr::include_graphics("longtitle.png")
You can add titles and subtitles to panels in much the same way as titles and subtitles. Allyou do is specify panel
as an argument:
p <- arphitgg() + agg_title("Panel title for panel 1", panel = "1") + agg_subtitle("And a subtitle", panel = "1")
agg_draw(p, filename = "paneltitles.png")
knitr::include_graphics("paneltitles.png")
You can also apply the same title to multiple panels at once using a vector of panel names panel = c("1","3")
.
You can specify the units for your graph using the agg_units
function. This can be used either with or without a panel specifier. If called without a panel specifier, the units are applied to all panels, otherwise the units are added only to specified panel:
p <- arphitgg() + agg_units("index")
agg_draw(p, filename = "units-all.png")
knitr::include_graphics("units-all.png")
p <- arphitgg() + agg_units("index", panel = "1") + agg_units("ppt", panel = "2")
agg_draw(p, filename = "units-specific.png")
knitr::include_graphics("units-specific.png")
You can also apply the same units to multiple panels at once using a vector of panel names panel = c("1","3")
.
You can also add units for the x-axis in much the same way. These are ignored for anything other than scatter graphs.
p <- arphitgg(scatter_data, agg_aes(x=x,y=y)) + agg_point() + agg_xunits("ppt")
agg_draw(p, filename = "x-units.png")
knitr::include_graphics("x-units.png")
You can also apply the same units to multiple panels at once using a vector of panel names panel = c("1","3")
.
Adding sources and footnotes is done using agg_source
and agg_footnote
. You can pass in a single text string, or a vector of multiple strings. You can add as many agg_source
/agg_footnote
as you like:
p <- arphitgg() + agg_source("Source 1") + agg_source(c("Source 2 (as a vector)", "Source 3 (vectors are easy!")) + agg_footnote("This is my first footnoote") + agg_footnote("This is a second footnote")
agg_draw(p, filename = "sources.png")
knitr::include_graphics("sources.png")
arphit
will automatically guess axes for each panel. However, it is not smart enough to sensibly line up axes across panels (e.g. if you have left and right axes). And stacked bar graphs will confuse it.
Y-limits can be controlled with agg_ylim
. This function takes three required arguments: a minimum, a maximum, and the number of steps to include. You can optionally include a panel identifier; if omitted, the limits will be applied to all panels. You can alternatively apply the same limits to a set of panels at once using a vector of panel names panel = c("1","3")
.
p <- arphitgg(simple_data) + agg_line(agg_aes(x=date,y=y1),panel="1") + agg_line(agg_aes(x=date,y=y1),panel="2") + agg_ylim(-1,1,5,panel="1") + agg_ylim(-4,4,5,panel="2")
agg_draw(p, filename = "ylim-left-right-axes.png")
knitr::include_graphics("ylim-left-right-axes.png")
p <- arphitgg(simple_data) + agg_line(agg_aes(x=date,y=y1),panel="1") + agg_line(agg_aes(x=date,y=y1),panel="2") + agg_ylim(-1,1,5)
agg_draw(p, filename = "ylim-all-axes.png")
knitr::include_graphics("ylim-all-axes.png")
X-limits are controlled using agg_xlim
. This is similar to y-limits, but only a minimum and maximum is required. For time series graphs, you can use part years if desired by adding decimal places (e.g. 2000.5
).
As with the y-axis you can specify a panel identifier to apply the limits to a specific panel; if you omit the panel identifier, the limits will be applied to all panels. You can alternatively apply the same limits to a set of panels at once using a vector of panel names panel = c("1","3")
.
Very fine-grained control of x-ticks is not possible; x-ticks are determined by your x-variables.
p <- arphitgg(simple_data, agg_aes(x=date, y=y1)) + agg_line() + agg_xlim(1998, 2008)
agg_draw(p, filename = "x-axis-lim.png")
knitr::include_graphics("x-axis-lim.png")
You can specify only an upper or lower bound by setting the other the NA
. For instance, to start the above graph at 2001
but let the data determine where to end it:
p <- arphitgg(simple_data, agg_aes(x=date, y=y1)) + agg_line() + agg_xlim(2001, NA)
agg_draw(p, filename = "x-axis-lim-single-arg.png")
knitr::include_graphics("x-axis-lim-single-arg.png")
Time series graphs with data that gets close to the right hand axis will automatically add a small margin of spacing to the right hand side. You can stop this by setting a manual x-limit for the right hand side. Vertically divided time series graphs always add a margin.
close_data <- data.frame(date = seq.Date(as.Date("2000-03-01"),by="quarter",length.out=20), y1 = rnorm(10)) p <- arphitgg(close_data, agg_aes(x=date, y=y1)) + agg_line()
agg_draw(p, filename = "x-axis-padding.png")
knitr::include_graphics("x-axis-padding.png")
For layouts with vertical division (e.g. "2v", "2b2" etc), you can drop the the first tick of the right hand panel by setting dropxlabel = TRUE
in arphitgg
. This prevents the last label of the left hand panel overlapping the first of the right hand panel.
p <- arphitgg(simple_data, agg_aes(x=date, y=y1), layout = "2v", dropxlabel = TRUE) + agg_line(panel = c("1","2"))
agg_draw(p, filename = "drop-x-label.png")
knitr::include_graphics("drop-x-label.png")
By default categorical graphs have all their x ticks displayed. You can change this
behaviour (if your x-ticks are overlapping) to only display an automatically determined
limited set of x-ticks by setting showallxlabels = FALSE
in the call to arphitgg
:
foo <- data.frame(x=paste("label",1:9),y=1:9) p <- arphitgg(foo, agg_aes(x=x,y=y), showallxlabels = FALSE) + agg_col()
agg_draw(p, filename = "showallxlabel.png")
knitr::include_graphics("showallxlabel.png")
For time series graphs, arphit
will automatically choose the frequency of the ticks on the x axis. Any graph covering less than a year will use months, less than 3 years quarters and greater than 50 years decades. (Note that vertically divided graphs will swap to decades sooner, due to the compression of the x-axis).
decades_data <- data.frame(date = seq.Date(from=as.Date("1950-06-01"),by="year",length=50), y1 = rnorm(50)) p <- arphitgg(decades_data, agg_aes(x=date, y=y1)) + agg_line()
agg_draw(p, filename = "decades.png")
knitr::include_graphics("decades.png")
Automatic x-limits respect the frequency. If your axis is in quarters or months, arphit
will set the limits to the first and last quarter/month of data:
partial_quarter_data <- data.frame(date = seq.Date(from=as.Date("2000-03-01"),by="quarter",length=9), y1 = rnorm(9)) p <- arphitgg(partial_quarter_data, agg_aes(x=date, y=y1)) + agg_line()
agg_draw(p, filename = "quarter-partial-year.png")
knitr::include_graphics("quarter-partial-year.png")
If you want override the automatically chosen frequency, you can use agg_xaxisfreq
. Valid options are decade
, year
, quarter
and month
. You can specify panels too if desired.
partial_quarter_data <- data.frame(date = seq.Date(from=as.Date("2000-03-01"),by="quarter",length=9), y1 = rnorm(9)) p <- arphitgg(partial_quarter_data, agg_aes(x=date, y=y1)) + agg_line() + agg_xaxisfreq("year")
agg_draw(p, filename = "manual-year.png")
knitr::include_graphics("manual-year.png")
You can make either or both of the y
and x
axes log scales (x
only makes sense for scatter graphs.) Use the log_scale
option to arphitgg
and specify one of "x"
, "y"
or "xy"
, which behave as you'd expect.
log_scale_data <- data.frame(x = 1:10, y = c(11, 20, 40, 90, 11, 14, 90, 15, 15, 16)) p <- arphitgg(log_scale_data, agg_aes(x = x, y = y), log_scale = "y") + agg_line() + agg_ylim(10, 90, 5)
agg_draw(p, filename = "logscale.png")
knitr::include_graphics("logscale.png")
You can shade the area between series by adding agg_shading
.
Shading is drawn in the order you add it; the first shading added is on the bottom and subsequently added shading is drawn on top of this. Series are always drawn on top of shading.
p <- arphitgg(simple_data, agg_aes(x=date)) + agg_line(agg_aes(y=y1)) + agg_line(agg_aes(y=y2)) + agg_shading(from = y1, to = y2, colour = RBA["Blue1"])
agg_draw(p, filename = "shading-single.png")
knitr::include_graphics("shading-single.png")
Multiple shading:
p <- arphitgg(simple_data, agg_aes(x=date)) + agg_line(agg_aes(y=y1)) + agg_line(agg_aes(y=y2)) + agg_line(agg_aes(y=y3)) + agg_line(agg_aes(y=y4)) + agg_shading(from = y1, to = y2, colour = RBA["Blue1"]) + agg_shading(from = y3, to = y4, colour = "lightgrey")
agg_draw(p, filename = "shading-multiple.png")
knitr::include_graphics("shading-multiple.png")
You can add series labels, and arrows to aid those labels, using agg_label
and agg_arrow
arguments.
agg_label
takes 6 arguments - some are optional.
text
is the label text. You can add line breaks in text using the \n
character.x
and y
specify where (in the units on the plot) the centre of the label should be. For time series, x
is in decimal years (i.e. 2000.5 is July 2, 2000). For categorical graphs, 1 corresponds to the first categories, 2 to the second, etc.panel
specifies which panel to place the label on.colour
is self-explanatory; if not specified, defaults to black.size
is optional and sets the font size. The default is 20.p <- arphitgg() + agg_label("A label", x = 2002, y = 0.5, colour = RBA["Blue2"], panel = "1")
agg_draw(p, filename = "labels.png")
knitr::include_graphics("labels.png")
Arrows are specified with agg_arrow
.
tail.x
and tail.y
specify the coordinates (in the units on the plot) of where to start the arrow at.head.x
and head.y
where to finish the arrow (and where the arrow head is).panel
specifies which panel to place the arrow on.colour
is self-explanatory.lwd
is optional and specifies the linewidth of the arrow (default = 1).p <- arphitgg() + agg_arrow(tail.x = 2000, tail.y = 0, head.x = 2001, head.y = 0.5, colour = RBA["Blue1"], panel = "1")
agg_draw(p, filename = "arrow.png")
knitr::include_graphics("arrow.png")
arphit
has (experimental) functionality to automatically add series labels
for you. If enabled, the auto labeller will run on panels with more than one
series, and which do not already have text labels. If you manually set text labels
for a panel, the auto labeller will skip that panel. By default, it will also add
arrows from the label to the series if necessary for line series, but not for bar
series. You can stop the autolabeller from adding arrows to line series (or have
it add arrows to bars using the arguments arrow_lines
and arrow_bars
to
agg_autolabel
).
The auto labeller will use whatever your series are called in the data. For long data,
this will be the value of the group variable. This is identical to how legends
are determined. Series that appear in multiple panels are only labelled once.
Series that have NA
as their name are ignored by the autolabeller.
You can rename series using the function agg_rename_series
. See the section on
adding legends for more details.
Enable the auto labeller by adding agg_autolabel()
:
p <- arphitgg(long_data, agg_aes(x = date, y = y1, group = group_var)) + agg_line() + agg_autolabel()
agg_draw(p, filename = "autolabel.png")
knitr::include_graphics("autolabel.png")
If you put text labels on a panel, that disables the auto labeller for that panel,
unless you set ignore_existing_labels = TRUE
as an argument to agg_autolabel
:
p <- arphitgg(long_data, agg_aes(x = date, y = y1, group = group_var), layout = "2v") + agg_line(panel = "1") + agg_line(panel = "2") + agg_label("Manual\nlabel disables\nautolabels", x = 2001, y = 1.5, colour = "black", panel = "2") + agg_autolabel()
agg_draw(p, filename = "autolabel2.png")
knitr::include_graphics("autolabel2.png")
The autolabeller correctly handles left and right hand series:
p <- arphitgg(simple_data, agg_aes(x = date), layout = "1") + agg_line(agg_aes(y = y1), panel = "1") + agg_line(agg_aes(y = y2), colour = RBA["Orange5"], panel = "2") + agg_autolabel()
agg_draw(p, filename = "autolabel_rhs.png")
knitr::include_graphics("autolabel_rhs.png")
Horizontal and vertical lines are added using agg_hline
and agg_vline
respectively.
Horizontal lines are drawn by specifying the y co-ordinate to draw the line at agg_hline(y = 1)
;
vertical lines are similar, but the x
variable only. You can also control the
colour and line type. These are optional and default to a solid black line. You
must also tell arphit
which panel to put the line on.
The following example draws a vertical line at 2001 using the default colour and solid line. It also draws a horizontal line at -1 coloured darkred and dashed (lty = 2
).
p <- arphitgg() + agg_vline(x = 2001, panel = "1") + agg_hline(y = -1, colour = "darkred", lty = 2, panel = "1")
agg_draw(p, filename = "lines.png")
knitr::include_graphics("lines.png")
If you need more control over the line, you can use agg_abline
to specify the
coordinates of the line segment instead of using x
or y
. To do so use
x1
, x2
, y1
and y2
. All other options are the same. For example:
p <- arphitgg() + agg_abline(x1 = 2003, y1 = -0.1, x2 = 2005, y2 = 0.5, panel = "1")
agg_draw(p, filename = "specificlines.png")
knitr::include_graphics("specificlines.png")
Entering NA (or omitting the argument) for any of x1
, y1
, x2
, or y2
will set that coordinate to the axis limit (with x1
and y1
going to the left and bottom axes and x2
and y2
to the right and top).
Background shading can be added using agg_bgshading
. This draws a rectangle with bottom left corner at x1
, y1
and top right corner at x2
,y2
. Passing NA for any of the four coordinates will set that coordinate to the axis limit - this is useful for creating shading that stretches across a whole panel. colour
and panel
are self-explanatory (colour is optional and defaults to light grey).
This example creates horizontal shading across the whole panel between -1 and 3 on the y axis.
p <- arphitgg() + agg_bgshading(x1 = NA, y1 = -0.5, x2 = NA, y2 = 0.5, panel = "1")
agg_draw(p, filename = "bgshading.png")
knitr::include_graphics("bgshading.png")
And this two panel example repeats the above example for panel 1, but puts light green shading between two dates on the bottom panel.
p <- arphitgg(layout = "2h") + agg_bgshading(x1 = NA, y1 = -0.5, x2 = NA, y2 = 0.5, panel = "1") + agg_bgshading(x1 = 2000.5, y1 = NA, x2 = 2001.5, y2 = NA, panel = "3", colour = "lightgreen")
agg_draw(p, filename = "bgshading2.png")
knitr::include_graphics("bgshading2.png")
You can add y and x axis labels to plots using agg_yaxislabel
and agg_xaxislabel
. These take the text for the axis label, plus an optional panel identifier. If omitted, the label is applied to all panels.
p <- arphitgg(layout = "2b2") + agg_yaxislabel("A y axis label") + agg_xaxislabel("An x label")
agg_draw(p, filename = "oneaxislabel.png")
knitr::include_graphics("oneaxislabel.png")
p <- arphitgg(layout = "2b2") + agg_yaxislabel("Foo", panel = "1") + agg_yaxislabel("Bar", panel = "3") + agg_xaxislabel("An x label", panel = "3") + agg_xaxislabel("Another x label", panel = "4")
agg_draw(p, filename = "differentaxislabel.png")
knitr::include_graphics("differentaxislabel.png")
You can rotate x ticks using the srt
option in arphitgg
. It represents the rotation (in degrees):
p <- arphitgg(simple_data, agg_aes(x=date,y=y1), srt = 45) + agg_line()
agg_draw(p, filename = "xlabel-rotation.png")
knitr::include_graphics("xlabel-rotation.png")
The joined
argument inarphitgg
controls how your graph behaves with missing values. When joined = TRUE
(which is the default) the series will ignore the missing value and connect to the next non-missing value. When joined = FALSE
the series will break.
For instance, let's use this series, with the middle observation missing:
joining_data <- ts(data.frame(y = c(1,2,NA,3,4)), start = 2000, frequency = 1)
With joined = TRUE
, the series continues straight across the missing value for 2002.
p <- arphitgg(joining_data, agg_aes(y = y), joined = TRUE) + agg_line()
agg_draw(p, filename = "joined.png")
knitr::include_graphics("joined.png")
But when we set joined = FALSE
, the series does not connect over the missing observation:
p <- arphitgg(joining_data, agg_aes(y = y), joined = FALSE) + agg_line()
agg_draw(p, filename = "unjoined.png")
knitr::include_graphics("unjoined.png")
You can add a legend to your graph by adding agg_legend()
. This can also take one optional argument to specify how many columns to have with ncol
; arphit
will automatically guess if you leave it blank.
p <- arphitgg(long_data, agg_aes(x = date, y = y1, group = group_var)) + agg_line() + agg_legend()
agg_draw(p, filename = "legend.png")
knitr::include_graphics("legend.png")
arphit
will ignore duplicate series in multiple panels (i.e. it will only put in one legend entry).
If a series has NA
as it's name, it will not get a legend entry.
You can also add the legend on the panel, instead of beneath the graph. This is done
by specifying a location for the legend. There are two ways. The easiest is to choose
one of "bottomright", "bottom", "bottomleft", "left", "topleft", "top", "topright",
"right" and "center". Pass this to the optoinal x
argument to agg_legend
and
the legend will be automatically placed in the appropriate location.
p <- arphitgg(long_data, agg_aes(x = date, y = y1, group = group_var)) + agg_line() + agg_legend(x="topright")
agg_draw(p, filename = "onpanel-legend.png")
knitr::include_graphics("onpanel-legend.png")
Multipanels are ignored for the purposes of on-panel legends - graphs are treated as a whole and panels are ignored. E.g. in a "2b2" graph, "topright" is the top right of the graph, meaning top right in panel "2".
If you want fine-grained control, you can supply a value between 0 and 1 for x
and a supply a y
coordinate. This will place a legend in a specific place on
the graph. (0,0) corresponds to the bottom left corner, (1,1) top right.
p <- arphitgg(long_data, agg_aes(x = date, y = y1, group = group_var)) + agg_line() + agg_legend(x=0.6,y=0.9)
agg_draw(p, filename = "onpanel-legend-specific-place.png")
knitr::include_graphics("onpanel-legend-specific-place.png")
By default, series names in legends are the name of the y
aesthetic (if the
aesthetic has no group) or the value of the grouping variable. Often these are
variable names and so are not particularly meaningful on a graph. The function
agg_rename_series
exists to allow you to easily rename series for legends (or
for the autolabeller).
This function takes a named list. The values in the list are the current name and
the names in the list are what the series are to be renamed to. (This is the same
structure as dplyr
's rename
function.) You can optional restrict the mapping
to only a specific panel; if no panel ID is supplied, the mapping will be applied
to all panels:
p <- arphitgg(simple_data, agg_aes(x = date, y = y1)) + agg_line() + agg_rename_series(list("Nicer name" = "y1")) + agg_legend()
agg_draw(p, filename = "rename-series-simple.png")
knitr::include_graphics("rename-series-simple.png")
p <- arphitgg(long_data, agg_aes(x = date, y = y1, group = group_var)) + agg_line() + agg_rename_series(list("Series A" = "A", "Series B" = "B")) + agg_legend()
agg_draw(p, filename = "rename-series-group.png")
knitr::include_graphics("rename-series-group.png")
As before, you can stop a series from being displayed in a legend by settings its
name to NA
. This is a little complicated in agg_rename_series
because R does not
accept NA as a name in a list. Instead use the string "
p <- arphitgg(long_data, agg_aes(x = date, y = y1, group = group_var)) + agg_line() + agg_rename_series(list("Series A" = "A", "<NA>" = "B")) + agg_legend()
agg_draw(p, filename = "rename-series-na.png")
knitr::include_graphics("rename-series-na.png")
To save your graph to a file instead of displaying it, use agg_draw
with the optional filename command. arphit
will determine what file to save as, based on the extension of your filename. png
, emf
, emf+
, svg
and pdf
are supported. xlsx
is as well, which exports the data (see below).
p <- arphitgg(simple_data, aes = agg_aes(x = date, y = y1)) + agg_line() agg_draw(p, filename = "my-graph.png") agg_draw(p, filename = "my-graph.emf") agg_draw(p, filename = "my-graph.svg") agg_draw(p, filename = "my-graph.pdf")
You can also use the newer EMFplus
format by using extention .emf+
. This will still write an emf
file, but it is encoded as the newer EMF+ format.
agg_qplot(data, filename = "my_filename.emf+")
You can also export to an XLSX, which will save your graph data in a nicely formatted spreadsheet. This can be convenient for archiving, or talking with other programs.
agg_draw(p, filename = "my-graph.xlsx")
EMF files are problematic:
Additionally, only EMF+ files support partial transparency; EMF files do not.
If you can, you should prefer SVG over EMF. SVG is a much better supported vector image format. And much less problematic in how it is rendered by R.
You can create a GIF animation by creating a list of arphitgg objects and using
agg_slides
. You can specify how many seconds each 'slide' should be shown for,
and how many times the animation should loop (0 if infinitely). If you don't
supply a filename, it will open it externally.
Here we create a dataframe of four series over the same time period.
gif_data <- data.frame( series = rep(1:4, each = 10), x = rep(seq.Date(from = as.Date("2000-03-01"), by = "quarter", length.out = 10)), y = rnorm(4*10))
We then split this into a list of four dataframes, one for each series and construct a graph for each series
gif_data_list <- split(gif_data, gif_data$series) gg_list <- lapply(gif_data_list, function(data) { arphitgg(data, agg_aes(x = x, y = y)) + agg_line() })
To create the GIF animation, just pass gg_list
to agg_slides
agg_slides(gg_list, filename = "agg.gif")
knitr::include_graphics("agg.gif")
You do need to be careful. The different scales can cause the graphs to be out
of alignment. This could be solved by setting the same agg_ylim
for each graph.
The graphs don't need to be the same time series, that was just a convenient example. Here's a gif going through the different possible layouts, but only 3 times.
gg_list <- list( arphitgg(layout = "1"), arphitgg(layout = "2v"), arphitgg(layout = "2h"), arphitgg(layout = "2b2"), arphitgg(layout = "3v"), arphitgg(layout = "3h"), arphitgg(layout = "3b2"), arphitgg(layout = "4h"), arphitgg(layout = "4b2") )
agg_slides(gg_list, filename = "agg_layouts.gif", loop = 3)
knitr::include_graphics("agg_layouts.gif")
Add the following code to your website.
For more information on customizing the embed code, read Embedding Snippets.