theverge
theverge

Reputation: 61

Overlay two heatmaps in seaborn (one being frames around cells in the other) from a pandas dataframe

I have this simple problem: I have two data frames, one df_signal with columns (row, column, intensity), the other df_det with (row, column, detected), where "intensity" is a float and "detected" is binary 1 or 0.

I'd like to overlay the df_det data frame over the df_signal frame in a heatmap, where cells that were detected have a frame around them.

I'm also happy to use a plotting library other than seaborn, if this makes it easier.

Upvotes: 5

Views: 3462

Answers (1)

ImportanceOfBeingErnest
ImportanceOfBeingErnest

Reputation: 339330

I would not recommend to use seaborn here, since that makes it more difficult to get the correct scaling for data with units (as seaborn uses categorical values on the axes). Instead one may use a matplotlib imshow plot.

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()

enter image description here

Instead of the scatter, you can create a frame by using rectangles:

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)

enter image description here

Upvotes: 9

Related Questions