gpt4 book ai didi

python - 如何使用热图在 matplotlib 中制作方形子图?

转载 作者:太空狗 更新时间:2023-10-29 17:26:20 25 4
gpt4 key购买 nike

我正在尝试制作一个简单的子图,一个子图中有一个树状图,另一个子图中有一个热图,同时保持方轴。我尝试以下操作:

from scipy.cluster.hierarchy import linkage
from scipy.cluster.hierarchy import dendrogram
from scipy.spatial.distance import pdist

fig = plt.figure(figsize=(7,7))
plt.subplot(2, 1, 1)
cm = matplotlib.cm.Blues
X = np.random.random([5,5])
pmat = pdist(X, "euclidean")
linkmat = linkage(pmat)
dendrogram(linkmat)
plt.subplot(2, 1, 2)
labels = ["a", "b", "c", "d", "e", "f"]
Y = np.random.random([6,6])
plt.xticks(arange(0.5, 7.5, 1))
plt.gca().set_xticklabels(labels)
plt.pcolor(Y)
plt.colorbar()

这会产生以下结果:

enter image description here

但问题是坐标轴不是正方形的,颜色条被认为是第二个子图的一部分。我希望它卡在图外,并使树状图框和热图框都是正方形并彼此对齐(即相同大小。)

我尝试使用 aspect='equal' 在调用 subplot 时按照文档的建议获取方轴,但这破坏了情节,给出了这个...

enter image description here

如果我尝试在每个子图之后使用 plt.axis('equal') 而不是 aspect='equal',它奇怪地使热图平方而不是它的边界框(见下文),同时完全破坏了树状图并且还弄乱了 xtick 标签的对齐.... - 导致了这种困惑:

enter image description here

如何解决这个问题?总而言之,我试图绘制一些非常简单的东西:顶部子图中的方形树状图,底部子图中的方形热图,右侧有颜色条。没什么特别的。

最后,更一般的问题:是否有一般规则/原则可以强制 matplotlib 始终使坐标轴成正方形?我想不出一个我不想要方轴的案例,但这通常不是默认行为。如果可能的话,我想强制所有地 block 都是方形的。

最佳答案

aspect="equal"表示数据空间中的长度相同,屏幕空间中的长度相同,但在你的顶轴中,xaxis 和 yaxis 的数据范围不一样,所以它不会是一个正方形。要解决此问题,您可以将 aspect 设置为 xaxis range 和 yaxis range 的比率:

from scipy.cluster.hierarchy import linkage
from scipy.cluster.hierarchy import dendrogram
from scipy.spatial.distance import pdist
import matplotlib
from matplotlib import pyplot as plt
import numpy as np
from numpy import arange

fig = plt.figure(figsize=(5,7))
ax1 = plt.subplot(2, 1, 1)
cm = matplotlib.cm.Blues
X = np.random.random([5,5])
pmat = pdist(X, "euclidean")
linkmat = linkage(pmat)
dendrogram(linkmat)
x0,x1 = ax1.get_xlim()
y0,y1 = ax1.get_ylim()
ax1.set_aspect((x1-x0)/(y1-y0))
plt.subplot(2, 1, 2, aspect=1)
labels = ["a", "b", "c", "d", "e", "f"]
Y = np.random.random([6,6])
plt.xticks(arange(0.5, 7.5, 1))
plt.gca().set_xticklabels(labels)
plt.pcolor(Y)
plt.colorbar()

这是输出:

enter image description here

要定位颜色条,我们需要编写一个 ColorBarLocator 类,pad 和 width 参数以像素为单位,

  • pad:设置坐标轴和它的colobar之间的空间
  • width:colorbar的宽度

plt.colorbar() 替换为以下代码:

class ColorBarLocator(object):
def __init__(self, pax, pad=5, width=10):
self.pax = pax
self.pad = pad
self.width = width

def __call__(self, ax, renderer):
x, y, w, h = self.pax.get_position().bounds
fig = self.pax.get_figure()
inv_trans = fig.transFigure.inverted()
pad, _ = inv_trans.transform([self.pad, 0])
width, _ = inv_trans.transform([self.width, 0])
return [x+w+pad, y, width, h]

cax = fig.add_axes([0,0,0,0], axes_locator=ColorBarLocator(ax2))
plt.colorbar(cax = cax)

enter image description here

关于python - 如何使用热图在 matplotlib 中制作方形子图?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/11893414/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com