r - Vectorize text input to axislegend labels, possibly using marquee? - Stack Overflow

admin2025-04-29  2

I frequently want to adjust legend/axis labels to avoid text overlap; for example, aligning some to the left and some to the right. In the past, I've followed the solution here, which passes a vector to element_text(hjust()), while noting that it isn't an officially supported solution. Recently, this has started giving me weird results. The legend text is bold and pixelated (possibly layering multiple texts on top of each other?):

library(ggplot2)

set.seed(123)

df <- data.frame(
  x = runif(1000),
  y = runif(1000),
  z1 = rnorm(100)*10
)

p1 <- ggplot(df) + 
  geom_point(aes(x=x,y=y, color=z1)) + 
  scale_color_steps2(low = "blue", 
                     mid = "white", 
                     high = "red", 
                     midpoint = 0, 
                     guide = guide_colorbar(barwidth = 20),
                     breaks = c(-20, -10, -5, -1, 1, 5, 10, 20)) + 
  theme(legend.position = 'bottom') +
  labs(x='', y='', color='') 

p1 +
  theme(legend.text = element_text(hjust = c(rep(1, 4), rep(0, 4))))

I'd like to find a better solution. A similar problem posted here notes that element_text() is likely never going to support vectorized input, and suggests ggtext. However, ggtext stretches the length of the legend significantly, overriding the barwidth argument (and all my other attempts to set the legend width).

library(ggtext)
p1 +
  theme(legend.text = element_markdown(hjust = c(rep(1, 4), rep(0, 4))))

This discussion suggests that the new marquee package allows you to "specify different alignment options for each label", but I'm struggling to find examples of how to use the style system. The best I've come up with is the following, which still gives the "Vectorized input to element_text() is not officially supported" warning, and also removes my legend text altogether.

library(marquee)

p1 +
  theme(legend.text = marquee::element_marquee(hjust = c(rep(1, 4), rep(0, 4))))

Is there any way to do this at the current moment?

I frequently want to adjust legend/axis labels to avoid text overlap; for example, aligning some to the left and some to the right. In the past, I've followed the solution here, which passes a vector to element_text(hjust()), while noting that it isn't an officially supported solution. Recently, this has started giving me weird results. The legend text is bold and pixelated (possibly layering multiple texts on top of each other?):

library(ggplot2)

set.seed(123)

df <- data.frame(
  x = runif(1000),
  y = runif(1000),
  z1 = rnorm(100)*10
)

p1 <- ggplot(df) + 
  geom_point(aes(x=x,y=y, color=z1)) + 
  scale_color_steps2(low = "blue", 
                     mid = "white", 
                     high = "red", 
                     midpoint = 0, 
                     guide = guide_colorbar(barwidth = 20),
                     breaks = c(-20, -10, -5, -1, 1, 5, 10, 20)) + 
  theme(legend.position = 'bottom') +
  labs(x='', y='', color='') 

p1 +
  theme(legend.text = element_text(hjust = c(rep(1, 4), rep(0, 4))))

I'd like to find a better solution. A similar problem posted here notes that element_text() is likely never going to support vectorized input, and suggests ggtext. However, ggtext stretches the length of the legend significantly, overriding the barwidth argument (and all my other attempts to set the legend width).

library(ggtext)
p1 +
  theme(legend.text = element_markdown(hjust = c(rep(1, 4), rep(0, 4))))

This discussion suggests that the new marquee package allows you to "specify different alignment options for each label", but I'm struggling to find examples of how to use the style system. The best I've come up with is the following, which still gives the "Vectorized input to element_text() is not officially supported" warning, and also removes my legend text altogether.

library(marquee)

p1 +
  theme(legend.text = marquee::element_marquee(hjust = c(rep(1, 4), rep(0, 4))))

Is there any way to do this at the current moment?

Share Improve this question asked Jan 6 at 23:47 JakenJaken 5552 silver badges10 bronze badges
Add a comment  | 

1 Answer 1

Reset to default 0

For me, with marquee version 0.1.0 and ggplot2 3.5.1 using AGG graphics with R version 4.4.2 on OSX

p1 + theme( legend.text = marquee::element_marquee(hjust = c(rep(1, 4), rep(0, 4))) )

gives

转载请注明原文地址:http://anycun.com/QandA/1745938635a91388.html