gpt4 book ai didi

r - ggplot2 + gridExtra : how to ensure geom_bar in different size plot grobs result in exact same bar width

转载 作者:行者123 更新时间:2023-12-01 06:32:59 24 4
gpt4 key购买 nike

这个问题的动机是进一步探索这个 question .当每个面的条形数量差异较大时,已接受解决方案的问题变得更加明显。使用该解决方案查看此数据和结果图:

# create slightly contrived data to better highlight width problems
data <- data.frame(ID=factor(c(rep(1,9), rep(2,6), rep(3,6), rep(4,3), rep(5,3))),
TYPE=factor(rep(1:3,length(ID)/3)),
TIME=factor(c(1,1,1,2,2,2,3,3,3,1,1,1,2,2,2,1,1,1,2,2,2,1,1,1,1,1,1)),
VAL=runif(27))

# implement previously suggested solution
base.width <- 0.9
data$w <- base.width
# facet two has 3 bars compared to facet one's 5 bars
data$w[data$TIME==2] <- base.width * 3/5
# facet 3 has 1 bar compared to facet one's 5 bars
data$w[data$TIME==3] <- base.width * 1/5
ggplot(data, aes(x=ID, y=VAL, fill=TYPE)) +
facet_wrap(~TIME, ncol=1, scale="free") +
geom_bar(position="stack", aes(width = w),stat = "identity") +
coord_flip()

widths all the same but spacing is bad

您会注意到宽度看起来完全正确,但第 3 方面的空白非常明显。在我见过的 ggplot2 中没有简单的方法来解决这个问题(facet_wrap 没有 space 选项)。

下一步是尝试使用 gridExtra 解决这个问题:
# create each of the three plots, don't worry about legend for now
p1 <- ggplot(data[data$TIME==1,], aes(x=ID, y=VAL, fill=TYPE)) +
facet_wrap(~ TIME, ncol=1) +
geom_bar(position="stack", show_guide=FALSE) +
coord_flip()
p2 <- ggplot(data[data$TIME==2,], aes(x=ID, y=VAL, fill=TYPE)) +
facet_wrap(~ TIME, ncol=1) +
geom_bar(position="stack", show_guide=FALSE) +
coord_flip()
p3 <- ggplot(data[data$TIME==3,], aes(x=ID, y=VAL, fill=TYPE)) +
facet_wrap(~ TIME, ncol=1) +
geom_bar(position="stack", show_guide=FALSE) +
coord_flip()

# use similar arithmetic to try and get layout correct
require(gridExtra)
heights <- c(5, 3, 1) / sum(5, 3, 1)
print(arrangeGrob(p1 ,p2, p3, ncol=1,
heights=heights))

widths wrong

您会注意到我使用了之前基于每个面的条形数量建议的相同算法,但在这种情况下,结果却大错特错。这似乎是因为我需要在数学中考虑额外的“恒定高度”元素。

另一个复杂性(我相信)是最终输出(以及宽度是否匹配)还取决于我将最终 grob 输出到的位置的宽度和高度,无论是在 R/RStudio 环境中,还是到一个 PNG 文件。

我怎样才能做到这一点?

最佳答案

像这样的东西似乎有效,但它没有 - 不完全。因为 ID 因子的级别是连续的,所以它看起来像是在工作。还有什么,还有 scale = "free"失败。但有可能进一步发展。该方法使用 facet_grid ,因此 space = "free"可以使用。该方法使用 geom_rect 将不同颜色的矩形相互叠加。它需要计算累积总和,以便可以定位每个矩形的右侧边缘。

data <- data.frame(ID=factor(c(rep(1,9), rep(2,6), rep(3,6), rep(4,3), rep(5,3))),
TYPE=factor(rep(1:3,3)),
TIME=factor(c(1,1,1,2,2,2,3,3,3,1,1,1,2,2,2,1,1,1,2,2,2,1,1,1,1,1,1)),
VAL=runif(27))

library(ggplot2)
library(plyr)

# Get the cumulative sums
data = ddply(data, .(ID, TIME), mutate, CUMSUMVAL = cumsum(VAL))

ggplot(data, aes(x=VAL, y = as.numeric(ID), fill=TYPE)) +
geom_rect(data = subset(data, TYPE == 3), aes(xmin = 0, xmax = CUMSUMVAL, ymin = as.numeric(ID)-.2, ymax = as.numeric(ID)+.2)) +
geom_rect(data = subset(data, TYPE == 2), aes(xmin = 0, xmax = CUMSUMVAL, ymin = as.numeric(ID)-.2, ymax = as.numeric(ID)+.2)) +
geom_rect(data = subset(data, TYPE == 1), aes(xmin = 0, xmax = CUMSUMVAL, ymin = as.numeric(ID)-.2, ymax = as.numeric(ID)+.2)) +
facet_grid(TIME~., space = "free", scale="free") +
scale_y_continuous(breaks = c(1:5), expand = c(0, 0.2))

enter image description here

编辑:或者真的粗线效果更好(我认为)
ggplot(data, aes(x=VAL, y = ID, colour=TYPE)) +
geom_segment(data = subset(data, TYPE == 3), aes(x = 0, xend = CUMSUMVAL, y = ID, yend = ID), size = 10) +
geom_segment(data = subset(data, TYPE == 2), aes(x = 0, xend = CUMSUMVAL, y = ID, yend = ID), size = 10) +
geom_segment(data = subset(data, TYPE == 1), aes(x = 0, xend = CUMSUMVAL, y = ID, yend = ID), size = 10) +
facet_grid(TIME~., space = "free", scale="free")

enter image description here

附加编辑 从您的早期帖子中获取数据,并对其进行一些修改。
更新 opts已弃用;使用 theme反而。
df <- structure(list(ID = structure(c(1L, 1L, 1L, 1L, 1L, 2L, 2L, 2L, 
2L, 2L, 2L, 3L, 3L, 3L, 3L, 3L, 3L, 4L, 4L, 4L, 4L, 4L, 4L, 5L,
5L, 5L, 5L, 5L, 5L, 6L, 6L, 6L, 6L, 6L, 6L, 7L, 7L, 7L), .Label = c("a",
"b", "c", "d", "e", "f", "g"), class = "factor"), TYPE = structure(c(1L,
2L, 3L, 4L, 5L, 1L, 2L, 3L, 4L, 5L, 6L, 1L, 2L, 3L, 4L, 5L, 6L,
1L, 2L, 3L, 4L, 5L, 6L, 1L, 2L, 3L, 4L, 5L, 6L, 1L, 2L, 3L, 4L,
5L, 6L, 1L, 2L, 3L), .Label = c("1", "2", "3", "4", "5", "6",
"7", "8"), class = "factor"), TIME = structure(c(2L, 2L, 2L,
2L, 2L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 2L, 2L,
2L, 2L, 2L, 2L, 1L, 1L, 1L, 1L, 1L, 1L, 3L, 3L, 3L, 3L, 3L, 3L,
1L, 1L, 1L), .Label = c("One", "Five", "Fifteen"), class = "factor"), VAL = c(0.937377670081332,
0.522220720537007, 0.278690102742985, 0.967633064137772, 0.116124767344445,
0.0544306698720902, 0.470229141646996, 0.62017166428268, 0.195459847105667,
0.732876230962574, 0.996336271753535, 0.983087373664603, 0.666449476964772,
0.291554537601769, 0.167933790013194, 0.860138458199799, 0.172361251665279,
0.833266809117049, 0.620465772924945, 0.786503327777609, 0.761877260869369,
0.425386636285111, 0.612077651312575, 0.178726130630821, 0.528709076810628,
0.492527724476531, 0.472576208412647, 0.0702785139437765, 0.696220921119675,
0.230852259788662, 0.359884874196723, 0.518227979075164, 0.259466265095398,
0.149970305617899, 0.00682218233123422, 0.463400925742462, 0.924704828299582,
0.229068386601284)), .Names = c("ID", "TYPE", "TIME", "VAL"), row.names = c(NA,
-38L), class = "data.frame")

library(ggplot2)
library(plyr)

data = ddply(df, .(ID, TIME), mutate, CUMSUMVAL = cumsum(VAL))

ggplot(data, aes(x=VAL, y = ID, colour=TYPE)) +
geom_segment(data = subset(data, TYPE == 6), aes(x = 0, xend = CUMSUMVAL, y = ID, yend = ID), size = 10) +
geom_segment(data = subset(data, TYPE == 5), aes(x = 0, xend = CUMSUMVAL, y = ID, yend = ID), size = 10) +
geom_segment(data = subset(data, TYPE == 4), aes(x = 0, xend = CUMSUMVAL, y = ID, yend = ID), size = 10) +
geom_segment(data = subset(data, TYPE == 3), aes(x = 0, xend = CUMSUMVAL, y = ID, yend = ID), size = 10) +
geom_segment(data = subset(data, TYPE == 2), aes(x = 0, xend = CUMSUMVAL, y = ID, yend = ID), size = 10) +
geom_segment(data = subset(data, TYPE == 1), aes(x = 0, xend = CUMSUMVAL, y = ID, yend = ID), size = 10) +
facet_grid(TIME~., space = "free", scale="free") +
theme(strip.text.y = element_text(angle = 0))

enter image description here

关于r - ggplot2 + gridExtra : how to ensure geom_bar in different size plot grobs result in exact same bar width,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/18237754/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com