Zoe
Zoe

Reputation: 1000

Labelling with scale_fill_stepsn(), "Breaks and labels are different lengths"

This is the plot I have:

enter image description here

I used this code (including sample data):

# dummy data
df_test <- data.frame(long = rep(447030:447050, 21),
                      lat = rep(5379630:5379650, each=21),
                      z = rnorm(21*21))

# plot
ggplot(df_test) +
  geom_tile(aes(x=long, y = lat, fill = z)) +
  scale_fill_stepsn(
    limits = c(-3, 3), breaks = seq(-3, 3, 1), # labels = seq(-3, 3, 1),
    colors = c("#ff6f69", "grey90", "#00aedb"))

I would like the legend to show the maximum and minimum value (-3, +3). But when I uncomment the label-code labels = seq(-3, 3, 1), I get an error:

Error: Breaks and labels are different lengths"

Is this a bug or am I misusing the function? (aka: Is it a bug or a feature?) Either way: Do you guys know any workaround / solution for this issue? Maybe something with override.aes() (I am not really good with that function)?

R version: 4.1.0 | ggplot2 version: 3.3.5

(Maybe related: Breaks and labels of different lengths scale_size_binned)

Edit: If I install ggplot2 version 3.3.3, the last box in the legend is bigger somehow (which I don't like either).

enter image description here

Upvotes: 2

Views: 1090

Answers (1)

teunbrand
teunbrand

Reputation: 37933

This is just a workaround for what I think might be a bug, but you might tweak the breaks a little bit to add/subtract a very small value:

library(ggplot2)

# dummy data
df_test <- data.frame(long = rep(447030:447050, 21),
                      lat = rep(5379630:5379650, each=21),
                      z = rnorm(21*21))

# plot
smallvalue <- 10 * .Machine$double.eps

ggplot(df_test) +
  geom_tile(aes(x=long, y = lat, fill = z)) +
  scale_fill_stepsn(
    limits = c(-3, 3), 
    breaks = c(-3 + smallvalue, -2:2, 3 - smallvalue), 
    labels = seq(-3, 3, 1),
    colors = c("#ff6f69", "grey90", "#00aedb")
  )

Created on 2021-08-06 by the reprex package (v1.0.0)

EDIT:

Alternatively, you can set the inner breaks and use a function for the labels argument.

library(ggplot2)

# dummy data
df_test <- data.frame(long = rep(447030:447050, 21),
                      lat = rep(5379630:5379650, each=21),
                      z = rnorm(21*21))

# plot
smallvalue <- 10 * .Machine$double.eps

ggplot(df_test) +
  geom_tile(aes(x=long, y = lat, fill = z)) +
  scale_fill_stepsn(
    limits = c(-3, 3), 
    breaks = -2:2,
    labels = function(x) {x}, # Just display the breaks
    show.limits = TRUE,
    colors = c("#ff6f69", "grey90", "#00aedb")
  )

Created on 2021-08-06 by the reprex package (v1.0.0)

Upvotes: 5

Related Questions