【问题标题】:Side-by-Side plots lined up in RR中排列的并排图
【发布时间】:2022-07-08 12:16:26
【问题描述】:

我正在尝试在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 标签。

【问题讨论】:

  • 你试过par(mfrow=c(1,2))吗?
  • @Roman 让我可以将这些情节并排放置,但它不会将小提琴与每个情节中的小节对齐

标签: r plot count violin-plot


【解决方案1】:

根据您的规格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)

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

【讨论】:

    【解决方案2】:

    如果你想使用 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)
    

    输出:

    【讨论】:

      【解决方案3】:

      您可以使用此代码:

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

      输出:

      【讨论】:

      • 嗨@Quenten,我已经更新了示例以提供将删除条形图中标签的代码。但是,是否可以将条形图或 vioplot 排列到另一个的中心?
      【解决方案4】:

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

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

      我按照@GW5 的想法here 创建可以控制轴上位置的条形图。我按照@IRTFM 的想法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 )
      

      结果标签:

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2017-12-20
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2021-12-07
        • 2013-10-14
        相关资源
        最近更新 更多