如何使用热图在matplotlib中制作方形子图? [英] how to make square subplots in matplotlib with heatmaps?

查看:71
本文介绍了如何使用热图在matplotlib中制作方形子图?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

I'm trying to make a simple subplot with a dendrogram in one subplot and a heat map in another, while maintaining square axes. I try the following:

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

结果如下:

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

but the problems are that the axes are not square, and the colorbar is considered part of the second subplot. I'd like it instead to hang outside the plot, and make it so the dendrogram box and the heatmap box are both square and aligned with each other (i.e. same size.)

正如文档建议的那样,我在调用 subplot 时尝试使用 aspect ='equal'来获取方轴,但这破坏了绘图,给出了...

I tried using aspect='equal' to get square axes when calling subplot as the documentation suggests, but this ruined the plot, giving this...

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

if I try to use plt.axis('equal') after each subplot instead of aspect='equal', it strangely squares the heatmap but not its bounding box (see below), while destroying the dendrogram altogether and also messing up the alignment of the xtick labels.... - giving rise to this mess:

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

how can this be fixed? to summarize, I'm trying to plot something very simple: a square dendrogram in the top subplot, and a square heatmap in the bottom subplot, with the color bar on the right. nothing fancy.

最后,一个更笼统的问题:是否存在要遵循的一般规则/原理来迫使matplotlib 始终使轴变为正方形?我无法想到一种情况,我不希望使用直角坐标轴,但这通常不是默认行为.如果可能的话,我想强制所有地块都为正方形.

finally, more general question: is there a general rule / principle to follow to force matplotlib to always make axes square? I cannot think of a single case where I don't want square axes but it's usually not the default behavior. I'd like to force all plots to be square if possible.

推荐答案

@HYRY的答案非常好,应得到所有荣誉.但是为了完成关于很好地排列平方图的答案,您可以欺骗 matplotlib 认为两个图都有颜色条,只使第一个不可见:

@HYRY's answer is very good and deserves all the credit. But to finish off the answer about lining the squared plots up nicely, you could trick matplotlib into thinking that both plots have colorbars, only making the first one invisible:

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

# add a colorbar to the first plot and immediately make it invisible
cb = plt.colorbar(ax=ax1)
cb.ax.set_visible(False)

plt.show()

这篇关于如何使用热图在matplotlib中制作方形子图?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