我无法让像这样的imshow图形上的颜色条与图形的高度相同,因为事后没有使用Photoshop。我如何让高度匹配?


当前回答

我最近遇到了这个问题,我使用ax.twinx()来解决它。例如:

from matplotlib import pyplot as plt

# Some other code you've written
...

# Your data generation goes here
xdata = ...
ydata = ...
colordata = function(xdata, ydata)

# Your plotting stuff begins here
fig, ax = plt.subplots(1)
im = ax.scatterplot(xdata, ydata, c=colordata)

# Create a new axis which will be the parent for the colour bar
# Note that this solution is independent of the 'fig' object
ax2 = ax.twinx()
ax2.tick_params(which="both", right=False, labelright=False)

# Add the colour bar itself
plt.colorbar(im, ax=ax2)

# More of your code
...

plt.show()

我发现这在创建将matplotlib Axes对象作为参数、在它们上绘图并返回对象的函数时特别有用,因为这样我就不需要传入必须从图形对象生成的单独轴,也不需要传入图形对象本身。

其他回答

使用matplotlib AxisDivider可以很容易地做到这一点。

链接页面中的例子也可以不使用子图:

import matplotlib.pyplot as plt
from mpl_toolkits.axes_grid1 import make_axes_locatable
import numpy as np
    
plt.figure()
ax = plt.gca()
im = ax.imshow(np.arange(100).reshape((10,10)))
    
# create an axes on the right side of ax. The width of cax will be 5%
# of ax and the padding between cax and ax will be fixed at 0.05 inch.
divider = make_axes_locatable(ax)
cax = divider.append_axes("right", size="5%", pad=0.05)
   
plt.colorbar(im, cax=cax)

创建颜色条时,尝试使用分数和/或收缩参数。

从文件中:

分数0.15;用于颜色条的原始轴的部分 减少1.0;用来缩小颜色条的分数

@bogatron已经给出了matplotlib文档建议的答案,它产生了正确的高度,但它引入了一个不同的问题。 现在,颜色条的宽度(以及颜色条和绘图之间的空间)随着绘图的宽度而变化。 换句话说,颜色条的纵横比不再是固定的。

为了获得正确的高度和给定的宽高比,您必须深入研究神秘的axes_grid1模块。

import matplotlib.pyplot as plt
from mpl_toolkits.axes_grid1 import make_axes_locatable, axes_size
import numpy as np

aspect = 20
pad_fraction = 0.5

ax = plt.gca()
im = ax.imshow(np.arange(200).reshape((20, 10)))
divider = make_axes_locatable(ax)
width = axes_size.AxesY(ax, aspect=1./aspect)
pad = axes_size.Fraction(pad_fraction, width)
cax = divider.append_axes("right", size=width, pad=pad)
plt.colorbar(im, cax=cax)

请注意,这指定了颜色条的宽度w.r.t.绘图的高度(与图形的宽度形成对比,就像以前一样)。

颜色条和图形之间的间距现在可以指定为颜色条宽度的一个分数,在我看来,这是一个比图形宽度的分数更有意义的数字。

更新:

我创建了一个关于这个主题的IPython笔记本,在那里我把上面的代码打包成一个易于重用的函数:

import matplotlib.pyplot as plt
from mpl_toolkits import axes_grid1

def add_colorbar(im, aspect=20, pad_fraction=0.5, **kwargs):
    """Add a vertical color bar to an image plot."""
    divider = axes_grid1.make_axes_locatable(im.axes)
    width = axes_grid1.axes_size.AxesY(im.axes, aspect=1./aspect)
    pad = axes_grid1.axes_size.Fraction(pad_fraction, width)
    current_ax = plt.gca()
    cax = divider.append_axes("right", size=width, pad=pad)
    plt.sca(current_ax)
    return im.axes.figure.colorbar(im, cax=cax, **kwargs)

它可以这样使用:

im = plt.imshow(np.arange(200).reshape((20, 10)))
add_colorbar(im)

我最近遇到了这个问题,我使用ax.twinx()来解决它。例如:

from matplotlib import pyplot as plt

# Some other code you've written
...

# Your data generation goes here
xdata = ...
ydata = ...
colordata = function(xdata, ydata)

# Your plotting stuff begins here
fig, ax = plt.subplots(1)
im = ax.scatterplot(xdata, ydata, c=colordata)

# Create a new axis which will be the parent for the colour bar
# Note that this solution is independent of the 'fig' object
ax2 = ax.twinx()
ax2.tick_params(which="both", right=False, labelright=False)

# Add the colour bar itself
plt.colorbar(im, ax=ax2)

# More of your code
...

plt.show()

我发现这在创建将matplotlib Axes对象作为参数、在它们上绘图并返回对象的函数时特别有用,因为这样我就不需要传入必须从图形对象生成的单独轴,也不需要传入图形对象本身。

这种组合(以及接近这些值)似乎“神奇地”为我工作,以保持颜色条缩放到绘图,无论显示器的大小。

plt.colorbar(im,fraction=0.046, pad=0.04)

它也不需要共享轴,这可以使绘图脱离正方形。