【问题标题】:barplot() with data points - base R带有数据点的 barplot() - 基础 R
【发布时间】:2020-03-16 08:57:03
【问题描述】:

我正在尝试在base R 的顶部绘制带有数据点的条形图。

我使用base R 是因为不可能以简单的方式在ggplot 中创建纹理填充(例如,参见here,而ggtexture 不允许进行复杂的编辑)。

使用barplot() 函数和points(),我可以做到这一点:

library(tidyverse)

#Sample data
data <- iris %>% 
  group_by(Species) %>% 
  summarise(m = mean(Sepal.Length), 
            se = sd(Sepal.Length)/
              sqrt(sum(!is.na(Sepal.Length)))) %>% 
  ungroup()

chart <- barplot(height=data$m, names=data$Species,
        density = c(5, 5, 5),
        angle = c(0,45,90),
        col = "brown",
        width = c(0.1,0.1,0.1), 
        font.axis = 2, 
        border = c("black"), 
        lwd = 2)

points(x = chart,
       y = data$m)

但是,我想创建类似于以下内容的内容:

iris %>% 
  group_by(Species) %>% 
  summarise(m = mean(Sepal.Length), 
            se = sd(Sepal.Length)/
              sqrt(sum(!is.na(Sepal.Length)))) %>% 
  ungroup() %>%
  ggplot(aes(Species, m, 
             group = Species, 
             color = Species, 
             shape = Species)) + 
  geom_bar(stat = "identity", fill="white",
           color="black") +
  geom_jitter(
    aes(Species, Sepal.Length),
    data = iris) 

【问题讨论】:

  • 我不想使用ggplot,除非可以使用纹理填充。

标签: r plot bar-chart


【解决方案1】:

使用barplot 输出作为标签将Species 转换为因子。然后使用as.numeric(as.character(x))) 方法转换回数字时,点会出现在每个组的正确位置。

# op <- par(xpd=TRUE)
b <- barplot(with(iris, tapply(Sepal.Length, Species, mean)), density=c(5, 5, 5), 
             angle=c(0, 45, 90), 
             col="brown", 
             width=c(0.1, 0.1, 0.1), 
             font.axis=2, 
             border=c("black"), 
             lwd=2, 
             ylim=c(0, max(jitter(iris$Sepal.Length)) * 1.15)  ## better use dynamic ylim
             )
iris$Species.f <- factor(iris$Species, labels=b)
with(iris, points(jitter(as.numeric(as.character(iris$Species.f))), 
                  jitter(Sepal.Length), pch=as.numeric(Species) + 14, 
                  col=as.numeric(Species) + 1, cex=.8))
legend("topleft", title="Species", legend=levels(iris$Species), 
       pch=seq(levels(iris$Species)) + 14, col=seq(levels(iris$Species)) + 1, 
       horiz=TRUE, cex=.8)
box(lwd=2)
# par(op)

【讨论】:

  • 很好地使用xpd=TRUE。我忘了那个。
  • @Edward 是的,但ylim 可能会更好,否则我们会在绘图区域上遇到麻烦。
【解决方案2】:

您可以在此处使用jitter 函数。

chart <- barplot(height=data$m, names=data$Species,
                 density = c(5, 5, 5),
                 angle = c(0,45,90),
                 col = "brown",
                 width = c(0.1,0.1,0.1), 
                 font.axis = 2, 
                 border = c("black"), 
                 lwd = 2, las=1,
                 ylim=c(0,8))

points(x = lapply(rep(chart, each=50), jitter, amount=0.05),
       y = iris$Sepal.Length,
       col=iris$Species, pch=20)

【讨论】:

  • 感谢您的评论,如果我的组大小不一,您有解决方案吗?因此,rep(chart, each=50) 不适用?
  • 那代码会稍微难看一点:c(rep(chart[1], n1), rep(chart[2], n2), rep(chart[3], n3))
猜你喜欢
  • 2015-10-29
  • 2019-12-19
  • 2017-10-19
  • 1970-01-01
  • 2023-03-07
  • 1970-01-01
  • 2021-02-08
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多