Skip to content

Ordered factor levels are rearranged on axis when layers are rearranged #3197

@sctyner

Description

@sctyner

What I want to do

Draw vertical lines with x-intercepts where the x-axis is a factor under a geom_line() call with different data but identical ordered factor levels.

library(ggplot2)
library(tibble)

x <- c("X", "Y", "8", "9", "12")
x <- factor(x, levels = x, ordered = T)

dat <- tibble(x = x, y = rnorm(5), group = c(0,0, 1,1,1))

str(dat$x)
#>  Ord.factor w/ 5 levels "X"<"Y"<"8"<"9"<..: 1 2 3 4 5

dat_missing <- tibble(x = x[c(1,2,5)], group = c(0,0,1))

str(dat_missing$x) #same levels as dat$x
#>  Ord.factor w/ 5 levels "X"<"Y"<"8"<"9"<..: 1 2 5

# what I actually want to do.
ggplot() +
  geom_vline(data = dat_missing, aes(xintercept = x)) +
  geom_line(data = dat , aes(x = x, y= y, group = group, color = as.factor(group))) +
  facet_wrap(~group)
#> Error in UseMethod("rescale"): no applicable method for 'rescale' applied to an object of class "c('ordered', 'factor')"

Per closed issue #1780 geom_vline() must be numeric. (For my purposes, the variable must be an ordered factor because it's DNA data that needs to be drawn in the correct order.)

So, I developed a work-around using geom_segment() and discovered some odd behavior: even though the two datasets I want to use (dat and dat_missing) have the same levels of the ordered factor, when dat_missing is used for the first layer (which is what I want), and dat is used for the second layer, the ordered variable becomes unordered and put in alphabetical order. This behavior is not reproduced when dat is used in the first layer and dat_missing is used in the second layer. The same thing happens if geom_point() is used instead of geom_segment(), so it's not the geom_segment() hack causing the behavior.

Since both variables mapped to x in aes() are ordered factors with the same levels, the order of the layers shouldn't matter IMO.

Reprex(es)

This almost does what I want but the layers are in the wrong order.

ggplot() +
  geom_line(data = dat , aes(x = x, y= y, group = group, color = as.factor(group))) +
  geom_segment(data = dat_missing, aes(x = x, xend = x, y = -Inf, yend = Inf)) +
  facet_wrap(~group)

This is the order of layers I want but it reorders the x axis.

ggplot() +
  geom_segment(data = dat_missing, aes(x = x, xend = x, y = -Inf, yend = Inf))  +
  geom_line(data = dat , aes(x = x, y= y, group = group, color = as.factor(group))) +
  facet_wrap(~group)

It behaves the same way without facets, so I guess this is the real min reprex:

Correct x axis:

ggplot() +
  geom_line(data = dat , aes(x = x, y= y, group = group, color = as.factor(group))) +
  geom_segment(data = dat_missing, aes(x = x, xend = x, y = -Inf, yend = Inf))

Incorrect x axis

ggplot() +
  geom_segment(data = dat_missing, aes(x = x, xend = x, y = -Inf, yend = Inf))  +
  geom_line(data = dat , aes(x = x, y= y, group = group, color = as.factor(group)))

Created on 2019-03-21 by the reprex package (v0.2.1)

