在 R 中排列的并排图

Side-by-Side plots lined up in R

我试图在 R 中并排放置两个地块,并有以下示例。

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)

利用这些数据,我可以对我的 xy 变量进行 vioplot。现在,例如,我想绘制与左侧每个 vioplot 相关的单独计数数据的条形图。

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

我使用了 mtcars 示例,但它可以是任何计数数据。我想知道是否可以并排生成这些图,以便计数图与 vioplot 正确对齐。我不需要计数图的任何 y-axis 标签。

提前致谢。

您可以使用此代码:

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"))

输出:

根据你的规格ggplot是我的推荐

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)

在基础 R 中你可以这样做(请注意,我使用了箱线图,但也应该与 viopülot 一起使用)

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"))

如果你想使用 ggplot,另一个选项是 ggpubr 的函数 ggarrange()。

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)

输出:

感谢您提出有趣的问题,它激发了我探索基本 R 图形功能的动力。我试图找到一个案例,其中小提琴图和条形图之间的 side-by-side 配置提供了有意义的关系。情况是我有一个 iris 数据的子集,其中包含各种物种数量。我想显示三个统计数据:

  1. 每个物种的采样计数,通过显示条形图;
  2. 每个样本物种的萼片长度分布,通过显示小提琴图;和
  3. 通过定位小提琴图,每个采样物种的中值花瓣宽度。

我按照@GW5的想法 to create barplots of which the positions on the axes can be controlled. I follow @IRTFM's idea here来调整轴的原点。

完整代码如下:

library(vioplot)

some_iris <- iris[c(1:90, 110:139), ]
ir_counts <- some_iris |> with(Species) |> table()
ir_counts
#    setosa versicolor  virginica 
#        50         40         30 
ir_names <- names(ir_counts)
ir_colors <- c("cyan", "green", "pink")

x_vio1 <- some_iris |> subset(Species == ir_names[1]) |> with(Sepal.Length)
x_vio2 <- some_iris |> subset(Species == ir_names[2]) |> with(Sepal.Length)
x_vio3 <- some_iris |> subset(Species == ir_names[3]) |> with(Sepal.Length)

y_vio1 <- some_iris  |> subset(Species == ir_names[1]) |> with(Petal.Length) |> median() 
y_vio2 <- some_iris  |> subset(Species == ir_names[2]) |> with(Petal.Length) |> median() 
y_vio3 <- some_iris  |> subset(Species == ir_names[3]) |> with(Petal.Length) |> median() 

# `xpd = FALSE` to keep the grid inside the plotting boxes.

par(mfrow = c(1, 2), xpd = FALSE)

# The violin plots, put on the left side.

plot(NULL, 
     xlim = c(0, 10), ylim = c(0, 10), type = "n", las = 1, xaxs =  "i", yaxs = "i", 
     xlab = "Sepal Length (cm)", ylab = " Median Petal Width (cm)")

vioplot(x_vio1, col = ir_colors[1], horizontal = TRUE, at = y_vio1, add = TRUE, lty = 2)
vioplot(x_vio2, col = ir_colors[2], horizontal = TRUE, at = y_vio2, add = TRUE, lty = 2)
vioplot(x_vio3, col = ir_colors[3], horizontal = TRUE, at = y_vio3, add = TRUE, lty = 2)
grid()

# The texts that informs the names of the species

text(labels = ir_names, y = c(y_vio1, y_vio2, y_vio3), 
    x = c (min(x_vio1), min(x_vio2), min(x_vio3)) - 1)

# The barplots, put on the right side.

plot(NULL,
     xlim = c(0, 60), ylim = c(0, 10), yaxt = "n", type = "n", 
     las = 1, xlab = "Counts", ylab = "", xaxs = "i", yaxs = "i"
)
rect(xleft = 0, xright = ir_counts[1],
     ybottom = y_vio1 - 0.3, ytop = y_vio1 + 0.3, col = ir_colors[1])
rect(xleft = 0, xright = ir_counts[2],
     ybottom = y_vio2 - 0.3, ytop = y_vio2 + 0.3, col = ir_colors[2])
rect(xleft = 0, xright = ir_counts[3],
     ybottom = y_vio3 - 0.3, ytop = y_vio3 + 0.3, col = ir_colors[3])
grid()

结果如下:

如果您想在条形图(右侧)上放置标签,您可以使用 mtext,如下所示:

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

结果标签: