生信喵 发表于 2025-11-20 21:05:38

用base plot 画出Zoom的效果

<h1>背景</h1>
<p>用base plot画出C图这种zoom in效果的图。</p>
<p><img src="https://tcapi.voiceclouds.cn:8444/uploads/2025/11/20/mi7fxas545izfnwqfyu.png" alt="" /></p>
<p>出自PMID: 26451490文章</p>
<h1>应用场景</h1>
<p>有时会遇到这样的问题:点的分布很不均匀,堆在一起的点很难标label。</p>
<p>解决办法:画整体的同时画局部,就能看清堆在一起的点了,写label也很清晰。</p>
<p>示例图用于展示多个基因在两组中各变异类型所占的百分比,用颜色表示变异类型,泡泡大小表示pvalue,泡泡所在的位置偏左上说明在IDC中占比高于ILC,反之亦然。该图不仅限于基因。</p>
<h1>环境设置</h1>
<pre><code class="language-{r}">Sys.setenv(LANGUAGE = &quot;en&quot;) #显示英文报错信息
options(stringsAsFactors = FALSE) #禁止chr转成factor
</code></pre>
<h1>输入文件</h1>
<p>easy_input.csv,提供分组、个数及总数(用于计算百分比)、pvalue:</p>
<ul>
<li>第一列是基因名;</li>
<li>第二列是分组;</li>
<li>第3-4、5-6列分别是在ILC(横坐标)和IDC(纵坐标)里的数量和总数,后面会用这两列计算百分比;</li>
<li>最后一列是pvalue。</li>
</ul>
<p>示例数据整理自例文的Table 1. Recurrently Mutated Genes in Breast Cancer,这里只用了mutation,没加CNV,因此泡泡的位置跟原图有出入。</p>
<pre><code class="language-{r}">dat2 &lt;- read.csv(&quot;easy_input.csv&quot;)
head(dat2)
</code></pre>
<h1>把各列数据整理成画图所需的格式</h1>
<pre><code class="language-{r}">### 用3-6列计算百分比 ###
ILC &lt;- (dat2$n_ILC/dat2$total_ILC)*100
names(ILC) &lt;- dat2$Gene
IDC &lt;- (dat2$n_IDC/dat2$total_IDC)*100
names(IDC) &lt;- dat2$Gene

