基于 Python 的 seaborn 比率的热图
heatmap based on ratios in Python's seaborn
我有笛卡尔坐标系中的数据。对于每个笛卡尔坐标,也有二进制变量。我想制作一个热图,其中在每个多边形(hexagon/rectangle 等)中,颜色强度是布尔值为 True 的出现次数与该多边形中总出现次数的比率。
例如,数据可能如下所示:
df = pd.DataFrame([[1,2,False],[-1,5,True], [51,52,False]])
我知道 seaborn
可以通过 seaborn.heatmap 生成热图,但颜色强度默认基于每个多边形中的总出现次数,而不是上述比率。有没有更合适的绘图工具?
一个选项是计算两个直方图,一个用于完整的数据帧,一个用于为真值过滤的数据帧。然后将后者除以前者得出比率,你就在后面。
from __future__ import division
import numpy as np
import pandas as pd
import matplotlib.pyplot as plt
x = np.random.poisson(5, size=200)
y = np.random.poisson(7, size=200)
z = np.random.choice([True, False], size=200, p=[0.3, 0.7])
df = pd.DataFrame({"x" : x, "y" : y, "z":z})
dftrue = df[df["z"] == True]
bins = np.arange(0,22)
hist, xbins, ybins = np.histogram2d(df.x, df.y, bins=bins)
histtrue, _ ,__ = np.histogram2d(dftrue.x, dftrue.y, bins=bins)
plt.imshow(histtrue/hist, cmap=plt.cm.Reds)
plt.colorbar()
plt.show()
您还可以使用 pandas groupby
功能来计算比率,然后将结果传递给 seaborn.heatmap。使用从@ImportanceOfBeingErnest 借来的示例数据,它看起来像这样:
import numpy as np
import pandas as pd
import seaborn as sns
np.random.seed(0)
x = np.random.poisson(5, size=200)
y = np.random.poisson(7, size=200)
z = np.random.choice([True, False], size=200, p=[0.3, 0.7])
df = pd.DataFrame({"x" : x, "y" : y, "z":z})
res = df.groupby(['y','x'])['z'].mean().unstack()
ax = sns.heatmap(res)
ax.axis('equal')
ax.invert_yaxis()
the resulting plot
如果您的 x
和 y
值不是整数,您可以将它们分成所需数量的类别以进行分组:
bins = 10
res = df.groupby([pd.cut(df.y, bins),pd.cut(df.x,bins)])['z'].mean().unstack()
我有笛卡尔坐标系中的数据。对于每个笛卡尔坐标,也有二进制变量。我想制作一个热图,其中在每个多边形(hexagon/rectangle 等)中,颜色强度是布尔值为 True 的出现次数与该多边形中总出现次数的比率。
例如,数据可能如下所示:
df = pd.DataFrame([[1,2,False],[-1,5,True], [51,52,False]])
我知道 seaborn
可以通过 seaborn.heatmap 生成热图,但颜色强度默认基于每个多边形中的总出现次数,而不是上述比率。有没有更合适的绘图工具?
一个选项是计算两个直方图,一个用于完整的数据帧,一个用于为真值过滤的数据帧。然后将后者除以前者得出比率,你就在后面。
from __future__ import division
import numpy as np
import pandas as pd
import matplotlib.pyplot as plt
x = np.random.poisson(5, size=200)
y = np.random.poisson(7, size=200)
z = np.random.choice([True, False], size=200, p=[0.3, 0.7])
df = pd.DataFrame({"x" : x, "y" : y, "z":z})
dftrue = df[df["z"] == True]
bins = np.arange(0,22)
hist, xbins, ybins = np.histogram2d(df.x, df.y, bins=bins)
histtrue, _ ,__ = np.histogram2d(dftrue.x, dftrue.y, bins=bins)
plt.imshow(histtrue/hist, cmap=plt.cm.Reds)
plt.colorbar()
plt.show()
您还可以使用 pandas groupby
功能来计算比率,然后将结果传递给 seaborn.heatmap。使用从@ImportanceOfBeingErnest 借来的示例数据,它看起来像这样:
import numpy as np
import pandas as pd
import seaborn as sns
np.random.seed(0)
x = np.random.poisson(5, size=200)
y = np.random.poisson(7, size=200)
z = np.random.choice([True, False], size=200, p=[0.3, 0.7])
df = pd.DataFrame({"x" : x, "y" : y, "z":z})
res = df.groupby(['y','x'])['z'].mean().unstack()
ax = sns.heatmap(res)
ax.axis('equal')
ax.invert_yaxis()
the resulting plot
如果您的 x
和 y
值不是整数,您可以将它们分成所需数量的类别以进行分组:
bins = 10
res = df.groupby([pd.cut(df.y, bins),pd.cut(df.x,bins)])['z'].mean().unstack()