0

I would like to add a some aditional lines to this plot. I must to show the distance for max and min data, from horizontal and vertical, like the example below.
Is like to add boxplots without the boxes

I have tried follow this example, but without success. Avoid plot overlay using geom_point in ggplot2

I did this on photoshop. But, how can i add on R?

Original plot

plot <- ggplot(mtcars, aes(x = wt, y = mpg, colour = factor(gear))) +
    geom_point() +
    ggtitle("Cars")

plot

simple cars plot

Modded version

enter image description here

Adilson V Casula
  • 164
  • 1
  • 16
  • 1
    These may get you started: [How to draw lines outside of plot area in ggplot2?](https://stackoverflow.com/questions/10525957/how-to-draw-lines-outside-of-plot-area-in-ggplot2), [ggplot2 - annotate outside of plot](https://stackoverflow.com/questions/12409960/ggplot2-annotate-outside-of-plot) – Henrik Jul 11 '18 at 14:06
  • Here's an answer with a variety of ways to do marginal histograms and rug plots: https://stackoverflow.com/q/8545035/5325862 None of them are lines out of the box like you're looking for, but I'm thinking about ways to adapt those solutions to do a line instead of a histogram – camille Jul 11 '18 at 14:37
  • Thank you Henrik. @camille this will be very usefull. I just added a new column with zeros on my db and now i'm doing scatter plots based on factors. this method will work fine i think. – Adilson V Casula Jul 11 '18 at 14:40
  • You might also look at the internals of `ggExtra::ggMarginal`. It lets you choose from density, histogram, boxplot, or violin for the summaries, and you can do them by group; you might be able to replicate that code but do maybe a `geom_segment` instead of the other summaries used there – camille Jul 11 '18 at 14:48

2 Answers2

2

I got intensely curious about this, but found that my go-to, cowplot, wouldn't quite space the plots properly. The package writer himself suggested using patchwork instead for more complex spacing and alignment. With cowplot, I'd made a dummy ggplot to hold the top right as a blank space, but couldn't get the heights right. patchwork instead has a plot_spacing function to do this.

The first task was to make a summary data frame for drawing the lines. I added a row number so there was a way to stack the lines vertically for the top margin, and horizontally for the right margin. (I suppose a dummy value and position_dodge may have worked also.)

library(tidyverse)
library(patchwork)

summaries <- mtcars %>%
  group_by(gear) %>%
  summarise(minwt = min(wt), maxwt = max(wt), minmpg = min(mpg), maxmpg = max(mpg)) %>%
  ungroup() %>%
  mutate(row = row_number())

summaries
#> # A tibble: 3 x 6
#>    gear minwt maxwt minmpg maxmpg   row
#>   <dbl> <dbl> <dbl>  <dbl>  <dbl> <int>
#> 1     3  2.46  5.42   10.4   21.5     1
#> 2     4  1.62  3.44   17.8   33.9     2
#> 3     5  1.51  3.57   15     30.4     3

I made the top and right plots, using the same ggplot base, and gave them theme_void so there would be nothing shown except the segments themselves. I'd suggest going through this with a different theme so you can see how the plots come together.

summary_base <- ggplot(summaries, aes(color = factor(gear)))

top <- summary_base +
  geom_segment(aes(x = minwt, xend = maxwt, y = row, yend = row), show.legend = F) +
  theme_void()

right <- summary_base +
  geom_segment(aes(x = row, xend = row, y = minmpg, yend = maxmpg), show.legend = F) +
  theme_void()

Then the main plot:

points <- ggplot(mtcars, aes(x = wt, y = mpg, color = factor(gear))) +
  geom_point() +
  theme(legend.position = "bottom")

Then patchwork allows you to just add the plots together. They go left to right, top to bottom, so to get the top right blank space, I used plot_spacer. Then plot_layout sets up the grid. You can adjust the relative heights and widths how you want—probably make them more narrow. This was my first time using patchwork, but it was very straightforward.

top + plot_spacer() + points + right + 
  plot_layout(ncol = 2, nrow = 2, widths = c(1, 0.2), heights = c(0.2, 1))

Created on 2018-07-11 by the reprex package (v0.2.0).

camille
  • 16,432
  • 18
  • 38
  • 60
2

Got this result. (on original plot)

I built 3 plots + a empty one, like suggested here: Scatterplot with marginal histograms in ggplot2

to the horizontal and vertical plots i used:

horizontal <- ggplot(mtcars, aes(wt, gear, colour = factor(gear)) +
    geom_point() +
    geom_line() +
    theme(legend.position = "none",
          panel.background = element_blank(), 
          panel.grid.major = element_blank(), 
          panel.grid.minor = element_blank(), 
          axis.text.x = element_blank(),
          axis.text.y = element_blank(),
          axis.ticks = element_blank(),
          plot.margin=unit(c(0,1,-0.4,0.7), "cm")) +
    xlab("") + ylab("")

horizontal <- ggplot(mtcars, aes(gear, mpg, colour = factor(gear)) +
    geom_point() +
    geom_line() +
    theme(legend.position = "none",
          panel.background = element_blank(), 
          panel.grid.major = element_blank(), 
          panel.grid.minor = element_blank(), 
          axis.text.x = element_blank(),
          axis.text.y = element_blank(),
          axis.ticks = element_blank(),
          plot.margin=unit(c(0,1,-0.4,0.7), "cm")) +
    xlab("") + ylab("")

The best fit is achieved managing the margins in each plot.

Then, the empty plot

empty <- ggplot()+geom_point(aes(1,1), colour="white")+
    theme(axis.ticks=element_blank(), 
          panel.background=element_blank(), 
          axis.text.x=element_blank(), axis.text.y=element_blank(),           
          axis.title.x=element_blank(), axis.title.y=element_blank())

so, join everything

grid.arrange(horizontal, empty, plot, vertical, ncol=2, nrow=2, 
             widths=c(1, 0.05), heights=c(0.5, 4))

enter image description here

Adilson V Casula
  • 164
  • 1
  • 16