使用 Matplotlib 在带有图例的热图中显示不同大小的圆圈
Showing different size circles in heatmap with legend using Matplotlib
我问的问题源于这个原始 post
我正在尝试使用我的数据框复制它,但是,我的圆圈与绘图不对齐。其次,我还想创建一个图例,表示相对于圆圈大小的值。
x= {'ID': {0: 'GO:0002474',
1: 'GO:0052548',
2: 'GO:0002483',
3: 'GO:0043062',
4: 'GO:0060333'},
'TERM': {0: 'antigen processing and presentation of peptide antigen via MHC class I',
1: 'regulation of endopeptidase activity',
2: 'antigen processing and presentation of endogenous peptide antigen',
3: 'extracellular structure organization',
4: 'interferon-gamma-mediated signaling pathway'},
'Count': {0: 11, 1: 17, 2: 5, 3: 15, 4: 6},
'Ratio': {0: 18.64, 1: 14.53, 2: 8.47, 3: 12.82, 4: 10.17},
'pvalue': {0: -15.83, 1: -11.39, 2: -9.67, 3: -9.05, 4: -7.41},
'qvalue': {0: -11.63, 1: -7.49, 2: -6.52, 3: -5.63, 4: -4.55},
'Label': {0: 'NODAL', 1: 'NODAL', 2: 'NODAL', 3: 'SHARED', 4: 'NODAL'}}
A2780_GOBP= pd.DataFrame(x)
尝试的代码:
ylabels = A2780_GOBP["TERM"]
xlabels = ["GFP","SHARED","NODAL"]
x, y = np.meshgrid(np.arange(len(xlabels)), np.arange(len(ylabels)))
s = A2780_GOBP["Count"].values
c = A2780_GOBP["pvalue"].values
fig, ax = plt.subplots()
R = s/s.max()/2
circles = [plt.Circle((j,i), radius=r) for r, j, i in zip(R.flat, x.flat, y.flat)]
col = PatchCollection(circles, array=c.flatten(), cmap=cmap)
ax.add_collection(col)
ax.set(xticks=np.arange(3), yticks=np.arange(10),
xticklabels=xlabels, yticklabels=ylabels)
ax.set_xticks(np.arange(3+1)-0.5, minor=True)
ax.set_yticks(np.arange(10+1)-0.5, minor=True)
ax.grid(which='minor')
fig.colorbar(col)
plt.show()
如有任何帮助,我们将不胜感激!
这里的问题是复制的代码填充了所有字段,而您的代码不一定在每个框中都有一个条目。我们必须向上看,每个圆圈都必须绘制:
import numpy as np
import matplotlib.pyplot as plt
from matplotlib.collections import PatchCollection
import pandas as pd
x= {'ID': {0: 'GO:0002474',
1: 'GO:0052548',
2: 'GO:0002483',
3: 'GO:0043062',
4: 'GO:0060333'},
'TERM': {0: 'antigen processing and presentation of peptide antigen via MHC class I',
1: 'regulation of endopeptidase activity',
2: 'antigen processing and presentation of endogenous peptide antigen',
3: 'extracellular structure organization',
4: 'interferon-gamma-mediated signaling pathway'},
'Count': {0: 11, 1: 17, 2: 5, 3: 15, 4: 6},
'Ratio': {0: 18.64, 1: 14.53, 2: 8.47, 3: 12.82, 4: 10.17},
'pvalue': {0: -15.83, 1: -11.39, 2: -9.67, 3: -9.05, 4: -7.41},
'qvalue': {0: -11.63, 1: -7.49, 2: -6.52, 3: -5.63, 4: -4.55},
'Label': {0: 'NODAL', 1: 'GFP', 2: 'NODAL', 3: 'SHARED', 4: 'NODAL'}}
A2780_GOBP= pd.DataFrame(x)
cmap = "plasma"
#retrieve unique labels
ylabels = A2780_GOBP["TERM"].unique().tolist()
xlabels = A2780_GOBP["Label"].unique().tolist()
xn = len(xlabels)
yn = len(ylabels)
#retrieve size and color information
s = A2780_GOBP["Count"].values
c = A2780_GOBP["pvalue"].values
#preparation of the figure with its grid
fig, ax = plt.subplots(figsize=(10, 5))
ax.set_xlim(-0.5, xn-0.5)
ax.set_ylim(-0.5, yn-0.5)
ax.set(xticks=np.arange(xn), yticks=np.arange(yn),
xticklabels=xlabels, yticklabels=ylabels)
ax.set_xticks(np.arange(xn)-0.5, minor=True)
ax.set_yticks(np.arange(yn)-0.5, minor=True)
ax.grid(which='minor')
#ensure circles are displayed as circles
ax.set_aspect("equal", "box")
#create circles patches and colorbar
R = s/s.max()/2
circles = [plt.Circle((xlabels.index(A2780_GOBP.loc[i, "Label"]), ylabels.index(A2780_GOBP.loc[i, "TERM"])), radius=r) for i, r in enumerate(R)]
col = PatchCollection(circles, array=c, cmap=cmap)
ax.add_collection(col)
fig.colorbar(col)
plt.show()
示例输出:
该代码不会检查原始数据库的完整性,即每个标签-术语对确实只出现一次。
@Mr. 的改编答案。 T 包含图例生成器
from matplotlib.legend_handler import HandlerPatch
import matplotlib.patches as mpatches
ylabels = A2780_GOBP["TERM"].unique().tolist()
xlabels = A2780_GOBP["Label"].unique().tolist()
xn = len(xlabels)
yn = len(ylabels)
s = A2780_GOBP["Count"].values
c = A2780_GOBP["pvalue"].values
fig, ax = plt.subplots(figsize=(20,10))
ax.set_xlim(-0.5, xn-0.5)
ax.set_ylim(-0.5, yn-0.5)
ax.set(xticks=np.arange(xn), yticks=np.arange(yn), yticklabels=ylabels)
ax.set_xticklabels(xlabels, rotation='vertical')
ax.set_xticks(np.arange(xn)-0.5, minor=True)
ax.set_yticks(np.arange(yn)-0.5, minor=True)
ax.grid(which='minor')
ax.set_aspect("equal", "box")
R = s/s.max()/2
circles = [plt.Circle((xlabels.index(A2780_GOBP.loc[i, "Label"]), ylabels.index(A2780_GOBP.loc[i, "TERM"])), radius=r) for i, r in enumerate(R)]
col = PatchCollection(circles, array=c, cmap=cmap)
sc=ax.add_collection(col)
cbar=fig.colorbar(col).set_label('$-log_{10}(p-value)$', rotation=270, size=16,labelpad=15)
smax=s.max()
smin=s.min()
smid=(smax+smin)/2
texts = ["3","10","17"]
class HandlerEllipse(HandlerPatch):
def create_artists(self, legend, orig_handle,
xdescent, ydescent, width, height, fontsize, trans):
center = 0.5 * width - 0.5 * xdescent, 0.5 * height - 0.5 * ydescent
p = mpatches.Ellipse(xy=center, width=orig_handle.width,
height=orig_handle.height)
self.update_prop(p, orig_handle, legend)
p.set_transform(trans)
return [p]
c = [mpatches.Ellipse((), width=smin, height=smin, color="grey"),
mpatches.Ellipse((), width=smid, height=smid, color="grey"),
mpatches.Ellipse((), width=smax, height=smax, color="grey"),
]
legend = ax.legend(c,texts, handler_map={mpatches.Ellipse: HandlerEllipse()},title="Number of Proteins",bbox_to_anchor=(3.50, 0.82, 1.0, .102),fontsize="large")
plt.setp(legend.get_title(),fontsize='large')
plt.show()
输出:
我问的问题源于这个原始 post
我正在尝试使用我的数据框复制它,但是,我的圆圈与绘图不对齐。其次,我还想创建一个图例,表示相对于圆圈大小的值。
x= {'ID': {0: 'GO:0002474',
1: 'GO:0052548',
2: 'GO:0002483',
3: 'GO:0043062',
4: 'GO:0060333'},
'TERM': {0: 'antigen processing and presentation of peptide antigen via MHC class I',
1: 'regulation of endopeptidase activity',
2: 'antigen processing and presentation of endogenous peptide antigen',
3: 'extracellular structure organization',
4: 'interferon-gamma-mediated signaling pathway'},
'Count': {0: 11, 1: 17, 2: 5, 3: 15, 4: 6},
'Ratio': {0: 18.64, 1: 14.53, 2: 8.47, 3: 12.82, 4: 10.17},
'pvalue': {0: -15.83, 1: -11.39, 2: -9.67, 3: -9.05, 4: -7.41},
'qvalue': {0: -11.63, 1: -7.49, 2: -6.52, 3: -5.63, 4: -4.55},
'Label': {0: 'NODAL', 1: 'NODAL', 2: 'NODAL', 3: 'SHARED', 4: 'NODAL'}}
A2780_GOBP= pd.DataFrame(x)
尝试的代码:
ylabels = A2780_GOBP["TERM"]
xlabels = ["GFP","SHARED","NODAL"]
x, y = np.meshgrid(np.arange(len(xlabels)), np.arange(len(ylabels)))
s = A2780_GOBP["Count"].values
c = A2780_GOBP["pvalue"].values
fig, ax = plt.subplots()
R = s/s.max()/2
circles = [plt.Circle((j,i), radius=r) for r, j, i in zip(R.flat, x.flat, y.flat)]
col = PatchCollection(circles, array=c.flatten(), cmap=cmap)
ax.add_collection(col)
ax.set(xticks=np.arange(3), yticks=np.arange(10),
xticklabels=xlabels, yticklabels=ylabels)
ax.set_xticks(np.arange(3+1)-0.5, minor=True)
ax.set_yticks(np.arange(10+1)-0.5, minor=True)
ax.grid(which='minor')
fig.colorbar(col)
plt.show()
如有任何帮助,我们将不胜感激!
这里的问题是复制的代码填充了所有字段,而您的代码不一定在每个框中都有一个条目。我们必须向上看,每个圆圈都必须绘制:
import numpy as np
import matplotlib.pyplot as plt
from matplotlib.collections import PatchCollection
import pandas as pd
x= {'ID': {0: 'GO:0002474',
1: 'GO:0052548',
2: 'GO:0002483',
3: 'GO:0043062',
4: 'GO:0060333'},
'TERM': {0: 'antigen processing and presentation of peptide antigen via MHC class I',
1: 'regulation of endopeptidase activity',
2: 'antigen processing and presentation of endogenous peptide antigen',
3: 'extracellular structure organization',
4: 'interferon-gamma-mediated signaling pathway'},
'Count': {0: 11, 1: 17, 2: 5, 3: 15, 4: 6},
'Ratio': {0: 18.64, 1: 14.53, 2: 8.47, 3: 12.82, 4: 10.17},
'pvalue': {0: -15.83, 1: -11.39, 2: -9.67, 3: -9.05, 4: -7.41},
'qvalue': {0: -11.63, 1: -7.49, 2: -6.52, 3: -5.63, 4: -4.55},
'Label': {0: 'NODAL', 1: 'GFP', 2: 'NODAL', 3: 'SHARED', 4: 'NODAL'}}
A2780_GOBP= pd.DataFrame(x)
cmap = "plasma"
#retrieve unique labels
ylabels = A2780_GOBP["TERM"].unique().tolist()
xlabels = A2780_GOBP["Label"].unique().tolist()
xn = len(xlabels)
yn = len(ylabels)
#retrieve size and color information
s = A2780_GOBP["Count"].values
c = A2780_GOBP["pvalue"].values
#preparation of the figure with its grid
fig, ax = plt.subplots(figsize=(10, 5))
ax.set_xlim(-0.5, xn-0.5)
ax.set_ylim(-0.5, yn-0.5)
ax.set(xticks=np.arange(xn), yticks=np.arange(yn),
xticklabels=xlabels, yticklabels=ylabels)
ax.set_xticks(np.arange(xn)-0.5, minor=True)
ax.set_yticks(np.arange(yn)-0.5, minor=True)
ax.grid(which='minor')
#ensure circles are displayed as circles
ax.set_aspect("equal", "box")
#create circles patches and colorbar
R = s/s.max()/2
circles = [plt.Circle((xlabels.index(A2780_GOBP.loc[i, "Label"]), ylabels.index(A2780_GOBP.loc[i, "TERM"])), radius=r) for i, r in enumerate(R)]
col = PatchCollection(circles, array=c, cmap=cmap)
ax.add_collection(col)
fig.colorbar(col)
plt.show()
示例输出:
该代码不会检查原始数据库的完整性,即每个标签-术语对确实只出现一次。
@Mr. 的改编答案。 T 包含图例生成器
from matplotlib.legend_handler import HandlerPatch
import matplotlib.patches as mpatches
ylabels = A2780_GOBP["TERM"].unique().tolist()
xlabels = A2780_GOBP["Label"].unique().tolist()
xn = len(xlabels)
yn = len(ylabels)
s = A2780_GOBP["Count"].values
c = A2780_GOBP["pvalue"].values
fig, ax = plt.subplots(figsize=(20,10))
ax.set_xlim(-0.5, xn-0.5)
ax.set_ylim(-0.5, yn-0.5)
ax.set(xticks=np.arange(xn), yticks=np.arange(yn), yticklabels=ylabels)
ax.set_xticklabels(xlabels, rotation='vertical')
ax.set_xticks(np.arange(xn)-0.5, minor=True)
ax.set_yticks(np.arange(yn)-0.5, minor=True)
ax.grid(which='minor')
ax.set_aspect("equal", "box")
R = s/s.max()/2
circles = [plt.Circle((xlabels.index(A2780_GOBP.loc[i, "Label"]), ylabels.index(A2780_GOBP.loc[i, "TERM"])), radius=r) for i, r in enumerate(R)]
col = PatchCollection(circles, array=c, cmap=cmap)
sc=ax.add_collection(col)
cbar=fig.colorbar(col).set_label('$-log_{10}(p-value)$', rotation=270, size=16,labelpad=15)
smax=s.max()
smin=s.min()
smid=(smax+smin)/2
texts = ["3","10","17"]
class HandlerEllipse(HandlerPatch):
def create_artists(self, legend, orig_handle,
xdescent, ydescent, width, height, fontsize, trans):
center = 0.5 * width - 0.5 * xdescent, 0.5 * height - 0.5 * ydescent
p = mpatches.Ellipse(xy=center, width=orig_handle.width,
height=orig_handle.height)
self.update_prop(p, orig_handle, legend)
p.set_transform(trans)
return [p]
c = [mpatches.Ellipse((), width=smin, height=smin, color="grey"),
mpatches.Ellipse((), width=smid, height=smid, color="grey"),
mpatches.Ellipse((), width=smax, height=smax, color="grey"),
]
legend = ax.legend(c,texts, handler_map={mpatches.Ellipse: HandlerEllipse()},title="Number of Proteins",bbox_to_anchor=(3.50, 0.82, 1.0, .102),fontsize="large")
plt.setp(legend.get_title(),fontsize='large')
plt.show()
输出: