1
votes

I'm trying to plot a two "y" axis, the first one with "soil water content" in % (geom_line() ) and a geom_bar() with precipitation data. The problem is the precipitation chart. I need to "reverse" the plot.

I have this chart now:

Soil water content (%) and precipitation (cm) time serie

and I need the soil water content time series as image above but precipitation as following image

precipitation as i need but water content reversed

Transforming the data do not solve the problem since i can not transform the bar plot for visualize it form upside down since the data are bars not points. Overmore when i reverse the plot both axis turn reverse

the "hum_melt10" data frame is a data frame with 3 columns: fecha = date (daily), value = water content (%) and variable = if the data is from a probe o from a model

the "pp_melt" data frame is a data frame with 3 columns: fecha = date (daily), value = cm of precipitation for each day and variable = if the water is from precipitation or irrigation

gpp = ggplot() +
  geom_line(data = hum_melt10,aes(x = fecha, y = value, color = variable), size = 1.0) + 
  xlab("Fecha") +
  geom_bar(data = pp_melt, aes(x = fecha, y = value / 20, fill  = variable), stat="identity",position = 'dodge', na.rm = TRUE) +
  scale_y_continuous(name = "Contenido de agua (%)",sec.axis = sec_axis(~.*20, name = "pp y riego (cm)")) + 
  scale_x_date(breaks = '2 month', labels = fecha, date_labels = '%b %y') +
  theme(plot.title = element_text(lineheight=.8, face="bold", size = 20)) +
  theme_bw() + theme( panel.grid.major = element_blank(),
                      panel.grid.minor = element_blank(), axis.line = element_line(colour = "black"), aspect.ratio = 0.3) 

Thank you!

1
I think you might have to reverse the values of the second y axis and then manually label them. Quick tip though: please include a reproducible example. It doesn't much matter to us what your variables or data are, just what you're doing and want to do. You could create some fake data to use for the example so that we could tinker too.dmp
I agree with @dmp. The ability to add a second axis was a long-fought discussion in ggplot2 the finally resulted in the ability to effectively add just transformed labels; the second axis does nothing with the data itself. (This is clear by the need to do value in one and value/20 in the other.)r2evans

1 Answers

3
votes

Agreeing with @dmp, the use of sec_axis only adds the labels to the right; if you want to flip how it looks in the plot, you need to either

  1. Use scale_y_reverse(), which will flip everything;
  2. Manually flip the series in the aesthetic; or
  3. Manually flip the series in the data itself.

Since you only want to reverse one of the data series and not all of them, #1 is out. #3 does work, though you'll still need to modify the call to sec_axis, so I'll keep it simple with doing just #2.

library(ggplot2)
mt <- transform(mtcars, rn = 1:nrow(mtcars))
ggplot(mt) +
  geom_bar(aes(x = rn, y = drat), stat = "identity") +
  geom_line(aes(x = rn, y = disp/100), stat = "identity", color = "red", size = 1) +
  scale_y_continuous(sec.axis = sec_axis(~ . * 100))

ggplot of original data

Flipping just the red line, we change both how it is defined in the aesthetic (though it could be changed in the frame itself) and sec_axis.

ggplot(mt) +
  geom_bar(aes(x = rn, y = drat), stat = "identity") +
  geom_line(aes(x = rn, y = 5 - disp/100), stat = "identity", color = "red", size = 1) +
  # changes:                ^^^             vvv
  scale_y_continuous(sec.axis = sec_axis(~ (5 - .) * 100))

ggplot where one data is flipped in the aesthetic

(It's important to remember that the flipping point (5 in the example above) is based on the main-axis scale, not the new data.)

Without testing, I suspect the fix for your code would be something like this (where 9 is inferred from the plot).

gpp = ggplot() +
  geom_line(data = hum_melt10,aes(x = fecha, y = value, color = variable), size = 1.0) + 
  xlab("Fecha") +
  geom_bar(data = pp_melt, aes(x = fecha, y = 9 - value / 20, fill  = variable), stat="identity",position = 'dodge', na.rm = TRUE) +
  #  changes:                                 ^^^                          vvv
  scale_y_continuous(name = "Contenido de agua (%)", sec.axis = sec_axis(~(9 - .)*20, name = "pp y riego (cm)")) + 
  scale_x_date(breaks = '2 month', labels = fecha, date_labels = '%b %y') +
  theme(plot.title = element_text(lineheight=.8, face="bold", size = 20)) +
  theme_bw() + theme( panel.grid.major = element_blank(),
                     panel.grid.minor = element_blank(), axis.line = element_line(colour = "black"), aspect.ratio = 0.3)