1

enter image description here

I have plotted stacked bar plot and line graph in one which have two different data sets. I am getting two separate legends for both of them. I have tried all the possible things. Please find the attached code.

alldata = data.frame(x, aircargo, autototal, govtreceipts, 
iipconsumer,nongimports, railfreight)
linedata = data.frame(x,ceii)
melteddata = melt(alldata,id.vars="x")
plotS1 <- ggplot(melteddata)
plotS1 +  geom_bar(aes(x=ordered_x,y=value,factor=variable,fill=variable, 
                       order=-as.numeric(variable)), stat="identity") +
  geom_line(data=linedata, aes(x=as.numeric(ordered_x),y=ceii, color = "CEII"), lwd=1.5) + 
  scale_color_manual( values = c("#000000")) + 
  scale_fill_manual(name = "Components", values = c("#0000FF", "#FFC0CB", "#00FFFF", "#00FF00", "#FF00FF", "#20B2AA", "#000000")) + 
  theme(axis.text.x = element_text(angle = 90, vjust = 0.5, hjust=1)) + theme(plot.background = element_rect(fill = "#BFD5E3")) + 
  ggtitle("Monthly Contribution by Components (3 month MA)") + 
  theme( panel.border = element_blank(), panel.grid.major = element_blank(), panel.grid.minor = element_blank()) + labs( y = "", x = "") + 
  scale_y_continuous(labels = c("-0.30","-0.25","-0.2","-0.15","-0.10","-0.05", "0.00", "0.05", "0.10", "0.15", "0.20", "0.25", "0.30"), breaks = c(-0.30, -0.25, -0.20, -0.15, -0.10, -0.05, 0.00, 0.05, 0.10, 0.15, 0.20, 0.25, 0.30)) 

Dataset -

aircargo <- c(-0.027,   0.028,  0.044,  0.011,  0.041,  0.030,  -0.028, 0.017,  0.001,  0.060,  -0.040, 0.016,  0.006,  -0.040, -0.003, 0)

autototal <- c(0.061,   -0.004, 0.009,  0.024,  -0.026, 0.025,  -0.029, 0.000,  -0.015, -0.016, 0.026,  -0.062, 0.034,  0.002,  -0.081, -0.005)

govtreceipts <- c(-0.001,   0.001,  -0.005, 0.031,  -0.023, 0.000,  -0.009, 0.005,  0.002,  -0.005, 0.004,  0.000,  0.004,  -0.003, 0,  0)

iipconsumer <- c(0.043, -0.014, 0.041,  -0.035, 0.001,  0.001,  0.040,  0.010,  -0.006, 0.013,  0.001,  -0.006, -0.002, -0.011, -0.033, 0)

nongimports <- c(0.018, -0.008, 0.015,  -0.004, 0.019,  -0.010, 0.008,  0.007,  -0.021, 0.006,  -0.002, -0.007, 0.009,  -0.017, 0.005,  0)

railfreight <- c(0.014, -0.015, 0.031,  0.103,  -0.041, 0.025,  -0.044, 0.061,  -0.050, 0.092,  -0.045, 0.011,  -0.007, 0.050,  0.100,  -0.015)

x <- c("Jan-18",    "Feb-18",   "Mar-18",   "Apr-18",   "May-18",   "Jun-18",   "Jul-18",   "Aug-18",   "Sep-18",   "Oct-18",   "Nov-18",   "Dec-18",   "Jan-19",   "Feb-19",   "Mar-19",   "Apr-19")

ceii <- c(0.108,    -0.012, 0.134,  0.131,  -0.030, 0.072,  -0.062, 0.100,  -0.089, 0.149,  -0.070, -0.047, 0.043,  -0.019, -0.012, -0.020)

Please help in combining the legend. Thanks in advance.

  • Please provide sample data to reproduce your plot, as shown in https://stackoverflow.com/questions/5963269/how-to-make-a-great-r-reproducible-example – David Jorquera Sep 06 '19 at 19:30
  • My best guess is that you should make sure your `linedata` has a column named `variable` in it that has only a single value, `"CEII"`. Then you can map `variable` to `color` in the line geom and to `fill` in the bar geom. Make sure you use the same `name` in the `scale_*manual()` functions or the combined legend will get separated. – aosmith Sep 06 '19 at 19:38
  • I tried it, with the same name but still the legend are getting separated. Can you please tell me the exact command or modify my command. – Ayushi Jain Sep 07 '19 at 13:12
  • Please find the dataset used. @DavidJorquera – Ayushi Jain Sep 08 '19 at 17:01
  • @aosmith Please help. – Ayushi Jain Sep 08 '19 at 17:02

1 Answers1

0

One option is to get the same levels for the two factors. This takes some up front work with the data.frames.

For example, here's one way to do this, adding a variable named variable to linedata and then matching the factor levels.

melteddata = reshape2::melt(alldata, id.vars = "x")

# Add CEII to levels of "variable"
melteddata$variable = factor(melteddata$variable, 
                             levels = c(levels(melteddata$variable), "CEII") )


linedata = data.frame(x, ceii, variable = "CEII")

# Same levels in linedata as melteddata
linedata$variable = factor(linedata$variable, 
                           levels = levels(melteddata$variable) )

Then I made a vector for the colors outside of the plot so it can be used for both colors and fills. I made this a named vector since I find this best practice in case the order ever changes.

# Vector of colors
fillcol = c("#0000FF", "#FFC0CB", "#00FFFF", "#00FF00", "#FF00FF", "#20B2AA", "#000000")
names(fillcol) = levels(melteddata$variable)

Then you get a combined legend if you use drop = FALSE in the scale layers.

To get filled boxes plus a line box for the line you need override.aes within guide_legend(). I removed the fill from the last box so the line shows.

Note I didn't have your ordered_x variable so this is likely not exactly the plot you were looking for.

ggplot(melteddata) +  
    geom_col(aes(x = x, y = value, fill = variable) ) +
    geom_line(data = linedata, aes(x = x, y = ceii, 
                                   color = variable,
                                   group = 1), lwd = 1.5) + 
    scale_color_manual(name = "Components", drop = FALSE,
                         values = fillcol ) + 
    scale_fill_manual(name = "Components", drop = FALSE,
                      values = fillcol ) +
    guides(fill = guide_legend(override.aes = list(fill = c(fillcol[1:6], NA) ) ) )

enter image description here

aosmith
  • 34,856
  • 9
  • 84
  • 118
  • Thank you so much! It worked so well. But I just have a small conceptual doubt that when I am getting the graph the data points plotted do not show the actual data points. For eg - say the data point of air cargo is -0.02 , but the value it is showing in bar is more than -0.05 when all other are positive values. I have even added the picture of my graph above.@aosmith – Ayushi Jain Sep 10 '19 at 05:29
  • @AyushiJain Can you mark this question as solved (if it is) and then ask a new question? I don't think I see the issue in the plot I made, which makes me wonder if something happened when you set the `breaks`/`labels`. In a new question try making a very minimal example, possibly only including the month-year that shows the issue. That will help folks help you. – aosmith Sep 10 '19 at 14:12