将色条放置在图像内部

17

我有一个简单的散点图,每个点的颜色由0到1之间的值设置为所选择的色图。这是我的代码的MWE:

import matplotlib.pyplot as plt 
import numpy as np
import matplotlib.gridspec as gridspec

x = np.random.randn(60) 
y = np.random.randn(60)
z = [np.random.random() for _ in range(60)]

fig = plt.figure()
gs = gridspec.GridSpec(1, 2)

ax0 = plt.subplot(gs[0, 0])
plt.scatter(x, y, s=20)

ax1 = plt.subplot(gs[0, 1])
cm = plt.cm.get_cmap('RdYlBu_r')
plt.scatter(x, y, s=20 ,c=z, cmap=cm)
cbaxes = fig.add_axes([0.6, 0.12, 0.1, 0.02]) 
plt.colorbar(cax=cbaxes, ticks=[0.,1], orientation='horizontal')

fig.tight_layout()
plt.show()

它看起来像这样:

图片

问题在于我想让小的水平色条位于绘图的左下角,但是使用cax参数不仅感觉有点hacky,而且会与tight_layout发生冲突,导致出现警告:

/usr/local/lib/python2.7/dist-packages/matplotlib/figure.py:1533: UserWarning: This figure includes Axes that are not compatible with tight_layout, so its results might be incorrect.
  warnings.warn("This figure includes Axes that are not "

有没有更好的方法来定位色条,而不会在每次运行代码时都收到一个讨厌的警告?


编辑

我希望颜色条仅显示最大和最小值,即0和1,并且Joe通过在scatter中添加vmin=0, vmax=1来帮助我实现了这一点:

plt.scatter(x, y, s=20, vmin=0, vmax=1)

所以我将删除问题的这部分内容。


2
每当您手动添加轴时,关于轴不兼容的警告是正确的。您可以安全地忽略它,只需注意tight_layout不会考虑色条的位置。对于第二个问题,实际上是因为您的色条的最小值和最大值并不完全在0和1处。(默认情况下,scatter等函数将其设置为数据的确切最小值和最大值)。如果您传递vmin=0,vmax=1scatter,则刻度将显示出来。 - Joe Kington
我确实可以忽略它,但我宁愿不这样做。当你运行代码时,警告开始飞到你的脸上,这看起来非常糟糕,一定有更好的方法来解决这个问题。vmin=0,vmax=1 的方法可行,所以我将从问题中删除该部分,谢谢! - Gabriel
1
警告只是这样说的:tight_layout 只能处理子图的收缩和放大。如果你有不是子图的坐标轴,它会发出这个警告。你想要有不是子图的坐标轴(颜色条)。你基本上有 3 个选项:a) 捕捉特定的警告并将其静音,b) 关闭警告,c) 不使用 tight_layout,而使用 subplots_adjust 代替。(tight_layout 只是自动计算输入到 subplots_adjust 的值。)希望这能帮到你一点! - Joe Kington
1个回答

25

可以使用mpl_toolkits.axes_grid1.inset_locator.inset_axes函数将一个坐标轴放置在另一个坐标轴内,用于放置颜色条。该坐标轴的位置是相对于父坐标轴而言的,类似于图例使用loc参数进行定位(例如,loc=3表示左下角)。其宽度和高度可以使用绝对数值(英寸)或相对于父坐标轴的百分比进行指定。

cbaxes = inset_axes(ax1, width="30%", height="3%", loc=3) 

在此输入图片描述

import matplotlib.pyplot as plt 
import numpy as np
import matplotlib.gridspec as gridspec
from mpl_toolkits.axes_grid1.inset_locator import inset_axes

x = np.random.randn(60) 
y = np.random.randn(60)
z = [np.random.random() for _ in range(60)]

fig = plt.figure()
gs = gridspec.GridSpec(1, 2)

ax0 = plt.subplot(gs[0, 0])
plt.scatter(x, y, s=20)

ax1 = plt.subplot(gs[0, 1])
cm = plt.cm.get_cmap('RdYlBu_r')
plt.scatter(x, y, s=20 ,c=z, cmap=cm)

fig.tight_layout()

cbaxes = inset_axes(ax1, width="30%", height="3%", loc=3) 
plt.colorbar(cax=cbaxes, ticks=[0.,1], orientation='horizontal')


plt.show()
请注意,为了抑制警告,可以在添加插入轴之前简单地调用tight_layout

除了使用loc方便地定位轴之外(这确实很方便),还有没有使用fig.add_axes()的其他优点? - Gabriel
3
不必担心坐标系正是它的优点。在这个简单的例子中可能不太明显,但在一般情况下,您甚至可能不知道使用 add_axes 需要放置轴的坐标,而 inset_axes 确保轴在其他轴内并相对于其定位。 - ImportanceOfBeingErnest

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接