3

I plot the observed values per place with points and errorbars, which works as expected.

Problems:

  1. I try also to plot the expected value per place as a short horizontal line, centered in the same way as the points. I use segments for this, the lines appear, however they are not centered and I cannot figure out how to control them.

  2. I would like to plot the reference value which is the same per year for all the places but changes from year to year. I get the line with geom_line, but it is oblique and I would like to have steps (or two lines with an interrupt). With geom_steps I get the vertical shift per place, not per year. I tried the geom_hline as well however with defining a data.frame with hline.data<-data.frame(hy=chunk$Reference.Value, hx=chunk$Year) a get two parallel lines along the whole plot.

Could you please show me what I am doing wrong? Thank you very much in advance!

The code with my attempts:

library(data.table)
library(ggplot2)

chunk<-fread("
Year;Places;Code;Name;Reference.Value;Value;Expected.Value;CI
2010;Place5;A12;Indicator;0.079;0.087;0.082;0.00286
2010;Place1;A12;Indicator;0.079;0.075;0.086;0.02317
2010;Place2;A12;Indicator;0.079;0.059;0.069;0.01955
2010;Place3;A12;Indicator;0.079;0.065;0.067;0.02712
2010;Place4;A12;Indicator;0.079;0.091;0.101;0.03211
2011;Place5;A12;Indicator;0.077;0.062;0.058;0.00260
2011;Place1;A12;Indicator;0.077;0.078;0.069;0.01736
2011;Place2;A12;Indicator;0.077;0.029;0.037;0.02821
2011;Place3;A12;Indicator;0.077;0.062;0.059;0.02166
2011;Place4;A12;Indicator;0.077;0.110;0.099;0.06452")

chunk[,`:=` (Year     = as.factor(Year),
               Places   = as.factor(Places),
               Code     = as.factor(Code),
               Name     = as.factor(Name)
)]

limits <- aes(ymax = Value+CI, ymin=Value-CI)
dodge <- position_dodge(width=0.9)

p <- ggplot(chunk, aes(colour=Places, fill=Places, y=Value, x=Year))

p + geom_linerange(limits, position=dodge) +
geom_point(position=dodge, size = 5) +
geom_segment(position=dodge,
           aes(group=Places, 
               y=Expected.Value, yend=Expected.Value, 
               x=as.numeric(Year)-0.01, xend=as.numeric(Year)+0.01)
) +
geom_line(position=dodge, aes(group=Places, y=Reference.Value,x=Year),   color="black")
# geom_step(position=dodge, direction="vh", aes(group=Places,y=Reference.Value,x=Year), color="black")
v_e
  • 377
  • 1
  • 9

2 Answers2

2

Here is my interpretation. You could get the 'dodge' offsets and use those for the beginnings/endings of your line segments. The group in all the geoms will be Year, and offests determined by dodge just say how far from that grouping the Place factors should be.

## Get offsets for dodge
dodgeWidth <- 0.9
nFactors <- length(levels(chunk[,Places]))
chunk[, `:=` (dPlaces = (dodgeWidth/nFactors)*(as.numeric(Places) - mean(as.numeric(Places))))]

limits <- aes(ymax = Value+CI, ymin=Value-CI)
dodge <- position_dodge(width=0.9)
p <- ggplot(chunk, aes(colour=Places, fill=Places, y=Value, x=Year))

p + geom_linerange(limits, position=dodge) +
  geom_point(position=dodge, size = 5) +
  geom_segment(position=dodge, aes(y=Expected.Value, yend=Expected.Value, 
                   x=as.numeric(Year)+dPlaces-0.1, xend=as.numeric(Year)+dPlaces+0.1)) +
  geom_step(aes(group=Year, y=Reference.Value, 
                x=as.numeric(Year)+dPlaces), color="black", linetype=2)

enter image description here

Rorschach
  • 31,301
  • 5
  • 78
  • 129
1

You can use geom_errorbar with stat = "hline" much as in this answer to get the horizontal lines dodged how you want them. You would use geom_errorbar twice, once for adding the Expected.Value lines and once for the Reference.Value lines.

ggplot(chunk, aes(colour=Places, fill=Places, y=Value, x=Year)) +
    geom_linerange(limits, position=dodge) +
    geom_point(position=dodge, size = 5) +
    geom_errorbar(stat = "hline", aes(yintercept = Expected.Value, ymax = ..y.., ymin = ..y..), 
                position = dodge, width = .8)  +
    geom_errorbar(stat = "hline", aes(group = Year, yintercept = Reference.Value, ymax = ..y.., ymin = ..y..), 
                position = dodge, color="black", width = .8, linetype = 2)

enter image description here

Edit

The stat = "hline" approach no longer works in the development version of R per this github issue. However, geom_errorbar can be used directly to achieve the same result.

ggplot(chunk, aes(colour=Places, fill=Places, y=Value, x=Year)) +
    geom_linerange(limits, position=dodge) +
    geom_point(position=dodge, size = 5) +
    geom_errorbar(aes(y = Expected.Value, ymax = ..y.., ymin = ..y..), 
                position = dodge, width = .8)  +
    geom_errorbar(aes(group = Year, y = Reference.Value, ymax = ..y.., ymin = ..y..), 
                position = dodge, color="black", width = .8, linetype = 2)
Community
  • 1
  • 1
aosmith
  • 34,856
  • 9
  • 84
  • 118
  • This is a very interesting option, thank you very much! – v_e Jun 22 '15 at 17:02
  • Another question if I dare :-) I understand what `..y..` means but cannot find a documentation to this. Could you please point me to it? Many thanks! – v_e Jun 22 '15 at 17:27
  • 1
    @v_e Those special variables are most often in the documentation for the appropriate `stat_*` function (see [here](http://stackoverflow.com/questions/15556069/documentation-for-special-variables-in-ggplot-count-density-etc) and [here](https://groups.google.com/forum/#!topic/ggplot2/I9PVlFAAe9U) for some info). In this case I haven't actually found the documentation, but `..y..` is a short-cut to avoid rewriting the name of the `yintercept` variable when using `geom_errorbar` like this as `ymax` and `ymin` are required aesthetics in `geom_errorbar` but are irrelevant to a horizontal line. – aosmith Jun 22 '15 at 20:18
  • Thanks again! I could not find this without you. – v_e Jun 23 '15 at 16:41