我有这个简单的问题:我有两个数据框,一个df_signal带列(行,列,强度),另一个df_det带(行,列,检测到),其中“intensity”是浮点数并且“检测到”是二进制1或0.
我想将df_det数据框覆盖在热图中的df_signal帧上,其中检测到的单元格周围有一个框架。
如果这样做更容易,我也很乐意使用除了seaborn之外的绘图库。
答案 0 :(得分:5)
我不建议在这里使用seaborn,因为这样会更难以获得具有单位的数据的正确缩放(因为seaborn在轴上使用分类值)。相反,可以使用matplotlib imshow
图。
import pandas as pd
import numpy as np; np.random.seed(1)
import matplotlib.pyplot as plt
# generate data
x = np.linspace(-3,3, num=11)
y = np.linspace(2,8, num=11)
X,Y = np.meshgrid(x,y)
signal = np.random.rand(len(x)*len(y))
det = np.random.poisson(lam=0.5,size=len(x)*len(y))
det[det>1] = 1
df_signal = pd.DataFrame({"y":Y.flatten(), "x":X.flatten(), "intensity":signal})
df_det = pd.DataFrame({"y":Y.flatten(), "x":X.flatten(), "det":det})
# prepare Dataframes
df = df_signal.pivot(index="y", columns="x")
dfmark = df_det[df_det["det"]>0]
#plotting
fig, ax=plt.subplots()
x = df_signal["x"].unique()
y = df_signal["y"].unique()
ext = [x.min()-np.diff(x)[0]/2.,x.max()+np.diff(x)[0]/2.,
y.min()-np.diff(y)[0]/2.,y.max()+np.diff(y)[0]/2. ]
ax.imshow(df, extent=ext)
ax.set_xticks(x)
ax.set_yticks(y)
ax.scatter(dfmark["x"], dfmark["y"], marker="s", s=100, c="crimson")
plt.show()
您可以使用矩形创建框架,而不是散点图:
dx = np.diff(x)[0]; dy = np.diff(y)[0]
for (xi,yi), in zip(dfmark[["x","y"]].values):
rec = plt.Rectangle((xi-dx/2.,yi-dy/2.),dx,dy, fill=False, hatch="\\",
edgecolor="crimson", lw=2 )
ax.add_artist(rec)