gpt4 book ai didi

r - 由线条连接的条形图/如何连接在 R/ggplot2 中使用 grid.arrange 排列的两个图形

转载 作者:行者123 更新时间:2023-12-04 11:44:49 25 4
gpt4 key购买 nike

在 Facebook 研究中,我发现了这些漂亮的条形图,这些条形图由线条连接以指示排名变化:
Facebook's solution

https://research.fb.com/do-jobs-run-in-families/

我想使用 ggplot2 创建它们。条形图部分很简单:

library(ggplot2)
library(ggpubr)
state1 <- data.frame(state=c(rep("ALABAMA",3), rep("CALIFORNIA",3)),
value=c(61,94,27,10,30,77),
type=rep(c("state","local","fed"),2),
cumSum=c(rep(182,3), rep(117,3)))
state2 <- data.frame(state=c(rep("ALABAMA",3), rep("CALIFORNIA",3)),
value=c(10,30,7,61,94,27),
type=rep(c("state","local","fed"),2),
cumSum=c(rep(117,3), rep(182,3)))
fill <- c("#40b8d0", "#b2d183", "#F9756D")

p1 <- ggplot(data = state1) +
geom_bar(aes(x = reorder(state, value), y = value, fill = type), stat="identity") +
theme_bw() +
scale_fill_manual(values=fill) +
labs(x="", y="Total budget in 1M$") +
theme(legend.position="none",
legend.direction="horizontal",
legend.title = element_blank(),
axis.line = element_line(size=1, colour = "black"),
panel.grid.major = element_blank(),
panel.grid.minor = element_blank(),
panel.border = element_blank(), panel.background = element_blank()) +
coord_flip()

p2 <- ggplot(data = state2) +
geom_bar(aes(x = reorder(state, value), y = value, fill = type), stat="identity") +
theme_bw() +
scale_fill_manual(values=fill) + labs(x="", y="Total budget in 1M$") +
theme(legend.position="none",
legend.direction="horizontal",
legend.title = element_blank(),
axis.line = element_line(size=1, colour = "black"),
panel.grid.major = element_blank(),
panel.grid.minor = element_blank(),
panel.border = element_blank(),
panel.background = element_blank()) +
scale_x_discrete(position = "top") +
scale_y_reverse() +
coord_flip()

p3 <- ggarrange(p1, p2, common.legend = TRUE, legend = "bottom")

但我无法想出解决线路部分的方法。添加行时,例如到左边
p3 + geom_segment(aes(x = rep(1:2, each=3), xend = rep(1:10, each=3), 
y = cumSum[order(cumSum)], yend=cumSum[order(cumSum)]+10), size = 1.2)

问题是这些线将无法跨越到右侧。
它看起来像这样:
My version so far

基本上,我想将左侧的“加利福尼亚”栏与右侧的凯福尼亚栏连接起来。

为此,我认为,我必须以某种方式访问​​图表的上级。我查看了视口(viewport),并能够用由 geom_segment 制成的图表覆盖两个条形图,但后来我无法找出线条的正确布局:
subplot <- ggplot(data = state1) + 
geom_segment(aes(x = rep(1:2, each=3), xend = rep(1:2, each=3),
y = cumSum[order(cumSum)], yend =cumSum[order(cumSum)]+10),
size = 1.2)

vp <- viewport(width = 1, height = 1, x = 1, y = unit(0.7, "lines"),
just ="right", "bottom"))
print(p3)
print(subplot, vp = vp)

非常感谢帮助或指针。

最佳答案

这是一个纯 ggplot2 解决方案,它将底层数据帧组合成一个并将所有内容绘制在一个图中:

数据操作:

library(dplyr)    
bar.width <- 0.9

# combine the two data sources
df <- rbind(state1 %>% mutate(source = "state1"),
state2 %>% mutate(source = "state2")) %>%

# calculate each state's rank within each data source
group_by(source, state) %>%
mutate(state.sum = sum(value)) %>%
ungroup() %>%
group_by(source) %>%
mutate(source.rank = as.integer(factor(state.sum))) %>%
ungroup() %>%

# calculate the dimensions for each bar
group_by(source, state) %>%
arrange(type) %>%
mutate(xmin = lag(cumsum(value), default = 0),
xmax = cumsum(value),
ymin = source.rank - bar.width / 2,
ymax = source.rank + bar.width / 2) %>%
ungroup() %>%

# shift each data source's coordinates away from point of origin,
# in order to create space for plotting lines
mutate(x = ifelse(source == "state1", -max(xmax) / 2, max(xmax) / 2)) %>%
mutate(xmin = ifelse(source == "state1", x - xmin, x + xmin),
xmax = ifelse(source == "state1", x - xmax, x + xmax)) %>%

# calculate label position for each data source
group_by(source) %>%
mutate(label.x = max(abs(xmax))) %>%
ungroup() %>%
mutate(label.x = ifelse(source == "state1", -label.x, label.x),
hjust = ifelse(source == "state1", 1.1, -0.1))

阴谋:
ggplot(df, 
aes(x = x, y = source.rank,
xmin = xmin, xmax = xmax,
ymin = ymin, ymax = ymax,
fill = type)) +
geom_rect() +
geom_line(aes(group = state)) +
geom_text(aes(x = label.x, label = state, hjust = hjust),
check_overlap = TRUE) +

# allow some space for the labels; this may be changed
# depending on plot dimensions
scale_x_continuous(expand = c(0.2, 0)) +
scale_fill_manual(values = fill) +

theme_void() +
theme(legend.position = "top")

plot

数据源(与@camille 相同):
set.seed(1017)

state1 <- data_frame(
state = rep(state.name[1:5], each = 3),
value = floor(runif(15, 1, 100)),
type = rep(c("state", "local", "fed"), times = 5)
)

state2 <- data_frame(
state = rep(state.name[1:5], each = 3),
value = floor(runif(15, 1, 100)),
type = rep(c("state", "local", "fed"), times = 5)
)

关于r - 由线条连接的条形图/如何连接在 R/ggplot2 中使用 grid.arrange 排列的两个图形,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/52864447/

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