Skip to content

Commit

Permalink
Compatibility current ggplot2 (#410)
Browse files Browse the repository at this point in the history
* fix linetype scale

* fix outdated alternative build functions

* bump ggplot2 version

* Revert "fix linetype scale"

This reverts commit 99a1222.

* Use `discrete_scale()` instead of `scale_linetype()`
  • Loading branch information
teunbrand authored Mar 12, 2025
1 parent acd4f10 commit 34b224a
Show file tree
Hide file tree
Showing 4 changed files with 15 additions and 79 deletions.
2 changes: 1 addition & 1 deletion DESCRIPTION
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@ Imports:
ggforce,
gghighlight,
ggnewscale,
ggplot2,
ggplot2 (>= 3.5.0),
ggraph,
ggrepel,
ggtext,
Expand Down
8 changes: 4 additions & 4 deletions internals_ggbuild.R
Original file line number Diff line number Diff line change
Expand Up @@ -50,7 +50,7 @@ ggbuild <- function(plot) {


# Transform all scales
data <- lapply(data, ggplot2:::scales_transform_df, scales = scales) # ******
data <- lapply(data, scales$transform_df) # ******

# Record the layer data after scale transformation applied
all_steps$transformed <- data # ******
Expand All @@ -74,7 +74,7 @@ ggbuild <- function(plot) {
all_steps$poststat <- data # ******

# Make sure missing (but required) aesthetics are added
ggplot2:::scales_add_missing(plot, c("x", "y"), plot$plot_env) # ******
scales$add_missing(c("x", "y"), plot$plot_env) # ******

# Reparameterise geoms from (e.g.) y and width to ymin and ymax
data <- by_layer(function(l, d) l$compute_geom_1(d))
Expand All @@ -96,8 +96,8 @@ ggbuild <- function(plot) {
# Train and map non-position scales
npscales <- scales$non_position_scales()
if (npscales$n() > 0) {
lapply(data, ggplot2:::scales_train_df, scales = npscales) # ******
data <- lapply(data, ggplot2:::scales_map_df, scales = npscales) # ******
lapply(data, npscales$train_df) # ******
data <- lapply(data, npscales$map_df) # ******
}

# Fill in defaults etc.
Expand Down
72 changes: 2 additions & 70 deletions internals_gggtable.R
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,6 @@ gggtable <- function(data) {
theme <- ggplot2:::plot_theme(plot) # ******

geom_grobs <- Map(function(l, d) l$draw_geom(d, layout), plot$layers, data)
layout$setup_panel_guides(plot$guides, plot$layers, plot$mapping)
plot_table <- layout$render(geom_grobs, data, theme, plot$labels)

# Record the state after the panel layouts have done their job (I think!)
Expand All @@ -32,75 +31,8 @@ gggtable <- function(data) {
position <- "manual"
}

legend_box <- if (position != "none") {
ggplot2:::build_guides(plot$scales, plot$layers, plot$mapping, position, theme, plot$guides, plot$labels) # ******
} else {
zeroGrob()
}

if (ggplot2:::is.zero(legend_box)) { # ******
position <- "none"
} else {
# these are a bad hack, since it modifies the contents of viewpoint directly...
legend_width <- gtable:::gtable_width(legend_box) # ******
legend_height <- gtable:::gtable_height(legend_box) # ******

# Set the justification of the legend box
# First value is xjust, second value is yjust
just <- grid::valid.just(theme$legend.justification) # ******
xjust <- just[1]
yjust <- just[2]

if (position == "manual") {
xpos <- theme$legend.position[1]
ypos <- theme$legend.position[2]

# x and y are specified via theme$legend.position (i.e., coords)
legend_box <- grid::editGrob(legend_box, # ******
vp = grid::viewport(x = xpos, y = ypos, just = c(xjust, yjust), # ******
height = legend_height, width = legend_width))
} else {
# x and y are adjusted using justification of legend box (i.e., theme$legend.justification)
legend_box <- grid::editGrob(legend_box, # ******
vp = grid::viewport(x = xjust, y = yjust, just = c(xjust, yjust))) # ******
legend_box <- gtable:::gtable_add_rows(legend_box, unit(yjust, 'null')) # ******
legend_box <- gtable:::gtable_add_rows(legend_box, unit(1 - yjust, 'null'), 0) # ******
legend_box <- gtable:::gtable_add_cols(legend_box, unit(xjust, 'null'), 0) # ******
legend_box <- gtable:::gtable_add_cols(legend_box, unit(1 - xjust, 'null')) # ******
}
}

panel_dim <- find_panel(plot_table)
# for align-to-device, use this:
# panel_dim <- summarise(plot_table$layout, t = min(t), r = max(r), b = max(b), l = min(l))

theme$legend.box.spacing <- theme$legend.box.spacing %||% unit(0.2, 'cm')
if (position == "left") {
plot_table <- gtable::gtable_add_cols(plot_table, theme$legend.box.spacing, pos = 0) # ******
plot_table <- gtable::gtable_add_cols(plot_table, legend_width, pos = 0) # ******
plot_table <- gtable::gtable_add_grob(plot_table, legend_box, clip = "off", # ******
t = panel_dim$t, b = panel_dim$b, l = 1, r = 1, name = "guide-box")
} else if (position == "right") {
plot_table <- gtable::gtable_add_cols(plot_table, theme$legend.box.spacing, pos = -1) # ******
plot_table <- gtable::gtable_add_cols(plot_table, legend_width, pos = -1) # ******
plot_table <- gtable::gtable_add_grob(plot_table, legend_box, clip = "off", # ******
t = panel_dim$t, b = panel_dim$b, l = -1, r = -1, name = "guide-box")
} else if (position == "bottom") {
plot_table <- gtable::gtable_add_rows(plot_table, theme$legend.box.spacing, pos = -1) # ******
plot_table <- gtable::gtable_add_rows(plot_table, legend_height, pos = -1) # ******
plot_table <- gtable::gtable_add_grob(plot_table, legend_box, clip = "off", # ******
t = -1, b = -1, l = panel_dim$l, r = panel_dim$r, name = "guide-box")
} else if (position == "top") {
plot_table <- gtable::gtable_add_rows(plot_table, theme$legend.box.spacing, pos = 0) # ******
plot_table <- gtable::gtable_add_rows(plot_table, legend_height, pos = 0) # ******
plot_table <- gtable::gtable_add_grob(plot_table, legend_box, clip = "off", # ******
t = 1, b = 1, l = panel_dim$l, r = panel_dim$r, name = "guide-box")
} else if (position == "manual") {
# should guide box expand whole region or region without margin?
plot_table <- gtable::gtable_add_grob(plot_table, legend_box, # ******
t = panel_dim$t, b = panel_dim$b, l = panel_dim$l, r = panel_dim$r,
clip = "off", name = "guide-box")
}
legend_box <- plot$guides$assemble(theme)
plot_table <- ggplot2:::table_add_legends(plot_table, legend_box, theme)

# Record the state of the gtable after the legends have been added
all_states$legend <- plot_table # ******
Expand Down
12 changes: 8 additions & 4 deletions scales-other.qmd
Original file line number Diff line number Diff line change
Expand Up @@ -245,7 +245,9 @@ base <- ggplot(df, aes(linetype = value)) +
base
```

You can control the line type by specifying a string with up to 8 hexadecimal values (i.e., from 0 to F). In this specification, the first value is the length of the first line segment, the second value is the length of the first space between segments, and so on. This allows you to specify your own line types using `scale_linetype_manual()`, or alternatively, by passing a custom function to the `palette` argument:
You can control the line type by specifying a string with up to 8 hexadecimal values (i.e., from 0 to F).
In this specification, the first value is the length of the first line segment, the second value is the length of the first space between segments, and so on.
This allows you to specify your own line types using `scale_linetype_manual()`, or alternatively, by passing a custom function to the `palette` argument:

```{r}
#| eval: false
Expand All @@ -264,14 +266,16 @@ linetypes <- function(n) {
return(types[seq_len(n)])
}
base + scale_linetype(palette = linetypes)
base + discrete_scale("linetype", palette = linetypes)
```

Note that the last four lines are blank, because the `linetypes()` function defined above returns `NA` when the number of categories exceeds 9. The `scale_linetype()` function contains a `na.value` argument used to specify what kind of line is plotted for these values. By default this produces a blank line, but you can override this by setting `na.value = "dotted"`:
Note that the last four lines are blank, because the `linetypes()` function defined above returns `NA` when the number of categories exceeds 9.
The `discrete_scale()` function contains a `na.value` argument used to specify what kind of line is plotted for these values.
By default this produces a blank line, but you can override this by setting `na.value = "dotted"`:

```{r}
#| eval: false
base + scale_linetype(palette = linetypes, na.value = "dotted")
base + discrete_scale("linetype", palette = linetypes)
```

Valid line types can be set using a human readable character string: `"blank"`, `"solid"`, `"dashed"`, `"dotted"`, `"dotdash"`, `"longdash"`, and `"twodash"` are all understood.
Expand Down

0 comments on commit 34b224a

Please sign in to comment.