Home > Net >  geom_line(): styling legend
geom_line(): styling legend

Time:01-06

I am trying to make a plot using the following code:

p <- ggplot() 
  geom_line(fit.pre.net, mapping = aes(x = x, y = y, group = group, col = "Predicted (before SOEs)", linetype = "Predicted (before SOEs)"), size = 1)  
  geom_line(fit.mid.net, mapping = aes(x = x, y = y, group = group, col = "Predicted (during SOEs)", linetype = "Predicted (during SOEs)"), size = 1)  
  geom_line(fit.post.net, mapping = aes(x = x, y = y, group = group, col = "Predicted (after SOEs)", linetype = "Predicted (after SOEs)"), size = 1)  
  geom_line(fit.pre.count, mapping = aes(x = x, y = y, group = group, col = "Counterfactual (before SOEs)", linetype = "Counterfactual (before SOEs)"), size = 1)  
  geom_line(fit.mid.count, mapping = aes(x = x, y = y, group = group, col = "Counterfactual (during SOEs)", linetype = "Counterfactual (during SOEs)"), size = 1)  
  scale_linetype_manual(values = c("Predicted (before SOEs)" = "solid", "Predicted (during SOEs)" = "solid", "Predicted (after SOEs)" = "solid",
                                   "Counterfactual (before SOEs)" = "dashed", "Counterfactual (during SOEs)" = "dashed"))  
  scale_color_manual(values = c("Predicted (before SOEs)" = "steelblue4", "Counterfactual (before SOEs)" = "steelblue4",
                                "Predicted (during SOEs)" = "red", "Counterfactual (during SOEs)" = "red", "Predicted (after SOEs)" = "seagreen4")) 

And the legend looks like this: enter image description here

  1. Why does it show linetype and color separately, and how to combine them?
  2. I saw another example where "dashed" actually looks like "dashed", instead of just being a bit shorter than "solid" legend. Why and how to fix this?
  3. Right now, legend appeared on the right side of the graph. Is there a way to make it smaller and place it at the lower left bottom?

I want to assign color and linetype as follows:

"Predicted (before SOEs)": steelblue4, solid

"Predicted (during SOEs)": red, solid

"Predicted (after SOEs)": seagreen4, solid

"Counterfactual (before SOEs)": steelblue4, dashed

"Counterfactual (during SOEs)": red, dashed

Could anybody please tell me how to fix this issue?


As suggested in the comment, I tried this instead:

p <- ggplot
  geom_line(fit, mapping = aes(x = x, y = y, group = group, col = group, linetype = group), size = 1)  
  scale_linetype_manual(values = c("Predicted (before SOEs)" = "solid", "Predicted (during SOEs)" = "solid", "Predicted (after SOEs)" = "solid",
                                   "Counterfactual (before SOEs)" = "dashed", "Counterfactual (during SOEs)" = "dashed"))  
  scale_color_manual(values = c("Predicted (before SOEs)" = "steelblue4", "Counterfactual (before SOEs)" = "steelblue4",
                                "Predicted (during SOEs)" = "red", "Counterfactual (during SOEs)" = "red", "Predicted (after SOEs)" = "seagreen4")) 

The data looks like this now:

# A tibble: 10 × 3
   x           y group                       
   <chr>   <dbl> <chr>                       
 1 2018-01  24.7 Predicted (before SOEs)     
 2 2020-03  25.1 Predicted (before SOEs)     
 3 2020-04  25.3 Predicted (during SOEs)     
 4 2021-09  25.0 Predicted (during SOEs)     
 5 2021-10  25.2 Predicted (after SOEs)      
 6 2022-07  25.2 Predicted (after SOEs)      
 7 2020-04  25.1 Counterfactual (before SOEs)
 8 2021-09  25.4 Counterfactual (before SOEs)
 9 2021-10  25.0 Counterfactual (during SOEs)
10 2022-07  24.9 Counterfactual (during SOEs)

I then found that I can change legend place and size by adding the following code inside theme():

legend.text=element_text(size=10),
legend.justification=c(0.05,0.05),legend.position=c(0.05,0.05),legend.title=element_blank()

Now, 1 and 3 are solved, but my dashed legend still looks weird... What could be the problem here?

enter image description here

CodePudding user response:

The reason your linetypes are not properly visible in the legend key is that the size of the lines in the legend key are too large to see the linetype aesthetic. The solution for this problem is to explicitly define the size to use in the legend to be smaller. By default, the legend key aesthetics match what is drawn by the geom_*() command, but you can redefine the aesthetics to use in the legend or change the size of the keys to fix the problem.

Example of the Problem

Here's an example that demonstrates this problem well and the fix above. First, here's the basic plot:

library(ggplot2)

p <- ggplot(iris, aes(Sepal.Length, Sepal.Width, color=Species, linetype=Species))
p   geom_line()

enter image description here

In the plot above, you can easily differentiate linetypes in the legend. Note that the size and aesthetics of the legend keys match what is displayed in the main panel. Let's see what happens when we define a larger size for the lines within geom_line():

p   geom_line(size=1.8)

enter image description here

Look familiar? The larger line size relative to the legend key size causes the legend keys to not look correct. You can fix this by either making the legend keys larger or by redefining the aesthetics to use for drawing the legend.

Fix 1: Changing Legend Size

To change the size of the legend, you can use theme() elements legend.key.size or legend.key.width, or legend.key.height. I like legend.key.width here, since we're looking at horizontal lines:

p   geom_line(size=1.8)  
  theme(legend.key.width = unit(40, 'pt'))

enter image description here

Fix 2: Changing Legend Aesthetics

A potentially better solution (in my mind) is to define explicitly the aesthetics to use in the legend. This can be used to tell ggplot to "draw it smaller" in the legend:

p   geom_line(size=1.8)  
  guides(
    linetype=guide_legend(override.aes = list(size=1))
  )

enter image description here

The fix to use will depend depend on your particular plot and how it looks compared to the legend as well as personal preference.

  • Related