23

I did something like this with my data, but despite the transparency the segments are hard to visualise (my data has lot less number of segments than the example below) to see their beginning and end.

require(ggplot2)
ggplot(iris, aes(x = Petal.Length, xend = Petal.Width,
                 y = factor(Species), yend = factor(Species),
                 size = Sepal.Length)) +
    geom_segment(alpha = 0.05) + 
    geom_point(aes(shape = Species))

Came across this solution, but the lines are criss-crossed. Is there a way to make the jitter produce parallell lines with the points at the tips? I have tried position_dodge instead of position_jitter, but it requires ymax. Can ymax be integrated at all for use with geom_segment?

ggplot(iris, aes(x = Petal.Length, xend = Petal.Width,
                 y = factor(Species), yend = factor(Species))) +
    geom_segment(position = position_jitter(height = 0.25))+
    geom_point(aes(size = Sepal.Length, shape = Species))
Henrik
  • 61,039
  • 13
  • 131
  • 152
Anto
  • 1,099
  • 9
  • 15

1 Answers1

25

As far as I know, geom_segment does not allow jittering nor dodging. You can add jittering to the relevant variable in the data frame, then plot the jittered variable. In your example, the factor is converted to numeric, then the labels for the levels of the factor are added to the axis using scale_y_continuous.

library(ggplot2)
iris$JitterSpecies <- ave(as.numeric(iris$Species), iris$Species, 
   FUN = function(x) x + rnorm(length(x), sd = .1))

ggplot(iris, aes(x = Petal.Length, xend = Petal.Width,
                 y = JitterSpecies, yend = JitterSpecies)) +
    geom_segment()+
    geom_point(aes(size=Sepal.Length, shape=Species)) +
    scale_y_continuous("Species", breaks = c(1,2,3), labels = levels(iris$Species))

enter image description here

But it seems geom_linerange allows dodging.

ggplot(iris, aes(y = Petal.Length, ymin = Petal.Width,
                 x = Species, ymax = Petal.Length, group = row.names(iris))) +
       geom_point(position = position_dodge(.5)) +
     geom_linerange(position = position_dodge(.5)) +
     coord_flip()

enter image description here

Sandy Muspratt
  • 30,271
  • 11
  • 111
  • 119
  • Many thx! Both images are like the one I wanted. Will try it out. – Anto Feb 21 '14 at 09:11
  • Your first solution worked for me. With my data, the length of the segments represent time durations and when I use geom_linerange with facetting(scales='free'), the axis still show the whole range for the y-axis and just the range for each panel - probably because of the ymin and ymax settings. So, went in for the geom_segment. :) – Anto Feb 24 '14 at 09:54
  • 3
    @Sandy Muspratt Do you know of any documentation for the dodging behaviour of `geom_segment` ("As far as I know, `geom_segment` does not allow jittering nor dodging")? I have seen [**this post**](https://groups.google.com/forum/#!searchin/ggplot2/geom_segment$20position_dodge/ggplot2/iWojkpMicRY/ZMR75OOpHBQJ) on _vertical_ dodging, but I have a similar problem for horizontal dodging: `y` is dodged, but `yend` is not. It's slightly puzzling that `geom_segment` has a `position` argument if it's not working anyway... – Henrik Feb 10 '15 at 07:43