Matplotlib子图如何将颜色条与其他图例对齐,或如何使子图向左对齐

a11

如何在第二个和第三个子图中添加一个颜色条比例尺,使其与我的第一个和第四个子图中的图例保持一致?或者,用另一种方式表达问题:如何在不更改第二和第三子图的对齐方式/对齐方式的情况下添加颜色条比例尺?

关于设置颜色条的位置,有很多很好的例子(例如,在stackoverflowmatplotlib docs中),但是我仍然无法解决这个问题。

以下是可重现的示例。实际数据更加复杂,并且这是产生许多图形的循环的一部分,因此需要有关设置轴限制和子图纵横比的“额外”内容,并且会随不同数据集而变化。

使用Python 3.8。

不带颜色条的可复制示例

## Specify axes limits, tick intervals, and aspect ratio
xl, yl, xytick, ar = [-40000,120000], [-30000,10000], 20000, 0.8

## Global plot layout stuff
fig = plt.figure(figsize=(10, 7.5), constrained_layout=True)
gs = fig.add_gridspec(4, 1)
ax1 = fig.add_subplot(gs[0, 0])
ax2 = fig.add_subplot(gs[1, 0], sharex = ax1, sharey = ax1)
ax3 = fig.add_subplot(gs[2, 0], sharex = ax1)
ax4 = fig.add_subplot(gs[3, 0], sharex = ax1, sharey = ax3)
fig.execute_constrained_layout()
fig.suptitle('Suptitle')


## First Plot
ax1.plot([-30000, 500], [-2000, -21000], c='red', label='A')
ax1.plot([80000, 110000], [-9000, 800], c='blue', label='B')
ax1.set_title('ax1', style='italic');
ax1.set_xlabel('x');
ax1.set_ylabel('beta');
ax1.set_xlim(xl)
ax1.set_ylim(yl)
ax1.xaxis.set_major_locator(ticker.MultipleLocator(xytick))
ax1.yaxis.set_major_locator(ticker.MultipleLocator(xytick))
ax1.legend(handles=leg, bbox_to_anchor=(1.05, 1), loc='upper left')
ax1.set_aspect(aspect=ar)


## Dummy data for plots 2/3/4
x = [-15000, -2000, 0, 5000, 6000, 11000, 18000, 21000, 25000, 36000, 62000]
beta = [1000, 200, -800, 100, 1000, -2000, -5000, -5000, -15000, -21000, -1500]
y = [0.01, 0.2, 1.3, 0.35, 0.88, 2.2, 2.5, 1.25, 3.4, 4.1, 2.1]


## Second Plot
vals = ax2.scatter(x, beta, c=y, norm=mcolors.LogNorm(), cmap='rainbow')
ax2.set_title('ax2', style='italic');
ax2.set_xlabel('x');
ax2.set_ylabel('beta');
ax2.set_aspect(aspect=ar)

## Attempt to add colorbar
#cbar = fig.colorbar(vals, ax=ax2, format = '%1.2g', location='right', aspect=25)
#cbar.ax.set_ylabel('y')
#cbar.ax.yaxis.set_label_position('left')
#cbar_range = [min(y), max(y)]
#ticklabels = cbar.ax.get_ymajorticklabels()
#cbarticks = list(cbar.get_ticks())
#cbar.set_ticks(cbar_range + cbarticks)


## Third Plot
ax3.scatter(x, y, c=y, norm=mcolors.LogNorm(), cmap='rainbow')
ax3.set_title('ax3', style='italic');
ax3.set_xlabel('x');
ax3.set_ylabel('y');
ax3.yaxis.set_major_formatter(FormatStrFormatter('%1.2g'))


## Fourth Plot
ax4.scatter(x, y, c='black', label='Dots')
ax4.set_title('ax4', style='italic');
ax4.set_xlabel('x');
ax4.set_ylabel('y');
ax4.legend(bbox_to_anchor=(1.05, 1), loc='upper left')


## Clean-up, set aspect ratios
figW, figH = ax1.get_figure().get_size_inches()
_, _, w, h = ax1.get_position().bounds
disp_ratio = (figH * h) / (figW * w)
data_ratio = sub(*ax3.get_ylim()) / sub(*ax3.get_xlim())
ax3.set_aspect(aspect=disp_ratio / data_ratio )
ax4.set_aspect(aspect=disp_ratio / data_ratio)

## Clean-up, turn axis ticks back on after messing with cbar
#ax1.tick_params(axis='both', which='both', labelbottom='on')
#ax2.tick_params(axis='both', which='both', labelbottom='on')
#ax3.tick_params(axis='both', which='both', labelbottom='on')

在此处输入图片说明

尝试颜色条时的结果,请注意第二个图的未对齐

在此处输入图片说明

a11

inset_axes()如另一个答案中所建议的那样,using可以解决此问题,但是示例中未解释与转换相关的参数,但是我可以通过一些研究弄清楚。

inset_axes中的参数为[x-corner,y-corner,width,height],并且变换就像是本地引用。因此,使用[1,0,0.5,0.75]表示:x = 100%或父级斧头的末端;y = 0%或父轴的底端;宽度=父斧头的50%;高度=父斧头的75%。

在这里,我希望颜色条与父斧头(ax2和ax3)的高度相同,非常细,并且偏移一点以使其与其他图例更加一致。通过使用cbax = ax2.inset_axes([1.1, 0, 0.03, 1], transform=ax2.transAxes)可以达到目的。

此代码适用于任何纵横比ar

import matplotlib.pyplot as plt
import matplotlib.gridspec as gridspec
import matplotlib.colors as mcolors
from operator import sub
%matplotlib inline 
plt.style.use('seaborn-whitegrid')

## Specify axes limits, tick intervals, and aspect ratio
xl, yl, ar = [-40000,120000], [-30000,10000], .5

## Global plot layout stuff
fig = plt.figure(figsize=(10, 7.5), constrained_layout=True)
gs = fig.add_gridspec(4, 1)
ax1 = fig.add_subplot(gs[0, 0])
ax2 = fig.add_subplot(gs[1, 0], sharex = ax1, sharey = ax1)
ax3 = fig.add_subplot(gs[2, 0], sharex = ax1)
ax4 = fig.add_subplot(gs[3, 0], sharex = ax1, sharey = ax3)
fig.execute_constrained_layout()
fig.suptitle('Suptitle')


## First Plot
ax1.plot([-30000, 500], [-2000, -21000], c='red', label='A')
ax1.plot([80000, 110000], [-9000, 800], c='blue', label='B')
ax1.set_title('ax1', style='italic');
ax1.set_xlim(xl)
ax1.set_ylim(yl)
ax1.legend(bbox_to_anchor=(1.05, 1), loc='upper left')
ax1.set_aspect(aspect=ar)

## Dummy data for plots 2/3/4
x = [-15000, -2000, 0, 5000, 6000, 11000, 18000, 21000, 25000, 36000, 62000]
beta = [1000, 200, -800, 100, 1000, -2000, -5000, -5000, -15000, -21000, -1500]
y = [0.01, 0.2, 1.3, 0.35, 0.88, 2.2, 2.5, 1.25, 3.4, 4.1, 2.1]

## Second Plot
vals = ax2.scatter(x, beta, c=y, norm=mcolors.LogNorm(), cmap='rainbow')
ax2.set_title('ax2', style='italic');
ax2.set_aspect(aspect=ar)
cbax = ax2.inset_axes([1.1, 0, 0.03, 1], transform=ax2.transAxes)
cbar2 = fig.colorbar(vals, cax=cbax, format = '%1.2g', orientation='vertical')

## Third Plot
ax3.scatter(x, y, c=y, norm=mcolors.LogNorm(), cmap='rainbow')
ax3.set_title('ax3', style='italic');
cbax = ax3.inset_axes([1.1, 0, 0.03, 1], transform=ax3.transAxes)
cbar3 = fig.colorbar(vals, cax=cbax, format = '%1.2g', orientation='vertical')

## Fourth Plot
ax4.scatter(x, y, c='black', label='Dots')
ax4.set_title('ax4', style='italic');
ax4.legend(bbox_to_anchor=(1.05, 1), loc='upper left')

## Clean-up, set aspect ratios
figW, figH = ax1.get_figure().get_size_inches()
_, _, w, h = ax1.get_position().bounds
disp_ratio = (figH * h) / (figW * w)
data_ratio = sub(*ax3.get_ylim()) / sub(*ax3.get_xlim())
ax3.set_aspect(aspect=disp_ratio / data_ratio )
ax4.set_aspect(aspect=disp_ratio / data_ratio)

## Colorbars
cbar2.ax.set_ylabel('y')
cbar2.ax.yaxis.set_label_position('left')
cbar3.ax.set_ylabel('y')
cbar3.ax.yaxis.set_label_position('left')

前2个图的宽高比= 0.5的结果 在此处输入图片说明

前2个图的宽高比= 2的结果

在此处输入图片说明

本文收集自互联网,转载请注明来源。

如有侵权,请联系 [email protected] 删除。

编辑于
0

我来说两句

0 条评论
登录 后参与评论

相关文章