将边际总数添加到 R 中的 ggplot 热图
Adding marginal totals to ggplot heatmap in R
我想将总和和行总计添加到我的热图中,并努力使用已经建议的方法在其他 post 中实现,例如:.
上述 post 的问题是,我不理解创建总计(行、列)的代码。虽然它被标记为“#创建摘要行和列”,但我不明白。
所以如果...
1. ...有人可以帮助我并向我展示一种(简单的)方法来参考我的 posted 代码(下面)以及
2. ...如果行和列总计可以有单独的色标。
我试过了...
# create sample
scen <- 1:32
ls <- rep(1:7, length(scen))
df <- data.frame(Landscape = ls, Scenario = scen)
df$SoP <- sample(seq(-0.070, 0.070, by = 0.01),replace=T, nrow(df))
df$Landscape_Name <- LETTERS[1:7]
# create heatmap
library(ggplot2)
df.diff <- ggplot(df, aes(x = Landscape_Name, y = Scenario)) +
geom_tile(aes(fill = SoP)) +
geom_text(size = 3, aes(label = round(SoP,2))) + #displays cell values
scale_fill_gradient2(low = "gold", #colors
mid = "white",
high = "grey",
midpoint = 0) +
theme(panel.grid.major.x=element_blank(), #no gridlines
panel.grid.minor.x=element_blank(),
panel.grid.major.y=element_blank(),
panel.grid.minor.y=element_blank(),
panel.background=element_rect(fill="white"),
axis.text.x = element_text(angle=0, hjust = 0.5,vjust=0.5, size = 8,face = NULL),
axis.text.y = element_text(size = 8,face = NULL),
plot.title = element_text(size=10,face="bold")) +
ggtitle("Treatment efficiency") +
theme(legend.title=element_text(face="bold", size=8)) +
scale_x_discrete(name="Landscape", position = "top") +
scale_y_discrete(name="Scenario") +
labs(fill="SoP")
print(df.diff)
非常感谢您的帮助!
让我们看看我是否可以解释您引用的 post 中的答案,即 ggplot2: Independent Continuous Fill for Summary Row & Column
首先注意几点:
- 在
y
轴上,您绘制了一个数字向量,它被认为是一个连续的刻度,这就是为什么当您 运行 scale_y_discrete
时轴标签消失的原因,而该图工作正常,一旦我们决定向轴添加一个新值(即 Total
),这将导致问题,这就是为什么我认为 Scenario
应该是一个字符向量。
- 使用
as.character
将列 Scenario
转换为字符串会弄乱值的排序,例如尝试 运行ning sort(as.character(1:20))
,这可以通过使用 2 来避免数字(01、02、03、.....),这就是我在那里所做的
- 在上面提到的答案中,总数与原始 df 绑定,但是我将它们用作外部数据以使其更容易理解(或者至少我认为这样更容易)
我们开始吧:
library(ggplot2)
library(dplyr)
# pad numbers with zeros to get 2 digit numbers, this will be a string
scen <- sprintf('%02d', 1:32)
ls <- rep(1:7, length(scen))
df <- data.frame(Landscape = ls, Scenario = scen)
df$SoP <- sample(seq(-0.070, 0.070, by = 0.01),replace=T, nrow(df))
df$Landscape_Name <- LETTERS[1:7]
# create the main plot, and take a look at it
df.diff <- ggplot(df, aes(x = Landscape_Name, y = Scenario)) +
geom_tile(aes(fill = SoP)) +
geom_text(size = 3, aes(label = round(SoP,2))) + #displays cell values
scale_fill_gradient2(low = "gold", #colors
mid = "white",
high = "grey",
midpoint = 0)
df.diff
现在我们想要的数据允许我们向 Landscape_Name
添加一个额外的类别,并向 Scenario
添加一个额外的类别,这样:
- 添加到
Landscape_Name
的类别(水平总和)是每个 Scenario
和 的所有 SoP
的总和
- 添加到
Scenario
的类别(垂直总和)是每个 Landscape_Name
的所有 SoP
的总和
基本上我们需要group_by
和sum
h_total <- df %>%
group_by(Scenario) %>%
summarise(SoP = sum(SoP)) %>%
mutate(Landscape_Name = 'Total')
v_total <- df %>%
group_by(Landscape_Name) %>%
summarise(SoP = sum(SoP)) %>%
mutate(Scenario = 'Total')
现在我们可以将分组数据添加到原始图中,geom_point
,因为我们在新数据中使用了相同的列名,x
和 y
美学将从原始图继承,并使用与原始图不同的配色方案,我们使用 color
(而不是 fill
),这与所选形状配合得很好。
如果您还需要总计的单元格值,则还必须为这些单元格值添加图层
p <- df.diff +
geom_point(data = h_total,
aes(color = SoP),
size = 10,
shape = 19) +
geom_point(data = v_total,
aes(color = SoP),
size = 10,
shape = 19) +
scale_color_gradient2(low = "red", #colors
mid = "white",
high = "grey",
midpoint = 0) +
geom_text(data = h_total, size = 3, aes(label = round(SoP,2))) +
geom_text(data = v_total, size = 3, aes(label = round(SoP,2)))
p
最后添加主题定制、标题、轴和图例标签
p +
theme(panel.grid.major.x=element_blank(), #no gridlines
panel.grid.minor.x=element_blank(),
panel.grid.major.y=element_blank(),
panel.grid.minor.y=element_blank(),
panel.background=element_rect(fill="white"),
axis.text.x = element_text(angle=0, hjust = 0.5,vjust=0.5, size = 8,face = NULL),
axis.text.y = element_text(size = 8,face = NULL),
plot.title = element_text(size=10,face="bold"),
legend.title=element_text(face="bold", size=8)) +
scale_x_discrete(name="Landscape", position = "top") +
scale_y_discrete(name="Scenario",
# if you want the total to be at the bottom instead of at the top,
# you can set the limits of y with the reversed order of the categories
limits = rev(c(unique(as.character(df$Scenario)), 'Total'))) +
# you can here change the y/x ratio
coord_fixed(ratio = 0.4) +
labs(fill="SoP", color ="SoP Total") +
ggtitle("Treatment efficiency")
终于用ggsave(' PATH/TO/plot.jpeg', width =20, height = 40, units = 'cm')
挽救剧情了
这是输出
我想将总和和行总计添加到我的热图中,并努力使用已经建议的方法在其他 post 中实现,例如:
上述 post 的问题是,我不理解创建总计(行、列)的代码。虽然它被标记为“#创建摘要行和列”,但我不明白。
所以如果... 1. ...有人可以帮助我并向我展示一种(简单的)方法来参考我的 posted 代码(下面)以及 2. ...如果行和列总计可以有单独的色标。
我试过了...
# create sample
scen <- 1:32
ls <- rep(1:7, length(scen))
df <- data.frame(Landscape = ls, Scenario = scen)
df$SoP <- sample(seq(-0.070, 0.070, by = 0.01),replace=T, nrow(df))
df$Landscape_Name <- LETTERS[1:7]
# create heatmap
library(ggplot2)
df.diff <- ggplot(df, aes(x = Landscape_Name, y = Scenario)) +
geom_tile(aes(fill = SoP)) +
geom_text(size = 3, aes(label = round(SoP,2))) + #displays cell values
scale_fill_gradient2(low = "gold", #colors
mid = "white",
high = "grey",
midpoint = 0) +
theme(panel.grid.major.x=element_blank(), #no gridlines
panel.grid.minor.x=element_blank(),
panel.grid.major.y=element_blank(),
panel.grid.minor.y=element_blank(),
panel.background=element_rect(fill="white"),
axis.text.x = element_text(angle=0, hjust = 0.5,vjust=0.5, size = 8,face = NULL),
axis.text.y = element_text(size = 8,face = NULL),
plot.title = element_text(size=10,face="bold")) +
ggtitle("Treatment efficiency") +
theme(legend.title=element_text(face="bold", size=8)) +
scale_x_discrete(name="Landscape", position = "top") +
scale_y_discrete(name="Scenario") +
labs(fill="SoP")
print(df.diff)
非常感谢您的帮助!
让我们看看我是否可以解释您引用的 post 中的答案,即 ggplot2: Independent Continuous Fill for Summary Row & Column
首先注意几点:
- 在
y
轴上,您绘制了一个数字向量,它被认为是一个连续的刻度,这就是为什么当您 运行scale_y_discrete
时轴标签消失的原因,而该图工作正常,一旦我们决定向轴添加一个新值(即Total
),这将导致问题,这就是为什么我认为Scenario
应该是一个字符向量。 - 使用
as.character
将列Scenario
转换为字符串会弄乱值的排序,例如尝试 运行ningsort(as.character(1:20))
,这可以通过使用 2 来避免数字(01、02、03、.....),这就是我在那里所做的 - 在上面提到的答案中,总数与原始 df 绑定,但是我将它们用作外部数据以使其更容易理解(或者至少我认为这样更容易)
我们开始吧:
library(ggplot2)
library(dplyr)
# pad numbers with zeros to get 2 digit numbers, this will be a string
scen <- sprintf('%02d', 1:32)
ls <- rep(1:7, length(scen))
df <- data.frame(Landscape = ls, Scenario = scen)
df$SoP <- sample(seq(-0.070, 0.070, by = 0.01),replace=T, nrow(df))
df$Landscape_Name <- LETTERS[1:7]
# create the main plot, and take a look at it
df.diff <- ggplot(df, aes(x = Landscape_Name, y = Scenario)) +
geom_tile(aes(fill = SoP)) +
geom_text(size = 3, aes(label = round(SoP,2))) + #displays cell values
scale_fill_gradient2(low = "gold", #colors
mid = "white",
high = "grey",
midpoint = 0)
df.diff
现在我们想要的数据允许我们向 Landscape_Name
添加一个额外的类别,并向 Scenario
添加一个额外的类别,这样:
- 添加到
Landscape_Name
的类别(水平总和)是每个Scenario
和 的所有 - 添加到
Scenario
的类别(垂直总和)是每个Landscape_Name
的所有
SoP
的总和
SoP
的总和
基本上我们需要group_by
和sum
h_total <- df %>%
group_by(Scenario) %>%
summarise(SoP = sum(SoP)) %>%
mutate(Landscape_Name = 'Total')
v_total <- df %>%
group_by(Landscape_Name) %>%
summarise(SoP = sum(SoP)) %>%
mutate(Scenario = 'Total')
现在我们可以将分组数据添加到原始图中,geom_point
,因为我们在新数据中使用了相同的列名,x
和 y
美学将从原始图继承,并使用与原始图不同的配色方案,我们使用 color
(而不是 fill
),这与所选形状配合得很好。
如果您还需要总计的单元格值,则还必须为这些单元格值添加图层
p <- df.diff +
geom_point(data = h_total,
aes(color = SoP),
size = 10,
shape = 19) +
geom_point(data = v_total,
aes(color = SoP),
size = 10,
shape = 19) +
scale_color_gradient2(low = "red", #colors
mid = "white",
high = "grey",
midpoint = 0) +
geom_text(data = h_total, size = 3, aes(label = round(SoP,2))) +
geom_text(data = v_total, size = 3, aes(label = round(SoP,2)))
p
最后添加主题定制、标题、轴和图例标签
p +
theme(panel.grid.major.x=element_blank(), #no gridlines
panel.grid.minor.x=element_blank(),
panel.grid.major.y=element_blank(),
panel.grid.minor.y=element_blank(),
panel.background=element_rect(fill="white"),
axis.text.x = element_text(angle=0, hjust = 0.5,vjust=0.5, size = 8,face = NULL),
axis.text.y = element_text(size = 8,face = NULL),
plot.title = element_text(size=10,face="bold"),
legend.title=element_text(face="bold", size=8)) +
scale_x_discrete(name="Landscape", position = "top") +
scale_y_discrete(name="Scenario",
# if you want the total to be at the bottom instead of at the top,
# you can set the limits of y with the reversed order of the categories
limits = rev(c(unique(as.character(df$Scenario)), 'Total'))) +
# you can here change the y/x ratio
coord_fixed(ratio = 0.4) +
labs(fill="SoP", color ="SoP Total") +
ggtitle("Treatment efficiency")
终于用ggsave(' PATH/TO/plot.jpeg', width =20, height = 40, units = 'cm')
这是输出