上周有一篇果子的原创“用ggplot2来画带有对角线的热图”。图是这样的:
这是个比较另类的热图,先不管表达的信息会不会给人错乱的感觉,这图画出来确实很有难度。图要表达的意思就是要把不同的信息以热图形式放在一张图里,看图注大概都能懂。
果子是我很欣赏和钦佩的人。
我并不认识他,只是关注过他的公众号,跟他学习了不少。但从的公号的内容里大概能得到他应该是个很棒的临床医生,可能在四川或重庆工作。发现他不久前也关注了我的号~
看到他的画法后我时不时在想,直接写个图层来解决会省不少事。谁都知道写个图层包装一下用起来当然简单,但是图层不好写啊……
想到前段时间厚蕴老师写过一个基于ggplot2做相关性可视化的包
ggcor
,画出的图精致又美观。这个包里新写了不少图层,比如
geom_star
,
geom_square
,和
geom_circle2
等等。
我选个
geom_star
展示一下:
先造个数据
library(tidyverse)
data %
as.data.frame()%>%
rownames_to_column("A") %>%
gather("B","value1",-A)
画图
ggplot(data, aes(A, B, fill = value))+
scale_fill_viridis_c()+
ggcor::geom_star()+
coord_fixed()
借鉴上图的思路,我如果写个直角三角形的图层
geom_rectriangle
,再设置一下直角朝上
upper
,还是朝下
lower
,就可以实现带有对角线的热图了。找到
ggcor
的源码,说干就干!
造图层
library(vctrs)
library(grid)
geom_rectriangle
stat = "identity", position = "identity",
...,
linejoin = "mitre",
na.rm = FALSE,
show.legend = NA,
inherit.aes = TRUE) {
layer(
data = data,
mapping = mapping,
stat = stat,
geom = GeomRectriangle,
position = position,
show.legend = show.legend,
inherit.aes = inherit.aes,
params = list(
linejoin = linejoin,
na.rm = na.rm,
...
)
)
}
GeomRectriangle
"GeomRectriangle", Geom,
default_aes = aes(r = 1, colour = "grey35", fill = NA, size = 0.25, linetype = 1,
alpha = NA,type = "upper"),
required_aes = c("x", "y"),
draw_panel = function(self, data, panel_params, coord, linejoin = "mitre",type = "upper") {
aesthetics
polys
rectriangle
aes
GeomPolygon$draw_panel(cbind(rectriangle, aes), panel_params, coord)
})
ggplot2:::ggname("geom_rectriangle", do.call("grobTree", polys))
},
draw_key = draw_key_polygon
)
point_to_rectriangle
r
#r0 = 0.5
xmin
xmax
ymin
ymax
if(type == "upper"){
df = new_data_frame(list(
y = c(ymax, ymax, ymin, ymax),
x = c(xmin, xmax, xmin, xmin)
))
}else if(type == "lower"){
df = new_data_frame(list(
y = c(ymax, ymin, ymin, ymax),
x = c(xmax, xmax, xmin, xmax)
))
}
df
}
造个数据,为了使两列的数据有不一样的scale,我故意弄了个
value1
和
value2
。然后画图:
data %
as.data.frame()%>%
rownames_to_column("A") %>%
gather("B","value1",-A) %>%
mutate(value2 = -log2(sample(value1, length(value1))+1))
#install.packages("ggnewscale")
ggplot()+
geom_rectriangle(data = data, aes(A, B, fill = value1),type = "upper", r = 1)+
scale_fill_gradient(high = "red", low = "white")+
ggnewscale::new_scale_fill()+
geom_rectriangle(data = data, aes(A, B, fill = value2),type = "lower", r = 1)+
scale_fill_gradient(high = "white", low = "blue")+
labs(x = "", y = "")
图是这样的:
对角线热图
还可以再调的好看些,感兴趣可以试试。
对了,上面的参数里有个
r
,我把它默认成了1,可以改成
r = 0.5
试试。
又一个对角线热图
弄个包来的话会更便于使用,我暂时就不去搞个包了。不知道厚蕴老师能不能看到,希望他能采纳一下,把这个加到他的
ggcor
里,也是极好的。