python - 如何结合配对图和三角形热图?
问题描述
我正在尝试制作一个上三角相关矩阵,理想情况下我想将其叠加到下三角矩阵的另一张图片上。因此,我希望将遮罩颜色设置为无或透明(否则,如果它是白色的,我将无法叠加)......关于如何在 seaborn 中执行此操作的任何想法?
编辑
这是我想做的事情:使用数据框中的一组列,我想绘制这些列的对图(下三角形)和相关图(上三角形)
import numpy as np
import pandas as pd
import seaborn as sns
import matplotlib.pyplot as plt
rs = np.random.RandomState(112358)
d1 = pd.DataFrame(data=rs.normal(size=(100, 10)), columns=[*'abcdefghij' ])
corr1 = d1.corr()
mask1 = np.tril(np.ones_like(corr1, dtype=bool))
fig, ax = plt.subplots(figsize=(11, 9))
sns.heatmap(corr1, mask=mask1, cmap='PRGn', vmax=.3, vmin=-.3,
square=True, linewidths=.5, cbar_kws={"shrink": .85, "pad":-.01}, ax=ax)
def hide_current_axis(*args, **kwds):
plt.gca().set_visible(False)
e = sns.pairplot(d1)
e.map_upper(hide_current_axis)
plt.show()
这段代码当然有效,但它分别绘制了这两个数字。
解决方案
创建三角形热图的正常方法是掩盖不需要的部分。那里不会绘制任何内容,原始背景颜色将保持可见。如果您绘制第二张热图,它也只会在未被遮盖的地方绘制。
这是一些代码来演示这个想法。
import numpy as np
import pandas as pd
import seaborn as sns
import matplotlib.pyplot as plt
sns.set_theme(style="white")
rs = np.random.RandomState(112358)
d1 = pd.DataFrame(data=rs.normal(size=(100, 10)), columns=[*'abcdefghij' ])
d2 = pd.DataFrame(data=rs.normal(size=(100, 10)), columns=[*'abcdefghij' ])
corr1 = d1.corr()
corr2 = d2.corr()
mask1 = np.tril(np.ones_like(corr1, dtype=bool))
mask2 = np.triu(np.ones_like(corr2, dtype=bool))
fig, ax = plt.subplots(figsize=(11, 9))
sns.heatmap(corr1, mask=mask1, cmap='PRGn', vmax=.3, vmin=-.3,
square=True, linewidths=.5, cbar_kws={"shrink": .85, "pad":-.01}, ax=ax)
sns.heatmap(corr1, mask=mask2, cmap='RdYlBu', vmax=.3, vmin=-.3,
square=True, linewidths=.5, cbar_kws={"shrink": .85}, ax=ax)
# the following lines color and hatch the axes background, only the diagonals are visible
ax.patch.set_facecolor('grey')
ax.patch.set_edgecolor('yellow')
ax.patch.set_hatch('xx')
plt.show()
关于新问题,将配对图与三角形热图相结合。由于 pairplot 是一个图形级别的函数,它会创建自己的带有子图的图形。应该首先创建它。
作为第二步,ax
可以使用pairplot 的子图的位置创建一个特殊的热图。将其 facecolor 设置为 'none' 使其完全透明(默认为白色,隐藏所有内容)。
添加颜色条可能更麻烦,因为配对图并没有留下一个很好的位置来定位它。
import numpy as np
import pandas as pd
import seaborn as sns
import matplotlib.pyplot as plt
def hide_current_axis(*args, **kwds):
plt.gca().set_visible(False)
rs = np.random.RandomState(112358)
d1 = pd.DataFrame(data=rs.normal(size=(20, 5)), columns=[*'abcde'])
e = sns.pairplot(d1)
e.map_upper(hide_current_axis)
(xmin, _), (_, ymax) = e.axes[0, 0].get_position().get_points()
(_, ymin), (xmax, _) = e.axes[-1, -1].get_position().get_points()
ax = e.fig.add_axes([xmin, ymin, xmax - xmin, ymax - ymin], facecolor='none')
corr1 = d1.corr()
mask1 = np.tril(np.ones_like(corr1, dtype=bool))
sns.heatmap(corr1, mask=mask1, cmap='seismic', vmax=.5, vmin=-.5,
linewidths=.5, cbar=False, annot=True, annot_kws={'size': 22}, ax=ax)
ax.set_xticks([])
ax.set_yticks([])
# ax.xaxis.tick_top()
# ax.yaxis.tick_right()
plt.show()
正如评论中提到的,一种更忠实于 seaborn 理念的方法是根据相关性以及数字显示为右上方子图的轴着色。我找不到示例代码,这是我的尝试:
import numpy as np
import pandas as pd
import seaborn as sns
import matplotlib.pyplot as plt
from scipy.stats import pearsonr
def corrfunc(x, y, **kwds):
cmap = kwds['cmap']
norm = kwds['norm']
ax = plt.gca()
ax.tick_params(bottom=False, top=False, left=False, right=False)
sns.despine(ax=ax, bottom=True, top=True, left=True, right=True)
r, _ = pearsonr(x, y)
facecolor = cmap(norm(r))
ax.set_facecolor(facecolor)
lightness = (max(facecolor[:3]) + min(facecolor[:3]) ) / 2
ax.annotate(f"r={r:.2f}", xy=(.5, .5), xycoords=ax.transAxes,
color='white' if lightness < 0.7 else 'black', size=26, ha='center', va='center')
rs = np.random.RandomState(112358)
d1 = pd.DataFrame(data=rs.normal(size=(20, 5)), columns=[*'abcde'])
g = sns.PairGrid(d1)
g.map_lower(plt.scatter, s=10)
g.map_diag(sns.histplot, kde=False)
g.map_upper(corrfunc, cmap=plt.get_cmap('seismic'), norm=plt.Normalize(vmin=-.5, vmax=.5))
g.fig.subplots_adjust(wspace=0.06, hspace=0.06) # equal spacing in both directions
plt.show()
推荐阅读
- android - 具有全屏和列表视图的 Android 故障打开应用程序
- drake-r-package - 对 drake 工作流程的自定义函数进行单元测试的最佳实践
- angular - 在 Eclipse 中运行 Angular IDE 的文档在哪里
- r - 删除 R (flowCore) 中的 S4 类列
- javascript - InvalidValueError:NaN 不是可接受的纬度值
- connection - PHPMailer & Mailhog:连接被拒绝,主机未知
- mysql - 查询条件中的限制和计数器
- c# - 如何实现与 Thread.Sleep() 相同但异步的结果并保持相同的行为?
- python - Python [0]*n 语法仅适用于不可变对象?
- javascript - 使用 php 和 javascript 时如何在表单中显示错误消息