组合条形图与 R ggplot2:闪避和堆叠
combined barplots with R ggplot2: dodged and stacked
我有一个 table 的数据,其中已经包含几个值,这些值将被绘制在带有 ggplot2 包的条形图上(已经是累积数据)。
数据框中的数据 "reserves" 具有以下形式(简化):
period,amount,a1,a2,b1,b2,h1,h2,h3,h4
J,18.1,30,60,40,60,15,50,30,5
K,29,65,35,75,25,5,50,40,5
P,13.3,94,6,85,15,10,55,20,15
N,21.6,95,5,80,20,10,55,20,15
第一列(周期)是地质时代。它将在 x 轴上,我不需要对其进行额外排序,因此我使用命令
准备了适当的因子标记
reserves$period <- factor(reserves$period, levels = reserves$period)
列 "amount" 是要绘制为 y 轴的主要列(它是每个时期中碳氢化合物的百分比,但也可以是绝对值,例如百万吨或其他) .所以基本情节由命令调用:
ggplot(reserves,aes(x=period,y=amount)) + geom_bar(stat="identity")
但问题来了。我需要在同一个条形图上绘制其他值,即 a1-a2、b1-b2 和 h1-h4。这些值是每个字母的百分比值(例如,a1=60,然后 a2=40;b1-b2 相同;对于 h1-h4,它们总计为 100。所以:我需要值 a1- a2 作为某种颜色,将 "amount" 条按比例划分为 x 的每个值(堆叠条形图),然后我需要相同的值 b1-b2;所以我们每个周期都有两个相邻的列(分组条形图),每个它们中的一个是堆叠的。接下来,我需要第三列,对于值 h1-h4,也许,也作为堆叠条形图,但要么作为第三列,要么作为第一列上方的交错条形图。
因此布局如下所示:
我知道我需要先用包 reshape2 重塑数据,然后在 geom_bar() 中使用选项 position="dodge" 或 position="fill",但这里是它们的组合。第三个条形图(对于值 h1-h4)似乎需要 "stacked percent" 具有固定高度的表示。
是否有以更直观的方式处理绘图数据的包?比方说,我们只是声明,我们想要绘制变量 ai、bi、hi。
首先,您应该将数据从宽变长,然后将您的比例缩放到它们的原始值。然后将您的旧列名称(现在 "lett" 级别)拆分为字母和数字以进行标记。如果您的真实数据不是这样格式化的 (a1...h4),也有办法处理它。
library(dplyr)
library(tidyr)
library(ggplot2)
reserves <- read.csv(text = "period,amount,a1,a2,b1,b2,h1,h2,h3,h4
J,18.1,30,60,40,60,15,50,30,5
K,29,65,35,75,25,5,50,40,5
P,13.3,94,6,85,15,10,55,20,15
N,21.6,95,5,80,20,10,55,20,15")
reserves.tidied <- reserves %>%
gather(key = lett, value = prop, -period, -amount) %>%
mutate(rawvalue = prop * amount/100,
lett1 = substr(lett, 1, 1),
num = substr(lett, 2, 2))
reserves.tidied
period amount lett prop rawvalue lett1 num
1 J 18.1 a1 30 5.430 a 1
2 K 29.0 a1 65 18.850 a 1
3 P 13.3 a1 94 12.502 a 1
4 N 21.6 a1 95 20.520 a 1
5 J 18.1 a2 60 10.860 a 2
6 K 29.0 a2 35 10.150 a 2
7 P 13.3 a2 6 0.798 a 2
8 N 21.6 a2 5 1.080 a 2
9 J 18.1 b1 40 7.240 b 1
10 K 29.0 b1 75 21.750 b 1
11 P 13.3 b1 85 11.305 b 1
12 N 21.6 b1 80 17.280 b 1
13 J 18.1 b2 60 10.860 b 2
14 K 29.0 b2 25 7.250 b 2
15 P 13.3 b2 15 1.995 b 2
16 N 21.6 b2 20 4.320 b 2
17 J 18.1 h1 15 2.715 h 1
18 K 29.0 h1 5 1.450 h 1
19 P 13.3 h1 10 1.330 h 1
20 N 21.6 h1 10 2.160 h 1
21 J 18.1 h2 50 9.050 h 2
22 K 29.0 h2 50 14.500 h 2
23 P 13.3 h2 55 7.315 h 2
24 N 21.6 h2 55 11.880 h 2
25 J 18.1 h3 30 5.430 h 3
26 K 29.0 h3 40 11.600 h 3
27 P 13.3 h3 20 2.660 h 3
28 N 21.6 h3 20 4.320 h 3
29 J 18.1 h4 5 0.905 h 4
30 K 29.0 h4 5 1.450 h 4
31 P 13.3 h4 15 1.995 h 4
32 N 21.6 h4 15 3.240 h 4
然后绘制整理后的数据,您需要横跨 x 轴的字母,以及我们刚刚用 amount*proportion 在 y 轴上计算的原始值。我们将 geom_col
从 1 堆叠到 2 或从 1 堆叠到 4(reverse=T
参数覆盖默认值,默认值将在堆栈底部有 2 或 4)。 alpha
和 fill
让我们区分同一柱中的组和柱之间的组。
然后 geom_text
用名称、换行符和原始百分比标记每个堆叠的段,以每个段为中心。 scale
再次反转默认行为,使每个栏中的 1 最暗,2 或 4 最亮。然后你 facet
穿过,为每个周期制作一组柱状图。
ggplot(reserves.tidied,
aes(x = lett1, y = rawvalue, alpha = num, fill = lett1)) +
geom_col(position = position_stack(reverse = T), colour = "black") +
geom_text(position = position_stack(reverse = T, vjust = .5),
aes(label = paste0(lett, ":\n", prop, "%")), alpha = 1) +
scale_alpha_discrete(range = c(1, .1)) +
facet_grid(~period) +
guides(fill = F, alpha = F)
重新排列它,使 "h" 条不同于 "a" 和 "b" 条有点复杂,您必须考虑您想要的方式呈现,但它是完全可行的。
我有一个 table 的数据,其中已经包含几个值,这些值将被绘制在带有 ggplot2 包的条形图上(已经是累积数据)。
数据框中的数据 "reserves" 具有以下形式(简化):
period,amount,a1,a2,b1,b2,h1,h2,h3,h4
J,18.1,30,60,40,60,15,50,30,5
K,29,65,35,75,25,5,50,40,5
P,13.3,94,6,85,15,10,55,20,15
N,21.6,95,5,80,20,10,55,20,15
第一列(周期)是地质时代。它将在 x 轴上,我不需要对其进行额外排序,因此我使用命令
准备了适当的因子标记reserves$period <- factor(reserves$period, levels = reserves$period)
列 "amount" 是要绘制为 y 轴的主要列(它是每个时期中碳氢化合物的百分比,但也可以是绝对值,例如百万吨或其他) .所以基本情节由命令调用:
ggplot(reserves,aes(x=period,y=amount)) + geom_bar(stat="identity")
但问题来了。我需要在同一个条形图上绘制其他值,即 a1-a2、b1-b2 和 h1-h4。这些值是每个字母的百分比值(例如,a1=60,然后 a2=40;b1-b2 相同;对于 h1-h4,它们总计为 100。所以:我需要值 a1- a2 作为某种颜色,将 "amount" 条按比例划分为 x 的每个值(堆叠条形图),然后我需要相同的值 b1-b2;所以我们每个周期都有两个相邻的列(分组条形图),每个它们中的一个是堆叠的。接下来,我需要第三列,对于值 h1-h4,也许,也作为堆叠条形图,但要么作为第三列,要么作为第一列上方的交错条形图。
因此布局如下所示:
我知道我需要先用包 reshape2 重塑数据,然后在 geom_bar() 中使用选项 position="dodge" 或 position="fill",但这里是它们的组合。第三个条形图(对于值 h1-h4)似乎需要 "stacked percent" 具有固定高度的表示。
是否有以更直观的方式处理绘图数据的包?比方说,我们只是声明,我们想要绘制变量 ai、bi、hi。
首先,您应该将数据从宽变长,然后将您的比例缩放到它们的原始值。然后将您的旧列名称(现在 "lett" 级别)拆分为字母和数字以进行标记。如果您的真实数据不是这样格式化的 (a1...h4),也有办法处理它。
library(dplyr)
library(tidyr)
library(ggplot2)
reserves <- read.csv(text = "period,amount,a1,a2,b1,b2,h1,h2,h3,h4
J,18.1,30,60,40,60,15,50,30,5
K,29,65,35,75,25,5,50,40,5
P,13.3,94,6,85,15,10,55,20,15
N,21.6,95,5,80,20,10,55,20,15")
reserves.tidied <- reserves %>%
gather(key = lett, value = prop, -period, -amount) %>%
mutate(rawvalue = prop * amount/100,
lett1 = substr(lett, 1, 1),
num = substr(lett, 2, 2))
reserves.tidied
period amount lett prop rawvalue lett1 num 1 J 18.1 a1 30 5.430 a 1 2 K 29.0 a1 65 18.850 a 1 3 P 13.3 a1 94 12.502 a 1 4 N 21.6 a1 95 20.520 a 1 5 J 18.1 a2 60 10.860 a 2 6 K 29.0 a2 35 10.150 a 2 7 P 13.3 a2 6 0.798 a 2 8 N 21.6 a2 5 1.080 a 2 9 J 18.1 b1 40 7.240 b 1 10 K 29.0 b1 75 21.750 b 1 11 P 13.3 b1 85 11.305 b 1 12 N 21.6 b1 80 17.280 b 1 13 J 18.1 b2 60 10.860 b 2 14 K 29.0 b2 25 7.250 b 2 15 P 13.3 b2 15 1.995 b 2 16 N 21.6 b2 20 4.320 b 2 17 J 18.1 h1 15 2.715 h 1 18 K 29.0 h1 5 1.450 h 1 19 P 13.3 h1 10 1.330 h 1 20 N 21.6 h1 10 2.160 h 1 21 J 18.1 h2 50 9.050 h 2 22 K 29.0 h2 50 14.500 h 2 23 P 13.3 h2 55 7.315 h 2 24 N 21.6 h2 55 11.880 h 2 25 J 18.1 h3 30 5.430 h 3 26 K 29.0 h3 40 11.600 h 3 27 P 13.3 h3 20 2.660 h 3 28 N 21.6 h3 20 4.320 h 3 29 J 18.1 h4 5 0.905 h 4 30 K 29.0 h4 5 1.450 h 4 31 P 13.3 h4 15 1.995 h 4 32 N 21.6 h4 15 3.240 h 4
然后绘制整理后的数据,您需要横跨 x 轴的字母,以及我们刚刚用 amount*proportion 在 y 轴上计算的原始值。我们将 geom_col
从 1 堆叠到 2 或从 1 堆叠到 4(reverse=T
参数覆盖默认值,默认值将在堆栈底部有 2 或 4)。 alpha
和 fill
让我们区分同一柱中的组和柱之间的组。
然后 geom_text
用名称、换行符和原始百分比标记每个堆叠的段,以每个段为中心。 scale
再次反转默认行为,使每个栏中的 1 最暗,2 或 4 最亮。然后你 facet
穿过,为每个周期制作一组柱状图。
ggplot(reserves.tidied,
aes(x = lett1, y = rawvalue, alpha = num, fill = lett1)) +
geom_col(position = position_stack(reverse = T), colour = "black") +
geom_text(position = position_stack(reverse = T, vjust = .5),
aes(label = paste0(lett, ":\n", prop, "%")), alpha = 1) +
scale_alpha_discrete(range = c(1, .1)) +
facet_grid(~period) +
guides(fill = F, alpha = F)
重新排列它,使 "h" 条不同于 "a" 和 "b" 条有点复杂,您必须考虑您想要的方式呈现,但它是完全可行的。