Home > Net >  Time-varying width of geom_segment in ggplot2
Time-varying width of geom_segment in ggplot2

Time:10-05

I would like to plot a rectangle whose width increases as the x-axis on a plot increases. Geom_segment is a great way to plot lines but you cannot map size within aes(). You can only select one size for the entire segment:

 geom_segment(aes(x=5,xend=10,y=10,yend=10),size=10)

This doesn't work, the size doesn't vary with the value of x_axis_variable:

geom_segment(aes(x=5,xend=10,y=10,yend=10,size=x_axis_variable))

where x_axis_variable is whatever continuous variable you have plotted on the x-axis.

Is there a workaround, or some other option, to plot a single line whose size varies along the X or Y axes?

I'm happy to post some example data, but I'm actually not sure how helpful it would be for this question because it's not dependent upon data structure. I think it's just an artifact of geom_segment and hopefully there's another option. Thanks!

Edit with sort of the expected output:

enter image description here

Except that I'd like the line to increase gradually over the x-axis, not discretely as in the example.

CodePudding user response:

Can you just use geom_line()?

library(tidyverse)
library(ggplot2)

d <- tibble(x = 1:20, y=5)

ggplot(d, aes(x=x, y=y, size=I(x), color=x))   
  geom_line()

enter image description here

CodePudding user response:

Geom_segment is a great way to plot lines but you cannot map size within aes().

Is this premise true? Check out my artistic chart:

ggplot(mtcars)    
 geom_segment(aes(wt, mpg, xend = dplyr::lead(wt), 
                  yend = dplyr::lead(mpg), size = gear))

enter image description here

Or this:

ggplot(data = data.frame(x = 1:5),
       aes(x = x, xend = x   1,
           y = 0, yend = 0, size = x))  
  geom_segment()

enter image description here

geom_segment draws one segment with one size for each element of data you map. If you want the single segment to vary along its length, you might use ggforce::geom_link, like here, where it interpolates the size by making the segment into many pieces.

ggplot()  
  geom_segment(aes(x = 0, xend = 1, y = 0, yend = 0))  
  ggforce::geom_link(aes(x = 0, xend = 1, y = 0.5, yend = 0.5, size = after_stat(index)^2))  
  scale_size(range = c(0,10))
  

enter image description here

For a rectangle you might do something like:

ggplot()  
  ggforce::geom_link2(aes(x = c(0, 0, 1, 1, 0), 
                         xend = c(0, 1, 1, 0, 0),
                         y = c(0,1,1,0, 0), 
                         yend = c(1,1,0,0, 1),
                         size = c(1,1,2,2, 1)), lineend = "round") 
  

enter image description here

  • Related