【发布时间】:2021-09-13 20:39:55
【问题描述】:
我正在尝试构建一个函数,以使用单个颜色条和直方图在网格中绘制多个图像。我希望所有图之间的间距为固定值,并且颜色栏跨越所有图像的高度,直方图跨越图像/颜色栏的宽度。我有一些有效的代码,但它需要将图形大小设置为特定的纵横比才能工作。这并不理想,因为我想将该函数用于具有不同纵横比的图像以及不同数量的图像 2x1、1x2、2x2 等。
此代码输出 3 个不同纵横比的数字。我想是否将任何多余的尺寸应用于边框间距而不是子图 wspace、hspace 间距。
图宽:https://i.stack.imgur.com/BB1Cz.png
图高:https://i.stack.imgur.com/G5C34.png
图不错:https://i.stack.imgur.com/AVX6C.png
代码如下:
import math
import numpy as np
import matplotlib as mpl
from matplotlib import pyplot as plt
def compare_frames(frames, columns, bins=256, alpha=.5, vmin=None, vmax=None, fig=None):
if vmin is None:
vmin = min([f.min() for f in frames])
if vmax is None:
vmax = max([f.max() for f in frames])
if fig == None:
fig = plt.figure()
color_cycle = plt.get_cmap('tab10')
rows = math.ceil(len(frames)/columns)
width_ratios = [1 for col in range(columns)] + [.05]
gs = mpl.gridspec.GridSpec(rows + 1, columns + 1, figure=fig, width_ratios=width_ratios)
images = []
for row in range(rows):
for col in range(columns):
idx = row*columns + col
if idx < len(frames):
ax = fig.add_subplot(gs[row, col])
ax.get_xaxis().set_ticks([])
ax.get_yaxis().set_ticks([])
for spine in ['bottom', 'top', 'left', 'right']:
ax.spines[spine].set_color(color_cycle(idx))
ax.spines[spine].set_linewidth(3)
images.append(ax.imshow(frames[idx], vmin=vmin, vmax=vmax))
cax = fig.add_subplot(gs[0:-1, -1])
plt.colorbar(images[0], cax=cax)
hax = fig.add_subplot(gs[-1, :])
for i, frame in enumerate(frames):
hax.hist(frame.ravel(), bins=256, range=(vmin, vmax), color=color_cycle(i), alpha=alpha)
fig.subplots_adjust(wspace=.05, hspace=.05)
if __name__ == '__main__':
x_size = 640
y_size = 512
frames = []
for i in range(4):
frames.append(np.random.normal(i + 1, np.sqrt(i + 1), size=(y_size, x_size)))
fig_wide = plt.figure(figsize=(12, 8))
compare_frames(frames, 2, fig=fig_wide)
fig_tall = plt.figure(figsize=(6, 8))
compare_frames(frames, 2, fig=fig_tall)
fig_nice = plt.figure(figsize=(6.9, 8))
compare_frames(frames, 2, fig=fig_nice)
plt.show()
【问题讨论】:
-
你需要“图像”的纵横比是一对一的吗?如果是这样,那么您要求的是通常相对难以做到的事情。具体来说,您当然可以使用 set_position 手动放置轴
-
是的,我需要保留图像的纵横比行。我将使用的真实世界图像是我想要保留纵横比的相机传感器数据。但是,我不会混淆图像的纵横比(我比较的所有帧都将具有相同的纵横比)
标签: python matplotlib subplot figure imshow