Skip to content

Commit 3eda7bc

Browse files
author
Toby Dylan Hocking
committed
Merge pull request #172 from ropensci/toby-cookbook
Toby cookbook-axes
2 parents bfb23c7 + 07af388 commit 3eda7bc

File tree

2 files changed

+235
-2
lines changed

2 files changed

+235
-2
lines changed

R/ggplotly.R

Lines changed: 16 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -165,7 +165,10 @@ gg2list <- function(p){
165165
names(ranks) <- br
166166
misc$breaks[[a.vec]] <- ranks
167167
}
168-
misc$trans[sc$aesthetics] <- sc$trans$name
168+
## store if this is a reverse scale so we can undo that later.
169+
if(is.character(sc$trans$name)){
170+
misc$trans[sc$aesthetics] <- sc$trans$name
171+
}
169172
}
170173
reverse.aes <- names(misc$trans)[misc$trans=="reverse"]
171174

@@ -271,6 +274,12 @@ gg2list <- function(p){
271274
trace.name.map <- c()
272275
for(xy in c("x","y")){
273276
ax.list <- list()
277+
coord.lim <- p$coord$limits[[xy]]
278+
if(is.numeric(coord.lim)){
279+
## TODO: maybe test for more exotic coord specification types
280+
## involving NA, Inf, etc?
281+
ax.list$range <- coord.lim
282+
}
274283
s <- function(tmp)sprintf(tmp, xy)
275284
ax.list$tickcolor <- toRGB(theme.pars$axis.ticks$colour)
276285

@@ -335,8 +344,13 @@ gg2list <- function(p){
335344
sc <- p$scales$scales[[scale.i]]
336345
if(ax.list$type == "category"){
337346
trace.order.list[[xy]] <- sc$limits
347+
if(is.character(sc$breaks)){
348+
if(is.character(sc$labels)){
349+
trace.name.map[sc$breaks] <- sc$labels
350+
}
351+
##TODO: if(is.function(sc$labels)){
352+
}
338353
}
339-
trace.name.map[sc$breaks] <- sc$labels
340354
if (is.null(sc$breaks)) {
341355
ax.list$showticklabels <- FALSE
342356
ax.list$showgrid <- FALSE

tests/testthat/test-cookbook-axes.R

Lines changed: 219 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,219 @@
1+
context("cookbook axes")
2+
3+
bp <- ggplot(PlantGrowth, aes(x=group, y=weight)) +
4+
geom_boxplot()
5+
6+
expect_traces <- function(gg, n.traces, name){
7+
stopifnot(is.ggplot(gg))
8+
stopifnot(is.numeric(n.traces))
9+
save_outputs(gg, paste0("cookbook-axes-", name))
10+
L <- gg2list(gg)
11+
is.trace <- names(L) == ""
12+
all.traces <- L[is.trace]
13+
no.data <- sapply(all.traces, function(tr) {
14+
is.null(tr[["x"]]) && is.null(tr[["y"]])
15+
})
16+
has.data <- all.traces[!no.data]
17+
expect_equal(length(has.data), n.traces)
18+
list(traces=has.data, kwargs=L$kwargs)
19+
}
20+
21+
# Reverse the order of a discrete-valued axis
22+
# Get the levels of the factor
23+
flevels <- levels(PlantGrowth$group)
24+
# "ctrl" "trt1" "trt2"
25+
# Reverse the order
26+
flevels <- rev(flevels)
27+
# "trt2" "trt1" "ctrl"
28+
bp.flevels <- bp + scale_x_discrete(limits=flevels)
29+
30+
test_that("factor levels determine tick order", {
31+
info <- expect_traces(bp.flevels, 3, "flevels")
32+
trace.names <- sapply(info$traces, "[[", "name")
33+
expect_identical(as.character(trace.names),
34+
c("trt2", "trt1", "ctrl"))
35+
})
36+
37+
## These two do the same thing; all data points outside the graphing
38+
## range are dropped, resulting in a misleading box plot.
39+
bp.ylim.hide <- bp + ylim(5, 7.5)
40+
test_that("ylim hides points", {
41+
info <- expect_traces(bp.ylim.hide, 3, "ylim.hide")
42+
})
43+
44+
bp.scale.hide <- bp + scale_y_continuous(limits=c(5, 7.5))
45+
test_that("scale_y(limits) hides points", {
46+
info <- expect_traces(bp.scale.hide, 3, "scale.hide")
47+
expect_equal(info$kwargs$layout$yaxis$range, c(5, 7.5))
48+
})
49+
50+
bp.coord <- bp + coord_cartesian(ylim=c(5, 7.5))
51+
test_that("Using coord_cartesian zooms into the area", {
52+
info <- expect_traces(bp.coord, 3, "coord-ylim")
53+
expect_equal(info$kwargs$layout$yaxis$range, c(5, 7.5))
54+
})
55+
56+
# Create some noisy exponentially-distributed data
57+
xval <- c(0.26932812,-0.05341404,0.36977717,0.91504712,0.46329006,0.37956526, 0.93290644,0.75558976,0.67633497,0.48655293,0.79478162,0.55109982, 0.51681398,0.81073512,0.49406579,0.93919618,0.90472008,0.98732256, 0.94379876,0.95790909,0.54614241,1.13356941,1.13299144,1.18159277, 1.16428407,1.22955005,1.21030897,1.23314811,1.53822718,1.53674330, 1.80020468,1.40774011,1.74573515,1.26651625,2.06607711,1.50237263, 1.38480531,1.83625381,2.35275649,1.99004291,2.80396442,2.20863240, 2.42998876,2.12801180,2.26290348,2.38185989,2.14936036,2.66587947, 2.64586596,2.44240603,2.39266452,3.11831215,2.70258927,2.65529134, 2.65634690,2.95984290,2.71058076,2.87919480,3.07739358,2.66841935, 3.10792706,3.17134285,3.98070271,3.55497279,3.36831009,3.31390892, 3.32753965,2.86981968,3.22741000,3.78806438,3.74434536,3.56928928, 3.83783177,3.24485807,4.05766233,4.13619455,4.26888054,3.47546258, 3.93045819,3.77620080,4.66676431,3.88059240,4.54694485,4.03915767, 4.25556093,4.39251819,4.42692029,4.23262929,4.44890758,4.84981161, 4.51104252,4.33004508,5.06350705,4.89714069,4.21599077,4.55457578, 5.04044393,4.89111297,5.03105215,4.64113164)
58+
59+
yval <- c(1.177512e+01,7.303113e+00,6.109053e+00,2.545169e+01,3.366341e+01,1.042255e+01,2.703767e+01,1.178223e+01,4.495965e+01,1.614609e+01,4.003015e+01,1.038442e+02,4.024992e+01,4.163942e+01,9.108197e+01,3.116299e+01,2.558871e+02,7.482977e+01,2.502789e+01,5.923683e+01,3.967814e+01,9.207318e+01,1.298618e+02,1.138197e+02,1.804303e+02,3.363494e+02,3.197204e+02,4.968737e+02,1.783433e+02,4.765546e+02,4.486885e+02,6.736079e+02,4.289288e+02,3.433946e+02,5.658634e+02,4.667053e+02,5.257803e+02,3.401038e+02,6.131335e+02,5.928647e+02,7.838524e+02,7.987915e+02,3.348470e+03,1.704767e+03,1.264169e+03,2.690011e+03,2.738240e+03,1.663862e+03,5.377442e+03,3.883820e+03,6.673624e+03,1.857346e+03,6.683962e+03,1.213027e+03,1.742885e+03,2.146094e+03,4.597174e+03,4.357154e+03,8.413851e+03,8.194194e+03,7.076611e+03,1.554628e+04,6.984783e+03,1.027392e+04,1.158795e+04,9.193111e+03,3.226748e+04,3.955445e+04,2.978953e+04,1.926420e+04,7.610544e+04,2.129694e+04,1.438764e+04,7.908876e+04,2.676003e+04,1.791758e+05,3.978871e+04,9.411120e+04,4.486940e+04,1.270526e+05,1.587331e+05,1.616173e+05,3.351522e+05,3.001782e+05,2.527824e+05,2.745851e+05,3.446376e+05,1.544497e+05,1.318314e+05,8.334336e+05,2.464391e+05,8.694818e+05,2.747323e+05,6.373497e+05,2.918690e+05,9.505114e+05,7.835278e+05,3.775567e+05,1.795523e+06,1.568159e+06)
60+
61+
dat <- data.frame(xval = xval, yval = yval)
62+
63+
sp <- ggplot(dat, aes(xval, yval)) + geom_point()
64+
65+
test_that("A scatterplot with regular (linear) axis scaling", {
66+
info <- expect_traces(sp, 1, "linear-axes")
67+
})
68+
69+
library(scales) # Need the scales package
70+
sp.log2.scale <- sp + scale_y_continuous(trans=log2_trans())
71+
72+
test_that("log2 scaling of the y axis (with visually-equal spacing)", {
73+
info <- expect_traces(sp.log2.scale, 1, "log2-scale")
74+
})
75+
76+
sp.log2.coord <- sp + coord_trans(ytrans="log2")
77+
78+
test_that("log2 coordinate transformation with visually-diminishing spacing", {
79+
info <- expect_traces(sp.log2.coord, 1, "log2-coord")
80+
})
81+
82+
sp.labels <- sp +
83+
scale_y_continuous(trans = log2_trans(),
84+
breaks = trans_breaks("log2", function(x) 2^x),
85+
labels = trans_format("log2", math_format(2^.x)))
86+
87+
test_that("log2 transform with labels", {
88+
info <- expect_traces(sp.labels, 1, "log2-labels")
89+
})
90+
91+
sp.log10 <- sp + scale_y_log10()
92+
93+
test_that("scale_y_log10", {
94+
info <- expect_traces(sp.log10, 1, "scale_y_log10")
95+
})
96+
97+
sp.log10.labels <- sp +
98+
scale_y_log10(breaks = trans_breaks("log10", function(x) 10^x),
99+
labels = trans_format("log10", math_format(10^.x)))
100+
101+
test_that("log10 with exponents on tick labels", {
102+
info <- expect_traces(sp.log10.labels, 1, "scale_y_log10-labels")
103+
})
104+
105+
# Data where x ranges from 0-10, y ranges from 0-30
106+
set.seed(202)
107+
dat <- data.frame(xval = runif(40,0,10), yval = runif(40,0,30))
108+
sp <- ggplot(dat, aes(xval, yval)) + geom_point()
109+
110+
sp.fixed <- sp + coord_fixed()
111+
112+
test_that("Force equal scaling", {
113+
info <- expect_traces(sp.fixed, 1, "coord-fixed")
114+
})
115+
116+
sp.ratio <- sp + coord_fixed(ratio=1/3)
117+
118+
test_that("coord_fixed(ratio)", {
119+
info <- expect_traces(sp.ratio, 1, "coord-fixed-ratio")
120+
})
121+
122+
no.x.title <- bp +
123+
theme(axis.title.x = element_blank()) + # Remove x-axis label
124+
ylab("Weight (Kg)") # Set y-axis label
125+
126+
test_that("coord_fixed(ratio)", {
127+
info <- expect_traces(no.x.title, 3, "no-x-title")
128+
})
129+
130+
# Also possible to set the axis label with the scale
131+
# Note that vertical space is still reserved for x"s label
132+
133+
bp.scale.name <- bp + scale_x_discrete(name="") +
134+
scale_y_continuous(name="Weight (Kg)")
135+
136+
test_that("scale(name)", {
137+
info <- expect_traces(bp.scale.name, 3, "scale-name")
138+
})
139+
140+
# Change font options:
141+
# X-axis label: bold, red, and 20 points
142+
# X-axis tick marks: rotate 90 degrees CCW, move to the left a bit (using vjust,
143+
# since the labels are rotated), and 16 points
144+
145+
bp.fonts <- bp +
146+
theme(axis.title.x = element_text(face="bold", colour="#990000", size=20),
147+
axis.text.x = element_text(angle=90, vjust=0.5, size=16))
148+
149+
test_that("element_text face, colour, size, angle, vjust, size", {
150+
info <- expect_traces(bp.fonts, 3, "fonts")
151+
x <- info$kwargs$layout$xaxis
152+
xtitle <- x[["titlefont"]]
153+
xtick <- x[["tickfont"]]
154+
expect_identical(xtitle$color, toRGB("#990000"))
155+
expect_equal(xtitle$size, 20)
156+
## TODO: does plotly support bold text?
157+
expect_equal(x$tickangle, -90)
158+
## TODO: can we test for vjust?
159+
expect_equal(xtick$size, 16)
160+
})
161+
162+
# Label formatters
163+
library(scales) # Need the scales package
164+
165+
label.funs <- bp +
166+
scale_y_continuous(labels=percent) +
167+
scale_x_discrete(labels=abbreviate)
168+
169+
test_that("In this particular case, x scale has no effect", {
170+
info <- expect_traces(label.funs, 3, "label-funs")
171+
})
172+
173+
# Self-defined formatting function for times.
174+
timeHMS_formatter <- function(x) {
175+
h <- floor(x/60)
176+
m <- floor(x %% 60)
177+
s <- round(60*(x %% 1)) # Round to nearest second
178+
lab <- sprintf("%02d:%02d:%02d", h, m, s) # Format the strings as HH:MM:SS
179+
lab <- gsub("^00:", "", lab) # Remove leading 00: if present
180+
lab <- gsub("^0", "", lab) # Remove leading 0 if present
181+
}
182+
183+
custom.formatter <- bp + scale_y_continuous(label=timeHMS_formatter)
184+
185+
test_that("custom HMS formatter function", {
186+
info <- expect_traces(custom.formatter, 3, "custom-formatter")
187+
})
188+
189+
blank.minor.major <- bp +
190+
theme(panel.grid.minor=element_blank(),
191+
panel.grid.major=element_blank())
192+
193+
test_that("Hide all the gridlines", {
194+
info <- expect_traces(blank.minor.major, 3, "blank-minor-major")
195+
})
196+
197+
blank.minor <- bp +
198+
theme(panel.grid.minor=element_blank())
199+
200+
test_that("Hide just the minor gridlines", {
201+
info <- expect_traces(blank.minor, 3, "blank-minor")
202+
})
203+
204+
blank.x <- bp +
205+
theme(panel.grid.minor.x=element_blank(),
206+
panel.grid.major.x=element_blank())
207+
208+
test_that("Hide all the horizontal gridlines", {
209+
info <- expect_traces(blank.x, 3, "blank-x")
210+
})
211+
212+
blank.y <- bp +
213+
theme(panel.grid.minor.y=element_blank(),
214+
panel.grid.major.y=element_blank())
215+
216+
test_that("Hide all the vertical gridlines", {
217+
info <- expect_traces(blank.y, 3, "blank-y")
218+
})
219+

0 commit comments

Comments
 (0)