Skip to content

Instantly share code, notes, and snippets.

@paleolimbot
Last active July 2, 2019 14:10
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save paleolimbot/cbe59b49351edd15410df78838dd6e15 to your computer and use it in GitHub Desktop.
Save paleolimbot/cbe59b49351edd15410df78838dd6e15 to your computer and use it in GitHub Desktop.
library(ggplot2)
library(dplyr)
library(tibble)
SortingRange <- ggproto(
"SortingRange", ggplot2:::Range,
counted_range = tibble(value = character(0), n = integer(0)),
train = function(self, x, ...) {
new_counted_range <- tibble(value = x) %>%
count(value)
self$counted_range <- bind_rows(self$counted_range, new_counted_range) %>%
group_by(value) %>%
summarise(n = sum(n)) %>%
arrange(desc(n))
self$range <- self$counted_range$value
invisible(x)
}
)
ScaleDiscretePositionCounted <- ggproto(
"ScaleDiscreteCounted", ScaleDiscretePosition,
range = ggproto(NULL, SortingRange),
clone = function(self) {
new <- ggproto_parent(ScaleDiscretePosition, self)$clone()
new$range <- ggproto(NULL, SortingRange)
new
}
)
scale_x_discrete_sorted <- function(..., position = "bottom", expand = waiver()) {
sc <- discrete_scale(
c("x", "xmin", "xmax", "xend"), "position_d", identity, ...,
expand = expand, guide = "none", position = position, super = ScaleDiscretePositionCounted
)
sc$range_c <- ggplot2:::continuous_range()
sc
}
ggplot(mpg, aes(class)) +
geom_bar() +
facet_wrap(vars(drv), ncol = 1, scales = "fixed") +
scale_x_discrete_sorted()
@paleolimbot
Copy link
Author

library(ggplot2)
library(dplyr)
#> 
#> Attaching package: 'dplyr'
#> The following objects are masked from 'package:stats':
#> 
#>     filter, lag
#> The following objects are masked from 'package:base':
#> 
#>     intersect, setdiff, setequal, union
library(tibble)

SortingRange <- ggproto(
  "SortingRange", ggplot2:::Range,
  counted_range = tibble(value = character(0), n = integer(0)),
  
  train = function(self, x, ...) {
    new_counted_range <- tibble(value = x) %>%
      count(value)
    
    self$counted_range <- bind_rows(self$counted_range, new_counted_range) %>%
      group_by(value) %>%
      summarise(n = sum(n)) %>%
      arrange(desc(n))
    
    self$range <- self$counted_range$value
    
    invisible(x)
  }
)

ScaleDiscretePositionCounted <- ggproto(
  "ScaleDiscreteCounted", ScaleDiscretePosition,
  range = ggproto(NULL, SortingRange),
  clone = function(self) {
    new <- ggproto_parent(ScaleDiscretePosition, self)$clone()
    new$range <- ggproto(NULL, SortingRange)
    new
  }
)

scale_x_discrete_sorted <- function(..., position = "bottom", expand = waiver()) {
  sc <- discrete_scale(
    c("x", "xmin", "xmax", "xend"), "position_d", identity, ...,
    expand = expand, guide = "none", position = position, super = ScaleDiscretePositionCounted
  )
  
  sc$range_c <- ggplot2:::continuous_range()
  sc
}

ggplot(mpg, aes(class)) +
  geom_bar() +
  facet_wrap(vars(drv), ncol = 1, scales = "fixed") +
  scale_x_discrete_sorted()

Created on 2019-07-02 by the reprex package (v0.2.1)

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment