python colorbar xtick locator_关于python:如何使用热图在matplotlib中制作方形子图?

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

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

这将产生以下结果:

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

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

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

如何解决?总而言之,我正在尝试绘制一个非常简单的图形:顶部子图中的正方形树状图,底部子图中的正方形热图,右边的颜色条。没有什么花哨。

最后,还有一个更笼统的问题:是否有一条通用的规则/原理可以迫使matplotlib始终使轴保持正方形?我想不出一种情况,我不想要方轴,但通常不是默认行为。如果可能的话,我想强制所有地块都为正方形。

Aspect =" equal"表示数据空间中的相同长度将与屏幕空间中的相同长度,但是在顶部轴中,xaxis和yaxis的数据范围不同,因此不会是正方形。要解决此问题,可以将纵横比设置为x轴范围和y轴范围的比率:

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

这是输出:

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

垫:设置轴之间的空间和它的colobar

宽度:颜色栏的宽度

用以下代码替换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)

感谢您的回答,但您的地块仍无法像常规子图一样对齐。顶部和底部的边界框未对齐。我希望它们垂直对齐,并且颜色向后悬挂在右侧,有点像您拥有它但没有对齐。有什么想法吗?

感谢您的回答-它的输出完全正确,但是代码似乎非常复杂!有更容易的方法吗?似乎您必须是matplotlib开发人员之一,才能知道如何编写这样的内容,只是为了使颜色条排列起来...

以下是一些示例,但我认为它们也很难理解:matplotlib.sourceforge.net/examples/axes_grid/ matplotlib.sourceforge.net/examples/axes_grid/

我很好地知道了这些示例,但我认为它们不适用,因为其他子图中存在树状图,因为这会由于某些原因而使事情中断。

您知道为什么matplotlib弄乱了底部子图中x标签的垂直对齐吗?为什么arent a, b, c, d, e, f全部对齐?

@HYRY的答案非常好,应该得到所有荣誉。但是要结束有关很好地排列平方图的答案,您可以欺骗matplotlib认为这两个图都有颜色条,仅使第一个不可见:

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

要添加其他答案,您需要将参数的绝对值带到.set_aspect:

x0,x1 = ax1.get_xlim()

y0,y1 = ax1.get_ylim()

ax1.set_aspect(abs(x1-x0)/abs(y1-y0))

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值