0

I would like to merge 3 plots seamlessly together. My problem is that the plots are slightly shifted and that even if I plot them without borders, they do not merge seamlessly between plot 1 and 2 / plot 2 and 3.

library(tidyverse)
library(gridExtra)

plot1 <- ggplot(df) +
  theme_dark() +
  geom_line(aes(y = Price, x = time, color = "#00FFFF"), size = 0.7) +
  geom_area(aes(y = Price, x = time), fill = "#00FFFF", alpha = .1) +
  theme(axis.title.x=element_blank(),
        axis.text.x=element_blank(),
        axis.ticks.x=element_blank(),
        legend.position = c(.1, .95),
        legend.justification = c("right", "top"),
        legend.box.just = "right",
        legend.margin = margin(3, 3, 3, 3),
        plot.margin = margin(0,-0.5,-0.5,-0.5),
        plot.background = element_rect(fill = "#808080")) +
  scale_colour_manual(name = "Price", 
                      values = c("#00FFFF" = "#00FFFF"), labels = c("Stock")) +
  labs(y = "")
#  
plot1
#
plot2 <- ggplot(df) +
  theme_dark() +
  geom_bar(aes(x = time, y = B, fill = "green"), stat = "identity") +
  geom_bar(aes(x = time, y = S, fill = "red"), stat = "identity") +
  theme(axis.title.x=element_blank(),
        axis.text.x=element_blank(),
        axis.ticks.x=element_blank(),
        panel.border = element_blank(),
        legend.position = c(.1, .95),
        legend.justification = c("right", "top"),
        legend.box.just = "right",
        legend.margin = margin(3, 3, 3, 3),
        plot.margin = margin(-0.75,-0.5,0,-0.5),
        plot.background = element_rect(fill = "#808080")) +
  scale_fill_identity(name = "Volume",
                      guide = "legend", labels = c("B", "S")) +
  labs(y = "")
#
plot2
#
plot3 <- ggplot(df) +
  theme_dark() +
  geom_line(aes(y = EMA_short, x = time, color = "blue"), size = 0.7) +
  geom_area(aes(y = EMA_short, x = time), fill = "blue", alpha = .1) +
  geom_line(aes(y = EMA_long, x = time, color = "yellow"), size = 0.7) +
  geom_area(aes(y = EMA_long, x = time), fill = "yellow", alpha = .1) +
  theme(axis.title.x=element_blank(),
        axis.ticks.x=element_blank(),
        panel.border = element_blank(),
        legend.position = c(.1, .95),
        legend.justification = c("right", "top"),
        legend.box.just = "right",
        legend.margin = margin(3, 3, 3, 3),
        plot.margin = margin(-0.75,-0.5,2,-0.5),
        plot.background = element_rect(fill = "#808080")) +
  scale_colour_manual(name = "EMA", 
                      values = c("blue" = "blue", "yellow" = "yellow"), labels = c("EMA50", "EMA200")) +
  labs(y = "")
#
plot3
#
gA <- ggplotGrob(plot1)
gB <- ggplotGrob(plot2)
gC <- ggplotGrob(plot3)
grid::grid.newpage()
grid::grid.draw(rbind(gA, gB, gC))

In my mind I would like the 3 plots to merge into each other in a similar way as here: similar plot

I am grateful for any advice.

Edit

Thanks for the very helpful answers. I only have two small optical problems now. Although I have positioned all the legends the same, they are positioned somewhere else. Should I format them all into the same size? And unfortunately there are two small white spots on the left, as shown in the picture. I have already tried to make the edges bigger and smaller, but the spots there always stay white. I updated my new code above. Thanks! enter image description here

Qncy
  • 57
  • 6

2 Answers2

1

You should consider expand(c(0,0)) and/or theme(plot.margin = c(t,r,b,l))

First, add x and y expand parameters for each of the plot, to supress the blank space around your data, which is the default of ggplot:

plot1 + scale_y_continuous("", expand = c(0,0)) 
# we indicate here 'no label', so you should supress '+ ylab()'
plot1 + scale_x_datetime("", expand = c(0,0)) 
# same, you should supress 'xlab()' from the plots
  1. This let you with the minimal margin added between the plots by grid.arrange, and you could adjust these whith the theme(plot.margin = c(t,r,b,l)) (e.g., plot1 +theme(plot.margin(-0.5,-0.5,-0.5,-0.5))). In you're case, you're maybe need to adress the top and/or bottom of 2 plots (be careful with the middle one if the 2 others don't have margins).
  2. Sometimes you have to play with the output-size (height and width of the grid.arrange), typically when you save an arrangegrob object (e.g., ggsave( arrangeGrob(plot1, plot2)) need to adress the sizes).
  3. Please, note that you have to place your legend in the top, the bottom, or inside the plots, in order to stack the plots with same 'data-area' sizes. When legends doesn't have the same size, you can't stack the plots with legend in left or right position. So, add +theme(legend.position = 'top') for your 3 plots, or bottom or some coordinate.
Community
  • 1
  • 1
Clément LVD
  • 648
  • 5
  • 12
  • Thank you! I have a little trouble implementing it in my code. I will try again later when im back home. – Qncy Jun 17 '20 at 08:20
  • You're welcome. I suggest to test step by step, in order to understand which part of your plot is affected: (a) `expand()` in scale_y or scale_x remove space between the data-area and the axes, inside the plot; and (b) `theme(plot.margin=` let you crop the exterior-margins, from the outside of the plot (after axes labels); and (c), your desired output-legends [black-theme] are inside the plots (so indicate coordinate like `theme(legend.position= c(0.95,0.1))` – Clément LVD Jun 17 '20 at 08:52
  • I got it. I only have two small optical problems now as you can see above. Maybe you have a solution for this too. – Qncy Jun 18 '20 at 10:47
1

1- You made custom legend by indicate arguments in the theme() parameter, e.g.,

plot1 + theme(legend.background = element_blank(), legend.text.align=0, legend.title.align = 0))
#a legend with no white background, left text and title alignment. 

2- The area where the legend-lines have the guides() parameter, in order to indicate your very special key:

# (e.g., remove the little grey area background for the legend):
 plot1 + guides(color=guide_legend(override.aes=list(fill=NA)))

3- If necessary, read some parameters of the theme() and guides() func, in order to understand - multiples - themes arguments and create your personnal-darky-style-func().

Clément LVD
  • 648
  • 5
  • 12