Python包将两个热图合二为一(将每个正方形分成两个三角形)

Posted

技术标签:

【中文标题】Python包将两个热图合二为一(将每个正方形分成两个三角形)【英文标题】:Python package to plot two heatmaps in one (split each square into two triangles) 【发布时间】:2020-12-11 07:16:23 【问题描述】:

我一直在四处寻找,但找不到一个简单的解决方案,通过将热图中的每个正方形分成两个三角形(类似于我在论文中看到的附图),在一个图形中绘制两个热图。有人知道能够做到这一点的 Python 包吗?我尝试了 seaborn,但我认为它没有一个简单的方法来实现这一点。

感谢您的宝贵时间!

-彼得

【问题讨论】:

这不是破坏了热图的目的吗?你能找到热点吗? @RichieV 基本上,我想查看与两个不同属性相关的热点。而不是需要在两个单独的图中找到相同的正方形,我希望将它放在同一个图中(类似于我附加的图像)。 我知道剧情在说什么,我的评论是热图通常用于快速查看热点区域......而且组合版本很难一目了然地发现它们 我个人更喜欢计算一个组合指标并做一个常规的热图 【参考方案1】:

plt.tripcolor 为三角形网格着色,类似于plt.pcolormesh 为矩形网格着色。也类似于pcolormesh,必须注意顶点的数量少于三角形的数量。此外,需要将数组设为一维 (np.ravel)。所有这些重新编号为一维可能有点棘手。

例如,下面的代码根据x*y mod 10 创建了一种颜色,并为上下三角形使用了两个不同的颜色图。

import numpy as np
import matplotlib.pyplot as plt
from matplotlib.tri import Triangulation

M = 30
N = 20
x = np.arange(M + 1)
y = np.arange(N + 1)
xs, ys = np.meshgrid(x, y)
zs = (xs * ys) % 10
zs = zs[:-1, :-1].ravel()

triangles1 = [(i + j*(M+1), i+1 + j*(M+1), i + (j+1)*(M+1)) for j in range(N) for i in range(M)]
triangles2 = [(i+1 + j*(M+1), i+1 + (j+1)*(M+1), i + (j+1)*(M+1)) for j in range(N) for i in range(M)]
triang1 = Triangulation(xs.ravel(), ys.ravel(), triangles1)
triang2 = Triangulation(xs.ravel(), ys.ravel(), triangles2)
img1 = plt.tripcolor(triang1, zs, cmap=plt.get_cmap('inferno', 10), vmax=10)
img2 = plt.tripcolor(triang2, zs, cmap=plt.get_cmap('viridis', 10), vmax=10)

plt.colorbar(img2, ticks=range(10), pad=-0.05)
plt.colorbar(img1, ticks=range(10))
plt.xlim(x[0], x[-1])
plt.ylim(y[0], y[-1])
plt.xticks(x, rotation=90)
plt.yticks(y)
plt.show()

PS:要使整数刻度很好地位于单元格的中心(而不是它们的边界),需要进行以下更改:

triang1 = Triangulation(xs.ravel()-0.5, ys.ravel()-0.5, triangles1)
triang2 = Triangulation(xs.ravel()-0.5, ys.ravel()-0.5, triangles2)

# ...
plt.xlim(x[0]-0.5, x[-1]-0.5)
plt.ylim(y[0]-0.5, y[-1]-0.5)
plt.xticks(x[:-1], rotation=90)
plt.yticks(y[:-1]) 

【讨论】:

是的,这看起来很棒!但是,我对如何使用它有点困惑。所以,我有两个单独的(方形)数据数组(每个二维地图一个)。这与 xs、ys、zs 有什么关系?非常感谢您的帮助! 您需要img1 = plt.tripcolor(triang1, data_array_1.ravel(), cmap=...)img2 = plt.tripcolor(triang2, data_array_2.ravel(), cmap=...)np.ravel() 将 2D(或 nD)数组更改为 1D。演示代码使用zs 两次创建可验证的测试。 效果惊人 - 非常感谢!只是对答案的 PS 部分进行了非常小的更正。添加两行: plt.xticks(x[:-1], rotation=90) plt.yticks(y[:-1])

以上是关于Python包将两个热图合二为一(将每个正方形分成两个三角形)的主要内容,如果未能解决你的问题,请参考以下文章

如何修复 matplotlib 和 seaborn 热图?

如何用python将图片分成均匀间隔的正方形?

更改 seaborn 热图中的某些方块

使用 Matplotlib 绘制 2D 热图

一个 ???? × ????棋盘是要切成它的????·????单位正方形

如何使用Plotly Python组合热图和轮廓图