Home > Net >  Side-by-Side plots lined up in R
Side-by-Side plots lined up in R

Time:03-12

I am trying to place two plots side-by-side in R and have the below example.

library(vioplot)
x <- rnorm(100)
y <- rpois(100,1)
plot(x, y, xlim=c(-5,5), ylim=c(-5,5),type='n')
vioplot(x, col="tomato", horizontal=TRUE, at=-4, add=TRUE,lty=2, rectCol="gray")
vioplot(y, col="cyan", horizontal=TRUE, at=-3, add=TRUE,lty=2)
vioplot(y, col="cyan", horizontal=TRUE, at=-2, add=TRUE,lty=2)

With this data, I'm able to make a vioplot of my x and y variables. Now, for example, I want to develop bar plots of separate count data that relates to each vioplot on the left-hand side.

counts <- c(10, 20, 30)
barplot(counts, main="Car Distribution", horiz=TRUE)

I've used the mtcars example but it could be any count data. I'm wondering if it is possible to generate these plots side-by-side so that the count plot lines up with the vioplot correctly. I do not need any y-axis labels for the count plot.

Thanks in advance.

CodePudding user response:

According your specifications ggplot is my recommendation

library(tidyverse)
p1 <- lst(x, y, y1=y) %>% 
  bind_cols() %>% 
  pivot_longer(1:3) %>% 
  ggplot(aes(name, value))   
   geom_violin(trim = FALSE) 
   geom_boxplot(width=0.15)   
   coord_flip()
p2 <- mtcars %>% 
  count(gear) %>% 
  ggplot(aes(gear, n))   
   geom_col() 
   coord_flip()
cowplot::plot_grid(p1, p2)

enter image description here

In base R you can do (please note, I used boxplot, but should work with viopülot either)

par(mfrow=c(1,2))
counts <- table(mtcars$gear)
boxplot(cbind(x,y,y), col="tomato", horizontal=TRUE,lty=2, rectCol="gray")
barplot(counts, main="Car Distribution", horiz=TRUE,
        names.arg=c("3 Gears", "4 Gears", "5 Gears"))

enter image description here

CodePudding user response:

You can use this code:

library(vioplot)
x <- rnorm(100)
y <- rpois(100,1)
par(mfrow=c(1,2))
plot(x, y, xlim=c(-5,5), ylim=c(-5,-1),type='n')
vioplot(x, col="tomato", horizontal=TRUE, at=-4, add=TRUE,lty=2, rectCol="gray")
vioplot(y, col="cyan", horizontal=TRUE, at=-3, add=TRUE,lty=2)
vioplot(y, col="cyan", horizontal=TRUE, at=-2, add=TRUE,lty=2)

counts <- table(mtcars$gear)
barplot(counts, main="Car Distribution", horiz=TRUE,
        names.arg=c("3 Gears", "4 Gears", "5 Gears"))

Output:

enter image description here

CodePudding user response:

Another option if you want to use ggplot is function ggarrange() from ggpubr.

library(dplyr)
library(ggplot2)
library(ggpubr)

# Create a sample dataset
dt <- tibble(group = rep(c("x", "y"), each = 100)) %>% 
        mutate(value = if_else(group == "x", rnorm(200),
                               as.double(rpois(200, 1))))

# Combined violin/Box plot
violins <- dt %>% 
        ggplot(aes(value, group))  
        geom_violin(width = 0.5)  
        geom_boxplot(width = 0.1)

# Bar chart
bars <- dt %>% 
        ggplot(aes(group))  
        geom_bar(width = 0.1)  
        coord_flip()

# Combine
ggpubr::ggarrange(violins, bars   rremove("ylab")   rremove("y.text"), ncol = 2)

Output: enter image description here

CodePudding user response:

Thank you for your interesting question, which has motivates me to explore base R graphics features. I have tried to find a case where the side-by-side configuration between the violin plot and the barplot provides a meaningful relationship. The case is that I have a subset of iris data with various counts of the species. I want to show three statistics:

  1. the counts of sampled each species, by showing barplots;
  2. the spread of sepal lengths in each sampled species, by showing violin plots; and
  3. the median petal width of each sampled species, by positioning the violin plots.

I follow @GW5's idea enter image description here

In case you want to put labels on the barplots (on the right side), you can use mtext as follows:

# ... (The same code above)
mtext(text = ir_names, side = 2, at = c(y_vio1, y_vio2, y_vio3), 
      line = 0.2, las  = 1 )

The resulted labels: enter image description here

  • Related