单细胞Marker表达气泡图
GAL-0030
对细胞群与基因汇总平均表达和表达阳性细胞比例。
图与代码

code/R/main.R
suppressPackageStartupMessages(library(ggplot2))
dir.create("outputs", showWarnings=FALSE)
d <- read.csv("data/input.csv", check.names=FALSE)
stopifnot(all(d$expression>=0),!anyDuplicated(d[c("cell","gene")]))
means <- aggregate(expression~group+gene,d,mean);frac <- aggregate(expression~group+gene,d,function(x) mean(x>0));names(frac)[3]<-"fraction";tab<-merge(means,frac,by=c("group","gene"))
stats <- data.frame(key=c(paste0("mean_",tab$group,"_",tab$gene),paste0("fraction_",tab$group,"_",tab$gene)),value=c(tab$expression,tab$fraction))
p <- ggplot(tab,aes(gene,group,size=fraction,colour=expression))+geom_point()+scale_size_area(max_size=10,limits=c(0,1))+scale_colour_gradient(low="#dcecf6",high="#135ba0")+theme_classic()+labs(x="Marker",y="Cell group",size="Fraction > 0",colour="Mean expression",title="Marker expression by cell group")
stats <- stats[order(stats$key), ]
write.csv(stats, "outputs/stats_r.csv", row.names=FALSE)
nums <- lapply(seq_len(nrow(stats)), function(i) list(id=stats$key[i], value=stats$value[i], display=sprintf("%.6f", stats$value[i]), source=list(type="computed",locator="code/R/main.R")))
jsonlite::write_json(list(schema="zzy-media-studio/numbers/v1",asset=basename(normalizePath(".")),numbers=nums),"outputs/numbers.json",auto_unbox=TRUE,pretty=TRUE,digits=16)
ggsave("outputs/figure_r.png", p, width=7,height=4.8,dpi=120,bg="white")
code/py/main.py
from pathlib import Path
import numpy as np
import pandas as pd
import matplotlib.pyplot as plt
import scienceplots
plt.style.use(["science", "no-latex"])
Path("outputs").mkdir(exist_ok=True)
d=pd.read_csv("data/input.csv")
fig,ax=plt.subplots(figsize=(7,4.8))
assert (d.expression>=0).all() and not d.duplicated(["cell","gene"]).any()
tab=d.groupby(["group","gene"],sort=True).expression.agg(mean="mean",fraction=lambda x:(x>0).mean()).reset_index()
groups=sorted(d.group.unique());genes=sorted(d.gene.unique());x=[genes.index(v) for v in tab.gene];y=[groups.index(v) for v in tab.group]
img=ax.scatter(x,y,s=300*tab.fraction,c=tab["mean"],cmap="Blues",vmin=0);fig.colorbar(img,ax=ax,label="Mean expression")
for v in [.25,.5,1.]: ax.scatter([],[],s=300*v,color="#176597",label=f"{v:.0%}")
ax.legend(title="Fraction > 0",loc="upper left",bbox_to_anchor=(1.25,1));ax.set_xticks(range(len(genes)),genes);ax.set_yticks(range(len(groups)),groups)
stats=[*( (f"mean_{r.group}_{r.gene}",r.mean) for r in tab.itertuples()),*((f"fraction_{r.group}_{r.gene}",r.fraction) for r in tab.itertuples())]
ax.set(xlabel="Marker",ylabel="Cell group",title="Marker expression by cell group")
pd.DataFrame(stats,columns=["key","value"]).sort_values("key").to_csv("outputs/stats_py.csv",index=False)
fig.tight_layout()
fig.savefig("outputs/figure_py.png",dpi=120,facecolor="white")
plt.close(fig)什么时候用
- 比较各细胞群中标记基因的平均表达及表达细胞占比
常见误用
- 阳性定义为输入值大于零;均值包括零表达细胞
- 点面积表示表达比例;颜色为未按基因缩放的平均表达
数据与下载
数据:固定随机种子的原创模拟数据(原创模拟数据 CC0-1.0)。共享CSV为直接模拟的非负表达值,不对应具体归一化流程,无真实测序样本
下载包 sha256:e4fa184a625c9954a20e4b6f22c2e0bfd203823c7c62b9c97b0641d2df4163ab