为超过/低于阈值的值制作不同颜色的ggplot2热图
Posted
技术标签:
【中文标题】为超过/低于阈值的值制作不同颜色的ggplot2热图【英文标题】:Make ggplot2 heatmap with different colors for values over/under thresholds 【发布时间】:2021-09-10 07:12:27 【问题描述】:我想制作一个表格,其中根据单元格的值突出显示单元格,在这种情况下为 Perc_Diff。我希望 -100 和 +100 之间的值遵循 scale_fill_gradient2 模式(请参见下面的代码),但值 = 100 为黄色。这是数据(其中一些已更改以说明我的问题)。
plot30 <- structure(list(Station = structure(c(20L, 20L, 20L, 20L, 20L,
20L, 15L, 15L, 15L, 15L, 15L, 15L, 25L, 25L, 25L, 25L, 25L, 25L,
6L, 6L, 6L, 6L, 6L, 6L, 36L, 36L, 36L, 36L, 36L, 36L, 13L, 13L,
13L, 13L, 13L, 13L, 18L, 18L, 18L, 18L, 18L, 18L, 45L, 45L, 45L,
45L, 45L, 45L, 29L, 29L, 29L, 29L, 29L, 29L, 7L, 7L, 7L, 7L,
7L, 7L, 39L, 39L, 39L, 39L, 39L, 39L, 33L, 33L, 33L, 33L, 33L,
33L, 24L, 24L, 24L, 24L, 24L, 24L, 41L, 41L, 41L, 41L, 41L, 41L,
22L, 22L, 22L, 22L, 22L, 22L, 28L, 28L, 28L, 28L, 28L, 28L, 32L,
32L, 32L, 32L, 32L, 32L, 23L, 23L, 23L, 23L, 23L, 23L, 3L, 3L,
3L, 3L, 3L, 3L, 31L, 31L, 31L, 31L, 31L, 31L, 34L, 34L, 34L,
34L, 34L, 34L, 8L, 8L, 8L, 8L, 8L, 8L, 27L, 27L, 27L, 27L, 27L,
27L, 37L, 37L, 37L, 37L, 37L, 37L, 5L, 5L, 5L, 5L, 5L, 5L, 19L,
19L, 19L, 19L, 19L, 19L, 44L, 44L, 44L, 44L, 44L, 44L, 17L, 17L,
17L, 17L, 17L, 17L, 43L, 43L, 43L, 43L, 43L, 43L, 40L, 40L, 40L,
40L, 40L, 40L, 9L, 9L, 9L, 9L, 9L, 9L, 4L, 4L, 4L, 4L, 4L, 4L,
30L, 30L, 30L, 30L, 30L, 30L, 38L, 38L, 38L, 38L, 38L, 38L, 12L,
12L, 12L, 12L, 12L, 12L, 35L, 35L, 35L, 35L, 35L, 35L, 14L, 14L,
14L, 14L, 14L, 14L, 10L, 10L, 10L, 10L, 10L, 10L, 11L, 11L, 11L,
11L, 11L, 11L, 42L, 42L, 42L, 42L, 42L, 42L, 26L, 26L, 26L, 26L,
26L, 26L, 21L, 21L, 21L, 21L, 21L, 21L, 16L, 16L, 16L, 16L, 16L,
16L, 2L, 2L, 2L, 2L, 2L, 2L, 1L, 1L, 1L, 1L, 1L, 1L), .Label = c("WTES2",
"WRIS2", "WEBS2", "VGAS2", "UNIS2", "TIMS2", "STMS2", "SHSS2",
"SFWS2", "SFSS2", "RDFS2", "RBMS2", "PSTS2", "PRFS2", "ORRS2",
"OCMS2", "OAKS2", "NISS2", "MHTS2", "MCTS2", "MCMS2", "MATS2",
"LMNS2", "LLAS2", "JWLS2", "HMLS2", "HIHS2", "GTBS2", "GOTS2",
"FLNS2", "FLKS2", "EGBS2", "EDTS2", "CTWS2", "CTNS2", "CPTS2",
"CLRS2", "BWLS2", "BTNS2", "BTCS2", "BSNS2", "BKMS2", "BFMS2",
"AURS2", "ATRS2"), class = "factor"), Comp_Data = structure(c(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,
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, 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, 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, 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, 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, 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, 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, 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), .Label = c("Total_QPE",
"Stn_PP", "Diff_in", "Perc_Diff", "Frz_Days", "Miss_Days"), class = "factor"),
stuff = c(3.831, 3.07, -0.761, -24.79, 0, 0, 3.075, 1.81,
-1.265, -69.89, 0, 5, 2.941, 2.2, -0.741, -33.68, 0, 0, 2.907,
2.33, -0.577, -24.76, 0, 0, 2.319, 0.36, -1.959, -100, 0,
19, 2.241, 1.24, -1.001, -80.73, 0, 0, 1.926, 1.23, -0.696,
-56.59, 0, 0, 1.91, 1.07, -0.84, -78.5, 0, 0, 1.877, 1.47,
-0.407, -27.69, 0, 0, 1.867, 1.35, -0.517, -38.3, 0, 0, 1.773,
1.22, -0.553, -45.33, 0, 0, 1.773, 1.43, -0.343, -23.99,
0, 0, 1.717, 1.35, -0.367, -27.19, 0, 0, 1.659, 0.71, -0.949,
-100, 0, 0, 1.481, 0.5, -0.981, -100, 0, 0, 1.401, 0.23,
-1.171, -100, 0, 2, 1.377, 0.08, -1.297, -100, 0, 0, 1.296,
0.97, -0.326, -33.61, 0, 0, 1.263, 0.8, -0.463, -57.88, 0,
0, 1.255, 1.06, -0.195, -18.4, 0, 0, 1.212, 0.63, -0.582,
-92.38, 0, 0, 1.203, 0.71, -0.493, -69.44, 0, 0, 1.189, 0.01,
-1.179, -100, 0, 0, 1.18, 0.53, -0.65, -100, 0, 0, 1.144,
0.42, -0.724, -100, 0, 0, 1.105, 0.65, -0.455, -70, 0, 0,
1.062, 0.62, -0.442, -71.29, 0, 0, 1.043, 0.45, -0.593, -100,
0, 0, 1.032, 0.68, -0.352, -51.76, 0, 13, 0.99, 0.66, -0.33,
-50, 0, 0, 0.985, 0.67, -0.315, -47.01, 0, 0, 0.972, 0.7,
-0.272, -38.86, 0, 0, 0.946, 0.5, -0.446, -89.2, 0, 0, 0.916,
0.63, -0.286, -45.4, 0, 0, 0.87, 0.55, -0.32, -58.18, 0,
5, 0.854, 0.6, -0.254, -42.33, 0, 0, 0.825, 0.56, -0.265,
-47.32, 0, 0, 0.816, 0.74, -0.076, -10.27, 0, 0, 0.808, 0.24,
-0.568, -100, 0, 6, 0.765, 0.577, -0.188, -32.58, 0, 4, 0.723,
0.79, 0.067, 8.48, 0, 0, 0.713, 0.66, -0.053, -8.03, 0, 0,
0.647, 0.79, 0.143, 18.1, 0, 0, 0.452, 0.4, -0.052, -13,
0, 0, 0.328, 0.5, 0.172, 34.4, 0, 0), Perc_Diff = c(0, 0,
0, -24.79, 0, 0, 0, 0, 0, -69.89, 0, 0, 0, 0, 0, -33.68,
0, 0, 0, 0, 0, -24.76, 0, 0, 0, 0, 0, -100, 0, 0, 0, 0, 0,
-80.73, 0, 0, 0, 0, 0, -56.59, 0, 0, 0, 0, 0, -78.5, 0, 0,
0, 0, 0, -27.69, 0, 0, 0, 0, 0, -38.3, 0, 0, 0, 0, 0, -45.33,
0, 0, 0, 0, 0, -23.99, 0, 0, 0, 0, 0, -27.19, 0, 0, 0, 0,
0, -100, 0, 0, 0, 0, 0, -100, 0, 0, 0, 0, 0, -100, 0, 0,
0, 0, 0, -100, 0, 0, 0, 0, 0, -33.61, 0, 0, 0, 0, 0, -57.88,
0, 0, 0, 0, 0, -18.4, 0, 0, 0, 0, 0, -92.38, 0, 0, 0, 0,
0, -69.44, 0, 0, 0, 0, 0, -100, 0, 0, 0, 0, 0, -100, 0, 0,
0, 0, 0, -100, 0, 0, 0, 0, 0, -70, 0, 0, 0, 0, 0, -71.29,
0, 0, 0, 0, 0, -100, 0, 0, 0, 0, 0, -51.76, 0, 0, 0, 0, 0,
-50, 0, 0, 0, 0, 0, 100, 0, 0, 0, 0, 0, -38.86, 0, 0,
0, 0, 0, -89.2, 0, 0, 0, 0, 0, -45.4, 0, 0, 0, 0, 0, -58.18,
0, 0, 0, 0, 0, -42.33, 0, 0, 0, 0, 0, 100, 0, 0, 0, 0,
0, -10.27, 0, 0, 0, 0, 0, -100, 0, 0, 0, 0, 0, -32.58, 0,
0, 0, 0, 0, 8.48, 0, 0, 0, 0, 0, -8.03, 0, 0, 0, 0, 0, 18.1,
0, 0, 0, 0, 0, -13, 0, 0, 0, 0, 0, 34.4, 0, 0)), row.names = c(NA,
-270L), class = c("tbl_df", "tbl", "data.frame"))
这是我制作绘图的工作代码,但没有高于或低于 100 的值特别着色:
library(ggplot2)
ggplot(plot30, aes(Comp_Data, Station)) + geom_tile(aes(fill = Perc_Diff),color='black') + geom_text(aes(label = stuff)) +
scale_fill_gradient2(low = "green", mid = 'white', high = "red",limits=c(min(plot30$Perc_Diff,na.rm=T), max(plot30$Perc_Diff,na.rm=T))) +
ggtitle(paste('30 Day Precipitation Comparison (Inches) for',date_30,'to',date_1,'\nCell Values Represent Differences (SD Mesonet minus QPE; Inches)')) +
theme(legend.key.height = unit(3, "cm")) +
theme(axis.title = element_blank()) + theme(plot.title = element_text(hjust = 0.5)) + theme(panel.background = element_blank()) +
theme(axis.ticks = element_blank()) + theme(axis.text.y = element_text(margin = margin(r = 0))) + theme(legend.title = element_blank()) +
theme(legend.text = element_text(colour="black", size = 14, face = "bold")) +
scale_y_discrete(labels = parse(text = levels(plot30$Station))) +
theme(axis.text = element_text(size = 12, colour = "black", face='bold'))
我曾尝试将 ifelse 语句放在这样的填充语句中(如其他几个问题和在线资源中所见),但它不适用于我的编码。
geom_tile(aes(fill = if (Perc_Diff >= 100) 'yellow' else if (Perc_Diff) <= -100 'blue' else 'Perc_Diff')), color = 'black')
我需要在此处切换到手动秤才能使其正常工作吗?如果可能的话,我真的很想避免这种情况,将连续比例保持在 -100 到 +100 之间。任何帮助都会很棒。谢谢。
【问题讨论】:
【参考方案1】:png(filename = "E:\\Precip_QC_Folder\\New_Output\\30_day_pp.png",height = 3000, width = 2250, res = 250)
ggplot(plot30) +
geom_tile(data = plot30 %>% filter(Perc_Diff > -100 & Perc_Diff < 100),
aes(x = Comp_Data, y = Station, fill = Perc_Diff), color='black') +
geom_tile(data = plot30 %>% filter(Perc_Diff <= -100),
aes(x = Comp_Data, y = Station), fill = 'lightblue', color= 'black') +
geom_tile(data = plot30 %>% filter(Perc_Diff >= 100),
aes(x = Comp_Data, y = Station), fill = 'yellow', color= 'black') +
geom_text(aes(x = Comp_Data, y = Station, label = stuff)) +
scale_fill_gradient2(low = "lightgreen", mid = 'white', high = "orange",limits=c(min(plot30$Perc_Diff,na.rm=T), max(plot30$Perc_Diff,na.rm=T))) +
ggtitle(paste('30 Day Precipitation Comparison (Inches) for',date_30,'to',date_1,'\nCell Values Represent Differences (SD Mesonet minus QPE; Inches)')) +
theme(legend.key.height = unit(3, "cm")) +
theme(axis.title = element_blank()) + theme(plot.title = element_text(hjust = 0.5)) + theme(panel.background = element_blank()) +
theme(axis.ticks = element_blank()) + theme(axis.text.y = element_text(margin = margin(r = 0))) + theme(legend.title = element_blank()) +
theme(legend.text = element_text(colour="black", size = 14, face = "bold")) +
scale_y_discrete(labels = parse(text = levels(plot30$Station))) +
theme(axis.text = element_text(size = 12, colour = "black", face='bold'))
dev.off()
【讨论】:
【参考方案2】:这种方法是一种潜在的解决方案,但由于颜色(Perc Diff)和标签(东西)有时匹配,有时不匹配,因此该图看起来有点“奇怪”。
无论如何,这就是我如何将数据集分成 3 个“组”以进行绘图( -100 & = 100):
ggplot(plot30) +
geom_tile(data = plot30 %>% filter(Perc_Diff < 100 & Perc_Diff > -100),
aes(x = Comp_Data,
y = factor(Station, levels = unique(Station)),
fill = Perc_Diff), color='black') +
geom_tile(data = plot30 %>% filter(Perc_Diff <= -100),
aes(x = Comp_Data,
y = factor(Station, levels = unique(Station))),
fill = "blue", color='black') +
geom_tile(data = plot30 %>% filter(Perc_Diff >= 100),
aes(x = Comp_Data,
y = factor(Station, levels = unique(Station))),
fill = "yellow", color='black') +
geom_text(aes(x = Comp_Data,
y = factor(Station, levels = unique(Station)),
label = stuff)) +
scale_fill_gradient2(low = "green", mid = 'white', high = "red",
limits=c(min(plot30$Perc_Diff,na.rm=T),
max(plot30$Perc_Diff,na.rm=T))) +
ggtitle(paste('30 Day Precipitation Comparison (Inches) for', "date_30",'to',"date_1",'\nCell Values Represent Differences (SD Mesonet minus QPE; Inches)')) +
theme(legend.key.height = unit(3, "cm")) +
theme(axis.title = element_blank()) +
theme(plot.title = element_text(hjust = 0.5)) +
theme(panel.background = element_blank()) +
theme(axis.ticks = element_blank()) +
theme(axis.text.y = element_text(margin = margin(r = 0))) +
theme(legend.title = element_blank()) +
theme(legend.text = element_text(colour="black", size = 14, face = "bold")) +
theme(axis.text = element_text(size = 12, colour = "black", face='bold'))
【讨论】:
谢谢,这行得通。我将回答我的问题以显示最终解决方案。我仍然遇到的一个问题是数据与标签相反(y 轴上的数据由于某种原因而反转)。您是否还知道如何仅将黄色和蓝色单元格中的值加粗?再次感谢您。 如果您将 Station 变成一个因素(正如我在回答中所做的那样),您可以控制 y 轴的顺序。参见例如***.com/questions/34716245/… 了解更多详情。抱歉,我不知道如何将某些值加粗。以上是关于为超过/低于阈值的值制作不同颜色的ggplot2热图的主要内容,如果未能解决你的问题,请参考以下文章
Android - 如何记录加速度计在很长一段时间内超过+低于阈值的时间量
R语言ggplot2可视化热力图(heatmap)自定义配置图例标签为百分比进行热力图颜色渐变显示(legend to display percentage sign)
R语言ggplot2可视化热力图(heatmap)自定义配置图例标签为百分比进行热力图颜色渐变显示(legend to display percentage sign)