Session info
devtools::session_info()
#> ─ Session info ──────────────────────────────────────────────────────────
#>  setting  value                       
#>  version  R version 3.5.2 (2018-12-20)
#>  os       macOS Mojave 10.14.3        
#>  system   x86_64, darwin15.6.0        
#>  ui       X11                         
#>  language (EN)                        
#>  collate  en_US.UTF-8                 
#>  ctype    en_US.UTF-8                 
#>  tz       America/Chicago             
#>  date     2019-03-21                  
#> 
#> ─ Packages ──────────────────────────────────────────────────────────────
#>  package     * version date       lib source                         
#>  assertthat    0.2.0   2017-04-11 [1] CRAN (R 3.5.0)                 
#>  backports     1.1.3   2018-12-14 [1] CRAN (R 3.5.1)                 
#>  callr         3.1.1   2018-12-21 [1] CRAN (R 3.5.0)                 
#>  cli           1.1.0   2019-03-19 [1] CRAN (R 3.5.2)                 
#>  colorspace    1.4-1   2019-03-18 [1] CRAN (R 3.5.2)                 
#>  crayon        1.3.4   2017-09-16 [1] CRAN (R 3.5.0)                 
#>  curl          3.3     2019-01-10 [1] CRAN (R 3.5.2)                 
#>  desc          1.2.0   2018-05-01 [1] CRAN (R 3.5.0)                 
#>  devtools      2.0.1   2018-10-26 [1] CRAN (R 3.5.1)                 
#>  digest        0.6.18  2018-10-10 [1] CRAN (R 3.5.0)                 
#>  dplyr         0.8.0.1 2019-02-15 [1] CRAN (R 3.5.2)                 
#>  evaluate      0.13    2019-02-12 [1] CRAN (R 3.5.2)                 
#>  fs            1.2.6   2018-08-23 [1] CRAN (R 3.5.0)                 
#>  ggplot2     * 3.1.0   2018-10-25 [1] CRAN (R 3.5.0)                 
#>  glue          1.3.1   2019-03-14 [1] Github (tidyverse/glue@f356a12)
#>  gtable        0.2.0   2016-02-26 [1] CRAN (R 3.5.0)                 
#>  highr         0.7     2018-06-09 [1] CRAN (R 3.5.0)                 
#>  htmltools     0.3.6   2017-04-28 [1] CRAN (R 3.5.0)                 
#>  httr          1.4.0   2018-12-11 [1] CRAN (R 3.5.0)                 
#>  knitr         1.22    2019-03-08 [1] CRAN (R 3.5.2)                 
#>  labeling      0.3     2014-08-23 [1] CRAN (R 3.5.0)                 
#>  lazyeval      0.2.2   2019-03-15 [1] CRAN (R 3.5.2)                 
#>  magrittr      1.5     2014-11-22 [1] CRAN (R 3.5.0)                 
#>  memoise       1.1.0   2017-04-21 [1] CRAN (R 3.5.0)                 
#>  mime          0.6     2018-10-05 [1] CRAN (R 3.5.0)                 
#>  munsell       0.5.0   2018-06-12 [1] CRAN (R 3.5.0)                 
#>  pillar        1.3.1   2018-12-15 [1] CRAN (R 3.5.0)                 
#>  pkgbuild      1.0.2   2018-10-16 [1] CRAN (R 3.5.0)                 
#>  pkgconfig     2.0.2   2018-08-16 [1] CRAN (R 3.5.0)                 
#>  pkgload       1.0.2   2018-10-29 [1] CRAN (R 3.5.0)                 
#>  plyr          1.8.4   2016-06-08 [1] CRAN (R 3.5.0)                 
#>  prettyunits   1.0.2   2015-07-13 [1] CRAN (R 3.5.0)                 
#>  processx      3.3.0   2019-03-10 [1] CRAN (R 3.5.2)                 
#>  ps            1.3.0   2018-12-21 [1] CRAN (R 3.5.0)                 
#>  purrr         0.3.2   2019-03-15 [1] CRAN (R 3.5.2)                 
#>  R6            2.4.0   2019-02-14 [1] CRAN (R 3.5.2)                 
#>  Rcpp          1.0.1   2019-03-17 [1] CRAN (R 3.5.2)                 
#>  remotes       2.0.2   2018-10-30 [1] CRAN (R 3.5.0)                 
#>  rlang         0.3.1   2019-01-08 [1] CRAN (R 3.5.2)                 
#>  rmarkdown     1.11    2018-12-08 [1] CRAN (R 3.5.0)                 
#>  rprojroot     1.3-2   2018-01-03 [1] CRAN (R 3.5.0)                 
#>  scales        1.0.0   2018-08-09 [1] CRAN (R 3.5.0)                 
#>  sessioninfo   1.1.1   2018-11-05 [1] CRAN (R 3.5.0)                 
#>  stringi       1.4.3   2019-03-12 [1] CRAN (R 3.5.2)                 
#>  stringr       1.4.0   2019-02-10 [1] CRAN (R 3.5.2)                 
#>  testthat      2.0.1   2018-10-13 [1] CRAN (R 3.5.0)                 
#>  tibble      * 2.1.1   2019-03-16 [1] CRAN (R 3.5.2)                 
#>  tidyselect    0.2.5   2018-10-11 [1] CRAN (R 3.5.0)                 
#>  usethis       1.4.0   2018-08-14 [1] CRAN (R 3.5.0)                 
#>  withr         2.1.2   2018-03-15 [1] CRAN (R 3.5.0)                 
#>  xfun          0.5.1   2019-02-25 [1] Github (yihui/xfun@d547831)    
#>  xml2          1.2.0   2018-01-24 [1] CRAN (R 3.5.1)                 
#>  yaml          2.2.0   2018-07-25 [1] CRAN (R 3.5.0)                 
#> 
#> [1] /Users/sctyner/Library/R/3.x/library
#> [2] /Library/Frameworks/R.framework/Versions/3.5/Resources/library

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions