局部放大图(zoom)的简单实现,以及如何实现眼到手到。
2019-06-19 本文已影响36人
9d760c7ce737
ggforce
浑身都是宝,我们讲过贝塞尔曲线,讲过桑基图。
今天我们来看一下,如何快速地变大。
这是数据格式
如果我们快速地画个散点图,是这个样子的。
library(ggplot2)
ggplot(dat2,aes(ILC,IDC )) +
geom_point(aes(size=-log10(pvalue),color=group))+
scale_color_manual(values=c("red","navy","forestgreen","black","grey"))
我们发现,大部分的点都在某个局部,导致图很不好看,这时候我们可以用
ggforce
中的facet_zoom
图层把那个区域放大。只要在原来的数据上增加一列,指示要放大的区域即可。
library(ggplot2)
library(ggforce)
dat2$zoom <- ifelse(dat2$ILC <= 15 & dat2$IDC <= 15,TRUE,FALSE)
ggplot(dat2,aes(ILC,IDC )) +
geom_point(aes(size=-log10(pvalue),color=group))+
scale_color_manual(values=c("red","navy","forestgreen","black","grey"))+
facet_zoom(xy = zoom == TRUE,xlim = c(1,15),ylim = c(1,15),zoom.size=1)
这时候可以简单修饰一下
library(ggplot2)
library(ggforce)
dat2$zoom <- ifelse(dat2$ILC <= 15 & dat2$IDC <= 15,TRUE,FALSE)
ggplot(dat2,aes(ILC,IDC )) +
geom_point(aes(size=-log10(pvalue),color=group))+
scale_color_manual(values=c("red","navy","forestgreen","black","grey"))+
facet_zoom(xy = zoom == TRUE,xlim = c(1,15),ylim = c(1,15),zoom.size=1)+
geom_text_repel(data=subset(dat2,(ILC > 6 | IDC > 6) & pvalue < 0.001), aes(label=Gene),col="black")+
theme_bw()+
theme(panel.grid.major = element_blank(),
panel.grid.minor = element_blank(),
axis.line = element_line(colour = "black"))+
theme(zoom = element_rect(fill = 'grey75', colour = NA), validate = FALSE)
这个图层用起来很方便,我觉得最好的数据应该是地图数据,用这个方法局部放大某个区域,更好地展示图片。
就目前这个数据,如果没有这个图层应该怎么做呢,最简单的方法就是,画一个大图,再画一个小图,然后把他们拼接在一起。因为是单独画的,所以可以做很多修饰。
p1 <- ggplot(dat2,aes(ILC,IDC )) +
## 局部方框,要先画,就可以作为底层
geom_rect(aes(xmin=0, xmax=15, ymin=0, ymax=15), fill="orange",color="black",alpha=0.006)+
geom_point(aes(size=-log10(pvalue),color=group))+
scale_color_manual(values=c("red","navy","forestgreen","black","grey"))+
geom_text_repel(data=subset(dat2,(ILC > 15 | IDC > 15) & pvalue < 0.001), aes(label=Gene),col="black")+
theme_bw()+
ylim(0,ceiling(max(dat2$ILC)))+
## 对角线
geom_abline(intercept =0, slope = 1, linetype="dashed", color = "grey60",size=1)+
## 纵坐标放在右边,一定要limits限定y轴的长度
scale_y_continuous(position = "right",limits =c(0,ceiling(max(dat2$ILC))))+
theme(panel.grid.major = element_blank(),
panel.grid.minor = element_blank(),
axis.line = element_line(colour = "black"),
axis.title.y.right = element_text(angle = 90))+
## 调整x轴和y轴的坐标
labs(x="ILC (% altered samples)",y="IDC (% altered samples)")+
## legend放在底部
theme(legend.position="bottom")+
labs(size="Significance level [-log 10(q)]")
p1 + theme(legend.position="none")
## 去掉一个legend,留下size
p2 <- p1+ guides(color = FALSE)
## 去掉size留下group
p3 <- p1+ guides(size = FALSE)+labs(color=NULL)
## 画zoom 局部图
p4 <- ggplot(data=dat2,aes(ILC,IDC )) +
geom_point(aes(size=-log10(pvalue),color=group))+
scale_color_manual(values=c("red","navy","forestgreen","black","grey"))+
geom_text_repel(data=subset(dat2,(ILC > 6 | IDC > 6) & pvalue < 0.001), aes(label=Gene),col="black")+
geom_abline(intercept =0, slope = 1, linetype="dashed", color = "grey60",size=1)+
theme_bw()+
xlim(0,15)+
ylim(0,15)+
theme(panel.background = element_rect(fill = alpha('orange',0.2),
colour = "orange"),
panel.grid.major = element_blank(),
panel.grid.minor = element_blank(),
axis.line = element_line(colour = "black"))+
labs(x="ILC (% altered samples)",y="IDC (% altered samples)")+
theme(legend.position="none")
## 画出局部图
p11 <- cowplot::plot_grid(p4,ggpubr::get_legend(p3),ncol = 1,rel_heights = c(1, .1))
## 画出整体图
p22 <- cowplot::plot_grid(p1 + theme(legend.position="none"),ggpubr::get_legend(p2),ncol = 1,rel_heights = c(1, .1))
## 拼接
cowplot::plot_grid(p11,p22,nrow = 1)
这样看起来就很不错了,这个构思和配色方案来自于海涛,他用base plot实现了这个功能,并成为了小丫画图的第77号作品,如果有需求可以前往购买。
随着对ggplot2的熟悉,现在看到别人的图片脑子里面基本能转换成ggplot2的画法,至少说心里不会怕,但是要达到眼到手到的境界,还需要一段时间的练习,ggplot2的知识太过庞杂,真希望出现一本超大参考书,让我对全局有个了解。
等自己的技能储备够了,我就来尝试一下写图层,向Y叔看齐。
好了,我是果子,明天见。