ah bon
ah bon

Reputation: 10051

Fill the area above and below the central line in geom_step() with different colors

For the following PMI data, I would like to reproduce a plot similar to the figure below:

         date Eurozone.Markit.Composite.PMI France.Markit.Composite.PMI Germany.Markit.Composite.PMI
1   2022-1-31                          52.3                        52.7                         53.8
2   2022-2-28                          55.5                        55.5                         55.6
3   2022-3-31                          54.9                        56.3                         55.1
4   2022-4-30                          55.8                        57.6                         54.3
5   2022-5-31                          54.8                        57.0                         53.7
6   2022-6-30                          52.0                        52.5                         51.3
7   2022-7-31                          49.9                        51.7                         48.1
8   2022-8-31                          48.9                        50.4                         46.9
9   2022-9-30                          48.1                        51.2                         45.7
10 2022-10-31                          47.1                        50.0                         44.1

enter image description here

Figure source: Euro zone October PMI adds to evidence bloc is heading for recession

The most important thing is how to fill the area above and below the central line with different colors. How to implement it in R ggplot2 geom_step()? Thanks.

df <- structure(list(date = c("2022-1-31", "2022-2-28", "2022-3-31", 
"2022-4-30", "2022-5-31", "2022-6-30", "2022-7-31", "2022-8-31", 
"2022-9-30", "2022-10-31"), Eurozone.Markit.Composite.PMI = c(52.3, 
55.5, 54.9, 55.8, 54.8, 52, 49.9, 48.9, 48.1, 47.1), France.Markit.Composite.PMI = c(52.7, 
55.5, 56.3, 57.6, 57, 52.5, 51.7, 50.4, 51.2, 50), Germany.Markit.Composite.PMI = c(53.8, 
55.6, 55.1, 54.3, 53.7, 51.3, 48.1, 46.9, 45.7, 44.1)), class = "data.frame", row.names = c(NA, 
-10L))

My code:

vlines <- c(45, 50, 55)
ggplot(df, aes(date, Eurozone.Markit.Composite.PMI, group = 1, color='blue')) + 
  geom_step() +
  # geom_ribbon() +
  # geom_line() +
  # sapply(vlines, function(xint) geom_vline(aes(xintercept = xint)))
  geom_vline(xintercept=vlines) +
  theme_bw()

Out:

enter image description here

References:

R ggplot2: colouring step plot depending on value

Upvotes: 0

Views: 89

Answers (1)

stefan
stefan

Reputation: 125143

Using geom_rect and a bit of data wrangling you could do:

library(ggplot2)
library(dplyr)

df$date <- as.Date(df$date)

df <- df |> 
  mutate(xmax = lead(date), xmin = date, fill = Eurozone.Markit.Composite.PMI > 50)

ggplot(df, aes(x = date)) +
  geom_rect(aes(xmin = xmin, xmax = xmax, ymin = 50, ymax = Eurozone.Markit.Composite.PMI, fill = fill), alpha = .6) +
  geom_step(aes(y = Eurozone.Markit.Composite.PMI)) +
  geom_point(data = subset(df, date %in% range(date)), aes(y = Eurozone.Markit.Composite.PMI)) +
  geom_hline(yintercept = 50) +
  scale_fill_manual(values = c("red", "lightgreen")) +
  guides(fill = "none")
#> Warning: Removed 1 rows containing missing values (geom_rect).

Upvotes: 1

Related Questions