1context("Themes") 2 3skip_on_cran() # This test suite is long-running (on cran) and is skipped 4 5test_that("modifying theme element properties with + operator works", { 6 7 # Changing a "leaf node" works 8 t <- theme_grey() + theme(axis.title.x = element_text(colour = 'red', margin = margin())) 9 expect_identical(t$axis.title.x, element_text(colour = 'red', margin = margin(), vjust = 1)) 10 # Make sure the theme class didn't change or get dropped 11 expect_true(is.theme(t)) 12 # Make sure the element class didn't change or get dropped 13 expect_true(inherits(t$axis.title.x, "element")) 14 expect_true(inherits(t$axis.title.x, "element_text")) 15 16 # Modifying an intermediate node works 17 t <- theme_grey() + theme(axis.title = element_text(colour = 'red')) 18 expect_identical(t$axis.title, element_text(colour = 'red')) 19 20 # Modifying a root node changes only the specified properties 21 t <- theme_grey() + theme(text = element_text(colour = 'red')) 22 expect_identical(t$text$colour, 'red') 23 expect_identical(t$text$family, theme_grey()$text$family) 24 expect_identical(t$text$face, theme_grey()$text$face) 25 expect_identical(t$text$size, theme_grey()$text$size) 26 # Descendent is unchanged 27 expect_identical(t$axis.title.x, theme_grey()$axis.title.x) 28 29 # Adding element_blank replaces element 30 t <- theme_grey() + theme(axis.text.y = element_blank()) 31 expect_identical(t$axis.text.y, element_blank()) 32 33 # Adding a non-blank element to an element_blank() replaces it 34 t <- t + theme(axis.text.y = element_text(colour = 'red')) 35 expect_identical(t$axis.text.y, element_text(colour = 'red')) 36 37 # Adding empty theme() has no effect 38 t <- theme_grey() + theme() 39 expect_identical(t, theme_grey()) 40 41 expect_error(theme_grey() + "asdf") 42}) 43 44test_that("adding theme object to ggplot object with + operator works", { 45 ## test with complete theme 46 p <- qplot(1:3, 1:3) + theme_grey() 47 p <- p + theme(axis.title = element_text(size = 20)) 48 expect_true(p$theme$axis.title$size == 20) 49 50 # Should update specified properties, but not reset other properties 51 p <- p + theme(text = element_text(colour = 'red')) 52 expect_true(p$theme$text$colour == 'red') 53 tt <- theme_grey()$text 54 tt$colour <- 'red' 55 expect_true(tt$inherit.blank) 56 tt$inherit.blank <- FALSE 57 expect_identical(p$theme$text, tt) 58 59 ## test without complete theme 60 p <- qplot(1:3, 1:3) 61 p <- p + theme(axis.title = element_text(size = 20)) 62 expect_true(p$theme$axis.title$size == 20) 63 64 # Should update specified properties, but not reset other properties 65 p <- p + theme(text = element_text(colour = 'red')) 66 expect_true(p$theme$text$colour == 'red') 67 expect_null(p$theme$text$family) 68 expect_null(p$theme$text$face) 69 expect_null(p$theme$text$size) 70 expect_null(p$theme$text$hjust) 71 expect_null(p$theme$text$vjust) 72 expect_null(p$theme$text$angle) 73 expect_null(p$theme$text$lineheight) 74 expect_null(p$theme$text$margin) 75 expect_null(p$theme$text$debug) 76 77 ## stepwise addition of partial themes is identical to one-step addition 78 p <- qplot(1:3, 1:3) 79 p1 <- p + theme_light() + 80 theme(axis.line.x = element_line(color = "blue")) + 81 theme(axis.ticks.x = element_line(color = "red")) 82 83 p2 <- p + theme_light() + 84 theme(axis.line.x = element_line(color = "blue"), 85 axis.ticks.x = element_line(color = "red")) 86 87 expect_identical(p1$theme, p2$theme) 88}) 89 90test_that("replacing theme elements with %+replace% operator works", { 91 # Changing a "leaf node" works 92 t <- theme_grey() %+replace% theme(axis.title.x = element_text(colour = 'red')) 93 expect_identical(t$axis.title.x, element_text(colour = 'red')) 94 # Make sure the class didn't change or get dropped 95 expect_true(is.theme(t)) 96 97 # Changing an intermediate node works 98 t <- theme_grey() %+replace% theme(axis.title = element_text(colour = 'red')) 99 expect_identical(t$axis.title, element_text(colour = 'red')) 100 # Descendent is unchanged 101 expect_identical(t$axis.title.x, theme_grey()$axis.title.x) 102 103 # Adding empty theme() has no effect 104 t <- theme_grey() %+replace% theme() 105 expect_identical(t, theme_grey()) 106 107 expect_error(theme_grey() + "asdf") 108}) 109 110test_that("calculating theme element inheritance works", { 111 t <- theme_grey() + theme(axis.title = element_text(colour = 'red')) 112 113 # Check that properties are passed along from axis.title to axis.title.x 114 e <- calc_element('axis.title.x', t) 115 expect_identical(e$colour, 'red') 116 expect_false(is.null(e$family)) 117 expect_false(is.null(e$face)) 118 expect_false(is.null(e$size)) 119 120 # Check that rel() works for relative sizing, and is applied at each level 121 t <- theme_grey(base_size = 12) + 122 theme(axis.title = element_text(size = rel(0.5))) + 123 theme(axis.title.x = element_text(size = rel(0.5))) 124 e <- calc_element('axis.title', t) 125 expect_identical(e$size, 6) 126 ex <- calc_element('axis.title.x', t) 127 expect_identical(ex$size, 3) 128 129 # Check that a theme_blank in a parent node gets passed along to children 130 t <- theme_grey() + theme(text = element_blank()) 131 expect_identical(calc_element('axis.title.x', t), element_blank()) 132 133 # Check that inheritance from derived class works 134 element_dummyrect <- function(dummy) { # like element_rect but w/ dummy argument 135 structure(list( 136 fill = NULL, colour = NULL, dummy = dummy, size = NULL, 137 linetype = NULL, inherit.blank = FALSE 138 ), class = c("element_dummyrect", "element_rect", "element")) 139 } 140 141 e <- calc_element( 142 "panel.background", 143 theme( 144 rect = element_rect(fill = "white", colour = "black", size = 0.5, linetype = 1), 145 panel.background = element_dummyrect(dummy = 5), 146 complete = TRUE # need to prevent pulling in default theme 147 ) 148 ) 149 150 expect_identical( 151 e, 152 structure(list( 153 fill = "white", colour = "black", dummy = 5, size = 0.5, linetype = 1, 154 inherit.blank = TRUE # this is true because we're requesting a complete theme 155 ), class = c("element_dummyrect", "element_rect", "element")) 156 ) 157 158 # Check that blank elements are skipped in inheritance tree if and only if elements 159 # don't inherit from blank. 160 t <- theme_gray() + 161 theme( 162 strip.text = element_blank(), 163 strip.text.x = element_text() # inherit.blank = FALSE is default 164 ) 165 e1 <- calc_element("strip.text.x", t) 166 e2 <- calc_element("text", t) 167 e2$inherit.blank <- FALSE # b/c inherit.blank = TRUE for complete themes 168 expect_identical(e1, e2) 169 170 theme <- theme_gray() + 171 theme(strip.text = element_blank(), strip.text.x = element_text(inherit.blank = TRUE)) 172 e1 <- ggplot2:::calc_element("strip.text.x", theme) 173 e2 <- ggplot2:::calc_element("strip.text", theme) 174 expect_identical(e1, e2) 175}) 176 177test_that("complete and non-complete themes interact correctly with each other", { 178 # The 'complete' attribute of t1 + t2 is the OR of their 'complete' attributes. 179 180 # But for _element properties_, the one on the right modifies the one on the left. 181 t <- theme_bw() + theme(text = element_text(colour = 'red')) 182 expect_true(attr(t, "complete")) 183 expect_equal(t$text$colour, 'red') 184 185 # A complete theme object (like theme_bw) always trumps a non-complete theme object 186 t <- theme(text = element_text(colour = 'red')) + theme_bw() 187 expect_true(attr(t, "complete")) 188 expect_equal(t$text$colour, theme_bw()$text$colour) 189 190 # Adding two non-complete themes: the one on the right modifies the one on the left. 191 t <- theme(text = element_text(colour = 'blue')) + 192 theme(text = element_text(colour = 'red')) 193 expect_false(attr(t, "complete")) 194 expect_equal(t$text$colour, 'red') 195}) 196 197test_that("complete and non-complete themes interact correctly with ggplot objects", { 198 # Check that adding two theme successive theme objects to a ggplot object 199 # works like adding the two theme object to each other 200 p <- ggplot_build(qplot(1:3, 1:3) + theme_bw() + theme(text = element_text(colour = 'red'))) 201 expect_true(attr(p$plot$theme, "complete")) 202 203 # Compare the theme objects, after sorting the items, because item order can differ 204 pt <- p$plot$theme 205 tt <- theme_bw() + theme(text = element_text(colour = 'red')) 206 pt <- pt[order(names(pt))] 207 tt <- tt[order(names(tt))] 208 expect_identical(pt, tt) 209 210 p <- ggplot_build(qplot(1:3, 1:3) + theme(text = element_text(colour = 'red')) + theme_bw()) 211 expect_true(attr(p$plot$theme, "complete")) 212 # Compare the theme objects, after sorting the items, because item order can differ 213 pt <- p$plot$theme 214 tt <- theme(text = element_text(colour = 'red')) + theme_bw() 215 pt <- pt[order(names(pt))] 216 tt <- tt[order(names(tt))] 217 expect_identical(pt, tt) 218 219 p <- ggplot_build(qplot(1:3, 1:3) + theme(text = element_text(colour = 'red', face = 'italic'))) 220 expect_false(attr(p$plot$theme, "complete")) 221 expect_equal(p$plot$theme$text$colour, "red") 222 expect_equal(p$plot$theme$text$face, "italic") 223 224 p <- ggplot_build(qplot(1:3, 1:3) + 225 theme(text = element_text(colour = 'red')) + 226 theme(text = element_text(face = 'italic'))) 227 expect_false(attr(p$plot$theme, "complete")) 228 expect_equal(p$plot$theme$text$colour, "red") 229 expect_equal(p$plot$theme$text$face, "italic") 230}) 231 232test_that("theme(validate=FALSE) means do not validate_element", { 233 p <- qplot(1:3, 1:3) 234 bw <- p + theme_bw() 235 red.text <- theme(text = element_text(colour = "red")) 236 bw.before <- bw + theme(animint.width = 500, validate = FALSE) 237 expect_equal(bw.before$theme$animint.width, 500) 238 239 bw.after <- p + theme(animint.width = 500, validate = FALSE) + theme_bw() 240 expect_null(bw.after$theme$animint.width) 241 242 red.after <- p + theme(animint.width = 500, validate = FALSE) + red.text 243 expect_equal(red.after$theme$animint.width, 500) 244 245 red.before <- p + red.text + theme(animint.width = 500, validate = FALSE) 246 expect_equal(red.before$theme$animint.width, 500) 247}) 248 249test_that("theme validation happens at build stage", { 250 # adding a non-valid theme element to a theme is no problem 251 expect_silent(theme_gray() + theme(text = 0)) 252 253 # the error occurs when we try to render the plot 254 p <- ggplot() + theme(text = 0) 255 expect_error(print(p), "must be an object of type `element_text`") 256 257 # without validation, the error occurs when the element is accessed 258 p <- ggplot() + theme(text = 0, validate = FALSE) 259 expect_error(print(p), "text should have class element_text") 260}) 261 262test_that("element tree can be modified", { 263 # we cannot add a new theme element without modifying the element tree 264 p <- ggplot() + theme(blablabla = element_text(colour = "red")) 265 expect_error(print(p), "Theme element `blablabla` is not defined in the element hierarchy") 266 267 # things work once we add a new element to the element tree 268 register_theme_elements( 269 element_tree = list(blablabla = el_def("element_text", "text")) 270 ) 271 expect_silent(print(p)) 272 273 # inheritance and final calculation of novel element works 274 final_theme <- ggplot2:::plot_theme(p, theme_gray()) 275 e1 <- calc_element("blablabla", final_theme) 276 e2 <- calc_element("text", final_theme) 277 expect_identical(e1$family, e2$family) 278 expect_identical(e1$face, e2$face) 279 expect_identical(e1$size, e2$size) 280 expect_identical(e1$lineheight, e2$lineheight) 281 expect_identical(e1$colour, "red") # not inherited from element_text 282 283 # existing elements can be overwritten 284 ed <- el_def("element_rect", "rect") 285 register_theme_elements( 286 element_tree = list(axis.title = ed) 287 ) 288 expect_identical(get_element_tree()$axis.title, ed) 289 290 reset_theme_settings(reset_current = FALSE) # revert back to defaults 291}) 292 293test_that("all elements in complete themes have inherit.blank=TRUE", { 294 inherit_blanks <- function(theme) { 295 all(vapply(theme, function(el) { 296 if (inherits(el, "element") && !inherits(el, "element_blank")) { 297 el$inherit.blank 298 } else { 299 TRUE 300 } 301 }, logical(1))) 302 } 303 expect_true(inherit_blanks(theme_grey())) 304 expect_true(inherit_blanks(theme_bw())) 305 expect_true(inherit_blanks(theme_classic())) 306 expect_true(inherit_blanks(theme_dark())) 307 expect_true(inherit_blanks(theme_light())) 308 expect_true(inherit_blanks(theme_linedraw())) 309 expect_true(inherit_blanks(theme_minimal())) 310 expect_true(inherit_blanks(theme_void())) 311}) 312 313test_that("elements can be merged", { 314 text_base <- element_text(colour = "red", size = 10) 315 expect_equal( 316 merge_element(element_text(colour = "blue"), text_base), 317 element_text(colour = "blue", size = 10) 318 ) 319 rect_base <- element_rect(colour = "red", size = 10) 320 expect_equal( 321 merge_element(element_rect(colour = "blue"), rect_base), 322 element_rect(colour = "blue", size = 10) 323 ) 324 line_base <- element_line(colour = "red", size = 10) 325 expect_equal( 326 merge_element(element_line(colour = "blue"), line_base), 327 element_line(colour = "blue", size = 10) 328 ) 329 expect_error( 330 merge_element(text_base, rect_base), 331 "Only elements of the same class can be merged" 332 ) 333}) 334 335test_that("theme elements that don't inherit from element can be combined", { 336 expect_identical(combine_elements(1, NULL), 1) 337 expect_identical(combine_elements(NULL, 1), 1) 338 expect_identical(combine_elements(1, 0), 1) 339}) 340 341test_that("complete plot themes shouldn't inherit from default", { 342 default_theme <- theme_gray() + theme(axis.text.x = element_text(colour = "red")) 343 base <- qplot(1, 1) 344 345 ptheme <- plot_theme(base + theme(axis.text.x = element_text(colour = "blue")), default_theme) 346 expect_equal(ptheme$axis.text.x$colour, "blue") 347 348 ptheme <- plot_theme(base + theme_void(), default_theme) 349 expect_null(ptheme$axis.text.x) 350}) 351 352test_that("current theme can be updated with new elements", { 353 old <- theme_set(theme_grey()) 354 355 b1 <- ggplot() + theme_grey() 356 b2 <- ggplot() 357 358 # works for root element 359 expect_identical( 360 calc_element("text", plot_theme(b1)), 361 calc_element("text", plot_theme(b2)) 362 ) 363 364 # works for derived element 365 expect_identical( 366 calc_element("axis.text.x", plot_theme(b1)), 367 calc_element("axis.text.x", plot_theme(b2)) 368 ) 369 370 # theme calculation for nonexisting element returns NULL 371 expect_identical(calc_element("abcde", plot_theme(b1)), NULL) 372 373 # element tree gets merged properly 374 register_theme_elements( 375 abcde = element_text(color = "blue", hjust = 0, vjust = 1), 376 element_tree = list(abcde = el_def("element_text", "text")) 377 ) 378 379 e1 <- calc_element("abcde", plot_theme(b2)) 380 e2 <- calc_element("text", plot_theme(b2)) 381 e2$colour <- "blue" 382 e2$hjust <- 0 383 e2$vjust <- 1 384 expect_identical(e1, e2) 385 386 reset_theme_settings() 387 theme_set(old) 388}) 389 390test_that("titleGrob() and margins() work correctly", { 391 # ascenders and descenders 392 g1 <- titleGrob("aaaa", 0, 0, 0.5, 0.5) # lower-case letters, no ascenders or descenders 393 g2 <- titleGrob("bbbb", 0, 0, 0.5, 0.5) # lower-case letters, no descenders 394 g3 <- titleGrob("gggg", 0, 0, 0.5, 0.5) # lower-case letters, no ascenders 395 g4 <- titleGrob("AAAA", 0, 0, 0.5, 0.5) # upper-case letters, no descenders 396 397 expect_equal(height_cm(g1), height_cm(g2)) 398 expect_equal(height_cm(g1), height_cm(g3)) 399 expect_equal(height_cm(g1), height_cm(g4)) 400 401 # margins 402 g5 <- titleGrob("aaaa", 0, 0, 0.5, 0.5, margin = margin(t = 1, r = 0, b = 0, l = 0, unit = "cm"), margin_x = TRUE, margin_y = TRUE) 403 g6 <- titleGrob("aaaa", 0, 0, 0.5, 0.5, margin = margin(t = 0, r = 1, b = 0, l = 0, unit = "cm"), margin_x = TRUE, margin_y = TRUE) 404 g7 <- titleGrob("aaaa", 0, 0, 0.5, 0.5, margin = margin(t = 0, r = 0, b = 1, l = 0, unit = "cm"), margin_x = TRUE, margin_y = TRUE) 405 g8 <- titleGrob("aaaa", 0, 0, 0.5, 0.5, margin = margin(t = 0, r = 0, b = 0, l = 1, unit = "cm"), margin_x = TRUE, margin_y = TRUE) 406 407 expect_equal(height_cm(g5), height_cm(g1) + 1) 408 expect_equal(width_cm(g5), width_cm(g1)) 409 expect_equal(height_cm(g6), height_cm(g1)) 410 expect_equal(width_cm(g6), width_cm(g1) + 1) 411 expect_equal(height_cm(g7), height_cm(g1) + 1) 412 expect_equal(width_cm(g7), width_cm(g1)) 413 expect_equal(height_cm(g8), height_cm(g1)) 414 expect_equal(width_cm(g8), width_cm(g1) + 1) 415 416 # no margins when set to false 417 g9 <- titleGrob("aaaa", 0, 0, 0.5, 0.5, margin = margin(t = 1, r = 1, b = 1, l = 1, unit = "cm"), margin_x = FALSE, margin_y = TRUE) 418 g10 <- titleGrob("aaaa", 0, 0, 0.5, 0.5, margin = margin(t = 1, r = 1, b = 1, l = 1, unit = "cm"), margin_x = TRUE, margin_y = FALSE) 419 expect_equal(height_cm(g9), height_cm(g1) + 2) 420 # when one of margin_x or margin_y is set to FALSE and the other to TRUE, then the dimension for FALSE turns into 421 # length 1null. 422 expect_equal(g9$widths, grid::unit(1, "null")) 423 expect_equal(g10$heights, grid::unit(1, "null")) 424 expect_equal(width_cm(g10), width_cm(g1) + 2) 425}) 426 427test_that("provided themes explicitly define all elements", { 428 elements <- names(.element_tree) 429 430 t <- theme_all_null() 431 expect_true(all(names(t) %in% elements)) 432 expect_true(all(vapply(t, is.null, logical(1)))) 433 434 t <- theme_grey() 435 expect_true(all(names(t) %in% elements)) 436 437 t <- theme_bw() 438 expect_true(all(names(t) %in% elements)) 439 440 t <- theme_linedraw() 441 expect_true(all(names(t) %in% elements)) 442 443 t <- theme_light() 444 expect_true(all(names(t) %in% elements)) 445 446 t <- theme_dark() 447 expect_true(all(names(t) %in% elements)) 448 449 t <- theme_minimal() 450 expect_true(all(names(t) %in% elements)) 451 452 t <- theme_classic() 453 expect_true(all(names(t) %in% elements)) 454 455 t <- theme_void() 456 expect_true(all(names(t) %in% elements)) 457 458 t <- theme_test() 459 expect_true(all(names(t) %in% elements)) 460}) 461 462# Visual tests ------------------------------------------------------------ 463 464test_that("aspect ratio is honored", { 465 df <- cbind(data_frame(x = 1:8, y = 1:8, f = gl(2,4)), expand.grid(f1 = 1:2, f2 = 1:2, rep = 1:2)) 466 p <- ggplot(df, aes(x, y)) + 467 geom_point() + 468 theme_test() + 469 labs(x = NULL, y = NULL) 470 471 p_a <- p + theme(aspect.ratio = 3) 472 p_b <- p + theme(aspect.ratio = 1 / 3) 473 474 expect_doppelganger("height is 3 times width", 475 p_a 476 ) 477 expect_doppelganger("width is 3 times height", 478 p_b 479 ) 480 481 expect_doppelganger("height is 3 times width, 2 wrap facets", 482 p_a + facet_wrap(~f) 483 ) 484 expect_doppelganger("height is 3 times width, 2 column facets", 485 p_a + facet_grid(.~f) 486 ) 487 expect_doppelganger("height is 3 times width, 2 row facets", 488 p_a + facet_grid(f~.) 489 ) 490 expect_doppelganger("height is 3 times width, 2x2 facets", 491 p_a + facet_grid(f1~f2) 492 ) 493 494}) 495 496test_that("themes don't change without acknowledgement", { 497 df <- data_frame(x = 1:3, y = 1:3, z = c("a", "b", "a"), a = 1) 498 plot <- ggplot(df, aes(x, y, colour = z)) + 499 geom_point() + 500 facet_wrap(~ a) 501 502 expect_doppelganger("theme_bw", plot + theme_bw()) 503 expect_doppelganger("theme_classic", plot + theme_classic()) 504 expect_doppelganger("theme_dark", plot + theme_dark()) 505 expect_doppelganger("theme_minimal", plot + theme_minimal()) 506 expect_doppelganger("theme_gray", plot + theme_gray()) 507 expect_doppelganger("theme_light", plot + theme_light()) 508 expect_doppelganger("theme_void", plot + theme_void()) 509 expect_doppelganger("theme_linedraw", plot + theme_linedraw()) 510}) 511 512test_that("themes look decent at larger base sizes", { 513 df <- data_frame(x = 1:3, y = 1:3, z = c("a", "b", "a"), a = 1) 514 plot <- ggplot(df, aes(x, y, colour = z)) + 515 geom_point() + 516 facet_wrap(~ a) 517 518 expect_doppelganger("theme_bw_large", plot + theme_bw(base_size = 33)) 519 expect_doppelganger("theme_classic_large", plot + theme_classic(base_size = 33)) 520 expect_doppelganger("theme_dark_large", plot + theme_dark(base_size = 33)) 521 expect_doppelganger("theme_minimal_large", plot + theme_minimal(base_size = 33)) 522 expect_doppelganger("theme_gray_large", plot + theme_gray(base_size = 33)) 523 expect_doppelganger("theme_light_large", plot + theme_light(base_size = 33)) 524 expect_doppelganger("theme_void_large", plot + theme_void(base_size = 33)) 525 expect_doppelganger("theme_linedraw_large", plot + theme_linedraw(base_size = 33)) 526}) 527 528test_that("axes can be styled independently", { 529 plot <- ggplot() + 530 geom_point(aes(1:10, 1:10)) + 531 scale_x_continuous(sec.axis = dup_axis()) + 532 scale_y_continuous(sec.axis = dup_axis()) + 533 theme( 534 axis.title.x.top = element_text(colour = 'red'), 535 axis.title.x.bottom = element_text(colour = 'green'), 536 axis.title.y.left = element_text(colour = 'blue'), 537 axis.title.y.right = element_text(colour = 'yellow'), 538 axis.text.x.top = element_text(colour = 'red'), 539 axis.text.x.bottom = element_text(colour = 'green'), 540 axis.text.y.left = element_text(colour = 'blue'), 541 axis.text.y.right = element_text(colour = 'yellow'), 542 axis.ticks.x.top = element_line(colour = 'red'), 543 axis.ticks.x.bottom = element_line(colour = 'green'), 544 axis.ticks.y.left = element_line(colour = 'blue'), 545 axis.ticks.y.right = element_line(colour = 'yellow'), 546 axis.line.x.top = element_line(colour = 'red'), 547 axis.line.x.bottom = element_line(colour = 'green'), 548 axis.line.y.left = element_line(colour = 'blue'), 549 axis.line.y.right = element_line(colour = 'yellow') 550 ) 551 expect_doppelganger("axes_styling", plot) 552}) 553 554test_that("axes ticks can have independent lengths", { 555 plot <- ggplot() + 556 theme_test() + 557 geom_point(aes(1:10, 1:10)) + 558 scale_x_continuous(sec.axis = dup_axis()) + 559 scale_y_continuous(sec.axis = dup_axis()) + 560 theme( 561 axis.ticks.length.x.top = unit(-.5, "cm"), 562 axis.ticks.length.x.bottom = unit(-.25, "cm"), 563 axis.ticks.length.y.left = unit(.25, "cm"), 564 axis.ticks.length.y.right = unit(.5, "cm"), 565 axis.text.x.bottom = element_text(margin = margin(t = .25, unit = "cm")), 566 axis.text.x.top = element_text(margin = margin(b = .25, unit = "cm")) 567 ) 568 expect_doppelganger("ticks_length", plot) 569}) 570 571test_that("strips can be styled independently", { 572 df <- data_frame(x = 1:2, y = 1:2) 573 plot <- ggplot(df, aes(x, y)) + 574 facet_grid(x ~ y) + 575 theme( 576 strip.background.x = element_rect(fill = "red"), 577 strip.background.y = element_rect(fill = "green") 578 ) 579 expect_doppelganger("strip_styling", plot) 580}) 581 582test_that("rotated axis tick labels work", { 583 df <- data_frame( 584 y = c(1, 2, 3), 585 label = c("short", "medium size", "very long label") 586 ) 587 588 plot <- ggplot(df, aes(label, y)) + geom_point() + 589 theme(axis.text.x = element_text(angle = 50, hjust = 1)) 590 expect_doppelganger("rotated x axis tick labels", plot) 591}) 592 593test_that("plot titles and caption can be aligned to entire plot", { 594 df <- data_frame( 595 x = 1:3, 596 y = 1:3, 597 z = letters[1:3] 598 ) 599 600 plot <- ggplot(df, aes(x, y, color = z)) + 601 geom_point() + facet_wrap(~z) + 602 labs( 603 title = "Plot title aligned to entire plot", 604 subtitle = "Subtitle aligned to entire plot", 605 caption = "Caption aligned to panels" 606 ) + 607 theme(plot.title.position = "plot") 608 expect_doppelganger("titles aligned to entire plot", plot) 609 610 plot <- ggplot(df, aes(x, y, color = z)) + 611 geom_point() + facet_wrap(~z) + 612 labs( 613 title = "Plot title aligned to panels", 614 subtitle = "Subtitle aligned to panels", 615 caption = "Caption aligned to entire plot" 616 ) + 617 theme(plot.caption.position = "plot") 618 expect_doppelganger("caption aligned to entire plot", plot) 619 620}) 621 622test_that("Strips can render custom elements", { 623 element_test <- function(...) { 624 el <- element_text(...) 625 class(el) <- c('element_test', 'element_text', 'element') 626 el 627 } 628 element_grob.element_test <- function(element, label = "", x = NULL, y = NULL, ...) { 629 rectGrob(width = unit(1, "cm"), height = unit(1, "cm")) 630 } 631 df <- data_frame(x = 1:3, y = 1:3, a = letters[1:3]) 632 plot <- ggplot(df, aes(x, y)) + 633 geom_point() + 634 facet_wrap(~a) + 635 theme(strip.text = element_test()) 636 expect_doppelganger("custom strip elements can render", plot) 637}) 638