专栏名称: EasyCharts
EasyCharts,易图表,我们将定期推送各种数据可视化与分析教程,包括Excel(Power BI)、Origin、Sigmaplot、GraphPad、R、Python、Matlab、Tableau、D3.js等。
目录
相关文章推荐
商务河北  ·  经开区“美•强•优”三重奏 ·  2 天前  
云南省人民政府  ·  在线访谈丨我省如何构建国土空间新格局?省自然 ... ·  3 天前  
云南省人民政府  ·  在线访谈丨我省如何构建国土空间新格局?省自然 ... ·  3 天前  
51好读  ›  专栏  ›  EasyCharts

写个geom_rectriangle图层画对角线热图

EasyCharts  · 公众号  · 前端  · 2019-12-29 00:00

正文


上周有一篇果子的原创“用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 里,也是极好的。







请到「今天看啥」查看全文