### group列 ###
# 给每个group的泡泡一种颜色
# 先自定义足够多的颜色
mycol &lt;- c(&quot;red&quot;,&quot;navy&quot;,&quot;forestgreen&quot;,&quot;black&quot;,&quot;#FB9A99&quot;,&quot;#33A02C&quot;,&quot;#E31A1C&quot;,&quot;#B15928&quot;,&quot;#6A3D9A&quot;,&quot;#CAB2D6&quot;,&quot;#A6CEE3&quot;,&quot;#1F78B4&quot;,&quot;#FDBF6F&quot;,&quot;#999999&quot;,&quot;#FF7F00&quot;)
# 不显著的定义为notsig组,画成灰色
dat2$group &lt;- &quot;notsig&quot;
cols.names &lt;- unique(dat2$group)
cols.code &lt;- c(mycol,&quot;grey&quot;)
names(cols.code) &lt;- cols.names

### pvalue列 ###
# pvalue决定泡泡的大小
sizes &lt;- -log10(dat2$pvalue)/5
sizes &lt;- 0
names(sizes) &lt;- dat2$Gene
</code></pre>
<h1>开始画图</h1>
<p>Zoom in的效果,也就是画一个整体,再画一个局部。</p>
<h2>画局部</h2>
<pre><code class="language-{r,">par(mfrow=c(1,2),mar = par()$mar + c(3,0,0,3)) #在底部留出图例的地方)
plot(ILC, IDC,
   col = cols.code,
   xlim = c(0,15), ylim=c(0,15), #画局部
   pch = 16, #实心圆点
   ylab = &quot;IDC (% altered samples)&quot;,xlab=&quot;ILC (% altered samples)&quot;,
   cex = sizes)
abline(a = 0, b = 1, col = &quot;gray60&quot;, lwd = 1, lty = 5)
# 泡泡外面画白圈
points(ILC, IDC, pch = 1, col = &quot;white&quot;, cex = sizes)

# 给百分比大于6的泡泡标上文字
# 可以根据你自己的喜好调整
up &lt;- which(IDC &gt; 6)
down &lt;- which(ILC &gt; 6)

par(xpd=TRUE) #让超出画图范围的字也能显示出来
text(ILC, IDC, names(ILC), pos=2) #Values of 1, 2, 3 and 4, respectively indicate positions below, to the left of, above and to the right of the specified coordinates.
text(ILC, IDC, names(ILC), pos=4)

# 画黄色背景
## Add an alpha value to a colour
add.alpha &lt;- function(col, alpha=1){
if(missing(col))
    stop(&quot;Please provide a vector of colours.&quot;)
apply(sapply(col, col2rgb)/255, 2,
      function(x)
          rgb(x, x, x, alpha=alpha))
}
gray.alpha &lt;- add.alpha(&quot;orange&quot;, alpha=0.1)
rect(par(&quot;usr&quot;), par(&quot;usr&quot;), par(&quot;usr&quot;), par(&quot;usr&quot;), col = gray.alpha)

# 添加pathway颜色的图例
legend(&quot;bottom&quot;,
       inset=c(0,-.5), #把图例画到图外
       ncol = 3,
       pch=16, col=cols.code, legend=cols.names, bty=&quot;n&quot;)


### 画整体 ###
#par(mar = par()$mar + c(0,0,0,3)) #在右侧留出写title的地方
plot(ILC, IDC,
   col = cols.code,
   xlim=c(0,70),ylim=c(0,70),
   ylab=&quot;&quot;, xlab=&quot;ILC (% altered samples)&quot;,
   yaxt='n', #先不画y轴
   pch=16,
   cex=sizes)
# 泡泡外面画白圈
points(ILC, IDC, pch=1, col = &quot;white&quot;, cex=sizes)

axis(side = 4) #画右侧y轴
title(ylab=&quot;IDC (% altered samples)&quot;,
      mgp=c(-20,1,0)) #根据具体图的大小调整,这里取-25,让title位于右侧

# 给百分比大于15的泡泡标上文字
w &lt;- which(ILC &gt; 15 | IDC &gt; 15) # ILC或IDC&gt;15
text(ILC, IDC, names(ILC), pos=3) #Values of 1, 2, 3 and 4, respectively indicate positions below, to the left of, above and to the right of the specified coordinates.

# 添加size的图例
u &lt;- par(&quot;usr&quot;)
f &lt;- c(1,2.5,5,10,20)
s &lt;- sqrt(f/3)
legend(&quot;bottom&quot;,
       inset=c(0,-.5), #把图例画到图外
       legend=rep(&quot;&quot;, length(f)),
       title = &quot;Significance level [-log10(q)]&quot;,
       pch=1, pt.cex=s, bty='n',
       horiz = TRUE, #横向排列
       col=&quot;#88888888&quot;)

par(xpd = F) #默认就是F,前面为了写label改成TRUE了。画abline前一定改为FALSE,否则对角线的虚线会超出plot region
abline(a = 0, b = 1, col = &quot;gray60&quot;, lwd = 1, lty=2)

# 给局部区域画黄色背景
# 此处的4.6是由70/15得到的
rect(par(&quot;usr&quot;)/4.6, par(&quot;usr&quot;)/4.6, par(&quot;usr&quot;)/4.6, par(&quot;usr&quot;)/4.6, col = gray.alpha, border=TRUE)

recordedplot1 &lt;- recordPlot() # record the previous plot

pdf(&quot;baseZoom.pdf&quot;,10,5.5)
recordedplot1
dev.off()
</code></pre>
<p><img src="https://tcapi.voiceclouds.cn:8444/uploads/2025/11/20/mi7g1977abxvxty85wi.png" alt="" /></p>

生信喵 发表于 2025-11-20 21:07:57

<p>文中所用数据可以关注公众号“生信喵实验柴”<br />
<img src="https://tcapi.voiceclouds.cn:8444/uploads/2025/09/07/mf9nu72s90ofyseu9hl.png" alt="" /><br />
发送关键词“20250506”获取</p>
页: [1]
查看完整版本: 用base plot 画出Zoom的效果