Skip to content

Compatibility current ggplot2 #410

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 5 commits into from
Mar 12, 2025
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
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)
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Per tidyverse/ggplot2#5991 (comment), this usage was incorrect but behaved correctly by accident. There currently isn't a linetype scale template that allows setting palettes directly, as is the case for many aesthetics IIRC. We can enable this, but it'd have to wait for the next release.

```

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
Loading