使用颜色条在绘图中设置相等的纵横比
Set equal aspect in plot with colorbar
我需要生成一个纵横比相等的图,并且颜色条在右边。我试过设置 aspect='auto'
、aspect=1
和 aspect='equal'
,但没有很好的效果。请参阅下面的示例和 MWE。
使用 aspect='auto'
颜色条的高度正确,但绘图失真:
使用 aspect=1
或 aspect='equal'
绘图是正方形的(两个轴上的纵横比相等)但颜色条失真:
在这两个图中,出于某种原因,颜色条的位置太靠右了。如何获得带有匹配高度的颜色条的方形图?
MWE
import numpy as np
import matplotlib.gridspec as gridspec
import matplotlib.pyplot as plt
def col_plot(params):
gs, i, data = params
xarr, yarr, zarr = zip(*data)[0], zip(*data)[1], zip(*data)[2]
xmin, xmax = min(xarr), max(xarr)
ymin, ymax = min(yarr), max(yarr)
#plt.subplot(gs[i], aspect='auto')
plt.subplot(gs[i], aspect=1)
#plt.subplot(gs[i], aspect='equal')
plt.xlim(xmin, xmax)
plt.ylim(xmin, xmax)
plt.xlabel('$x axis$', fontsize=20)
plt.ylabel('$y axis$', fontsize=20)
# Scatter plot.
cm = plt.cm.get_cmap('RdYlBu_r')
SC = plt.scatter(xarr, yarr, marker='o', c=zarr, s=60, lw=0.25, cmap=cm,
zorder=3)
# Colorbar.
ax0 = plt.subplot(gs[i + 1])
cbar = plt.colorbar(SC, cax=ax0)
cbar.set_label('$col bar$', fontsize=21, labelpad=-2)
# Generate data.
data0 = np.random.uniform(0., 1., size=(50, 3))
data1 = np.random.uniform(0., 1., size=(50, 3))
# Create the top-level container
fig = plt.figure(figsize=(14, 25))
gs = gridspec.GridSpec(4, 4, width_ratios=[1, 0.05, 1, 0.05])
# Generate plots.
par_lst = [[gs, 0, data0], [gs, 2, data1]]
for pl_params in par_lst:
col_plot(pl_params)
# Output png file.
fig.tight_layout()
plt.savefig('colorbar_aspect.png', dpi=300)
您可以使用 AxesDivider 来做到这一点。我已经稍微修改了您的代码以使用 AxesDivider。
import numpy as np
import matplotlib.pyplot as plt
from mpl_toolkits.axes_grid1 import make_axes_locatable
def col_plot(data):
xarr, yarr, zarr = zip(*data)[0], zip(*data)[1], zip(*data)[2]
xarr = [2*x for x in xarr]
xmin, xmax = min(xarr), max(xarr)
ymin, ymax = min(yarr), max(yarr)
fig = plt.figure()
ax0 = fig.add_subplot(111, aspect='equal')
plt.xlim(xmin, xmax)
plt.ylim(ymin, ymax)
plt.xlabel('$x axis$', fontsize=20)
plt.ylabel('$y axis$', fontsize=20)
# Scatter plot.
cm = plt.cm.get_cmap('RdYlBu_r')
SC = ax0.scatter(xarr, yarr, marker='o', c=zarr, s=60, lw=0.25, cmap=cm,
zorder=3)
the_divider = make_axes_locatable(ax0)
color_axis = the_divider.append_axes("right", size="5%", pad=0.1)
# Colorbar.
cbar = plt.colorbar(SC, cax=color_axis)
cbar.set_label('$col bar$', fontsize=21, labelpad=-2)
# Generate data.
data0 = np.random.uniform(0., 1., size=(20, 3))
col_plot(data0)
结果如下(出于演示目的,我更改了您的数据,因此它在 x 方向上的范围为 [0, 2]):
在 Joseph Long's blog 上有以下不错的解决方案。
1) 定义一个colorbar
函数为:
from mpl_toolkits.axes_grid1 import make_axes_locatable
def colorbar(mappable):
ax = mappable.axes
fig = ax.figure
divider = make_axes_locatable(ax)
cax = divider.append_axes("right", size="5%", pad=0.05)
return fig.colorbar(mappable, cax=cax)
2) 当你想制作颜色条时调用colorbar(thing)
。在你的情况下:
SC = ax0.scatter(xarr, yarr, marker='o', c=zarr, s=60, lw=0.25, cmap=cm,
zorder=3)
colorbar(SC)
3) 你会得到:
我需要生成一个纵横比相等的图,并且颜色条在右边。我试过设置 aspect='auto'
、aspect=1
和 aspect='equal'
,但没有很好的效果。请参阅下面的示例和 MWE。
使用 aspect='auto'
颜色条的高度正确,但绘图失真:
使用 aspect=1
或 aspect='equal'
绘图是正方形的(两个轴上的纵横比相等)但颜色条失真:
在这两个图中,出于某种原因,颜色条的位置太靠右了。如何获得带有匹配高度的颜色条的方形图?
MWE
import numpy as np
import matplotlib.gridspec as gridspec
import matplotlib.pyplot as plt
def col_plot(params):
gs, i, data = params
xarr, yarr, zarr = zip(*data)[0], zip(*data)[1], zip(*data)[2]
xmin, xmax = min(xarr), max(xarr)
ymin, ymax = min(yarr), max(yarr)
#plt.subplot(gs[i], aspect='auto')
plt.subplot(gs[i], aspect=1)
#plt.subplot(gs[i], aspect='equal')
plt.xlim(xmin, xmax)
plt.ylim(xmin, xmax)
plt.xlabel('$x axis$', fontsize=20)
plt.ylabel('$y axis$', fontsize=20)
# Scatter plot.
cm = plt.cm.get_cmap('RdYlBu_r')
SC = plt.scatter(xarr, yarr, marker='o', c=zarr, s=60, lw=0.25, cmap=cm,
zorder=3)
# Colorbar.
ax0 = plt.subplot(gs[i + 1])
cbar = plt.colorbar(SC, cax=ax0)
cbar.set_label('$col bar$', fontsize=21, labelpad=-2)
# Generate data.
data0 = np.random.uniform(0., 1., size=(50, 3))
data1 = np.random.uniform(0., 1., size=(50, 3))
# Create the top-level container
fig = plt.figure(figsize=(14, 25))
gs = gridspec.GridSpec(4, 4, width_ratios=[1, 0.05, 1, 0.05])
# Generate plots.
par_lst = [[gs, 0, data0], [gs, 2, data1]]
for pl_params in par_lst:
col_plot(pl_params)
# Output png file.
fig.tight_layout()
plt.savefig('colorbar_aspect.png', dpi=300)
您可以使用 AxesDivider 来做到这一点。我已经稍微修改了您的代码以使用 AxesDivider。
import numpy as np
import matplotlib.pyplot as plt
from mpl_toolkits.axes_grid1 import make_axes_locatable
def col_plot(data):
xarr, yarr, zarr = zip(*data)[0], zip(*data)[1], zip(*data)[2]
xarr = [2*x for x in xarr]
xmin, xmax = min(xarr), max(xarr)
ymin, ymax = min(yarr), max(yarr)
fig = plt.figure()
ax0 = fig.add_subplot(111, aspect='equal')
plt.xlim(xmin, xmax)
plt.ylim(ymin, ymax)
plt.xlabel('$x axis$', fontsize=20)
plt.ylabel('$y axis$', fontsize=20)
# Scatter plot.
cm = plt.cm.get_cmap('RdYlBu_r')
SC = ax0.scatter(xarr, yarr, marker='o', c=zarr, s=60, lw=0.25, cmap=cm,
zorder=3)
the_divider = make_axes_locatable(ax0)
color_axis = the_divider.append_axes("right", size="5%", pad=0.1)
# Colorbar.
cbar = plt.colorbar(SC, cax=color_axis)
cbar.set_label('$col bar$', fontsize=21, labelpad=-2)
# Generate data.
data0 = np.random.uniform(0., 1., size=(20, 3))
col_plot(data0)
结果如下(出于演示目的,我更改了您的数据,因此它在 x 方向上的范围为 [0, 2]):
在 Joseph Long's blog 上有以下不错的解决方案。
1) 定义一个colorbar
函数为:
from mpl_toolkits.axes_grid1 import make_axes_locatable
def colorbar(mappable):
ax = mappable.axes
fig = ax.figure
divider = make_axes_locatable(ax)
cax = divider.append_axes("right", size="5%", pad=0.05)
return fig.colorbar(mappable, cax=cax)
2) 当你想制作颜色条时调用colorbar(thing)
。在你的情况下:
SC = ax0.scatter(xarr, yarr, marker='o', c=zarr, s=60, lw=0.25, cmap=cm,
zorder=3)
colorbar(SC)
3) 你会得到: