Replicating a Graph using ggplot2

Donald Trump’s First-Term Approval Ratings

A calculation of Trump’s first-term approval ratings, accounting for each poll’s quality, recency, sample size and partisan lean.

This is a graph from fivethirtyeight.com looking at various political polls and the rates people both approved and disapproved of Donald Trump during his first presidential term. I think this is a well-made visual, and I appreciate the reference bar that tells you the average disapproval and approval rates at any given day.

If I were to have any qualms about this graph, it would be the colors used and the clarity of the labels. When talking about partisan politics, it is typical to have red representing right-leaning and blue representing left-leaning opinions, so this graph is unintuitive in that way, since I would not immediately think of orange and green when thinking of the types of voters who approved or disapproved of Trump. Secondly, the text telling the reader what each line represents is small and could be easy to overlook in my opinion, which is why I would opt for a more traditional legend for clarity’s sake.

Before addressing any critiques, I will attempt to replicate it using the ggplot2 layers.

ggplot(trump)+
  geom_point(aes(x = mdy(enddate), y = adjusted_approve), color = "green2", alpha = 0.05)+
  geom_smooth(aes(x = mdy(enddate), y = adjusted_approve), color = "green3", alpha = 0.05, span = 0.25)+
  #method = "gam", formula = y ~ s(x, bs = "cs")
  geom_point(aes(x = mdy(enddate), y = adjusted_disapprove), color = "orange", alpha = 0.05)+
  geom_smooth(method = "gam", formula = y ~ s(x, bs = "cs"), 
              aes(x = mdy(enddate), y = adjusted_disapprove), color = "orange3", alpha = 0.05)+
  scale_x_continuous(limits = c(date(mdy("1/23/2017")), date(mdy("1/20/2021"))))+
  scale_y_continuous(limits = c(20, 80))+
  scale_x_continuous(breaks = scales::breaks_width(121.667))+
  scale_x_date()+
  theme_light()+
  theme(panel.grid.minor.x = element_blank())+
  labs(title = "Donald Trump’s First-Term Approval Ratings", x = "", y = "")

What this replication failed to capture was non-numeric dates for the x-axis, a wiggly trendline, and a horizontal scrolling reference bar. Here, each minor vertical gridline is meant to alternatingly represent each January, May, and September over 4 years.

Making Improvements

As I mentioned earlier, the changes I would make to the original graph are a color change and adding a prominent legend.

ggplot(trump)+
  geom_point(aes(x = mdy(enddate), y = adjusted_disapprove), color = "cornflowerblue", alpha = 0.05)+
  geom_point(aes(x = mdy(enddate), y = adjusted_approve), color = "brown1", alpha = 0.05)+
  geom_smooth(aes(x = mdy(enddate), y = adjusted_approve, color = "% who Approve"), alpha = 0.05)+
  geom_smooth(aes(x = mdy(enddate), y = adjusted_disapprove, color = "% who Disapprove"), alpha = 0.05)+
  scale_color_manual(values=c("brown3", "royalblue2"))+
  scale_x_continuous(limits = c(date(mdy("1/23/2017")), date(mdy("1/20/2021"))))+
  scale_y_continuous(limits = c(20, 80))+
  scale_x_continuous(breaks = scales::breaks_width(121.667))+
  scale_x_date()+
  theme_light()+
  theme(panel.grid.minor.x = element_blank())+
  labs(title = "Donald Trump’s First-Term Approval Ratings", x = "", y = "", color = "Opinion on Trump")

Disappointingly, I could not find a working method to swap the items in my legend, so the keys are in the opposite order they are in the graph. I tried using scale_fill_discrete(), which did not yield any results.