Matplotlib:如何在使用 plt.figure() 和 figure.addaxes() 时显示图像颜色条
Matplotlib: how to get image color bar to show up when using plt.figure() and figure.addaxes()
我正在尝试用六个单独的地块制作一个图形,组织成两行,每行三个地块。每行图都应该有自己的颜色条,对应于水平组中三个图中显示的图像。从视觉上看,该图应如下所示:
image_type1 | image_type1 | image_type1 | colorbar_for_type1_images
image_type2 | image_type2 | image_type2 | colorbar_for_type2_images
上图中的竖线只是为了分隔图中的不同部分。我实际上不需要图中的垂直线。
下面显示了我正在尝试做的事情的示例,以及我尝试让颜色条与每行中的第三个图像一起绘制的失败尝试。
我过去曾使用类似于下面的代码成功地做到了这一点,当时我使用自己的颜色图绘制一系列线条,而不是而不是我在下面尝试做的图像。
import numpy as np
from matplotlib import pyplot as plt
from matplotlib.cbook import get_sample_data
#Make 6 plotting areas of the same dimensions
figuresizex = 9.0
figuresizey = 6.1
lowerx = .07
lowery = .09
upperx = .92
uppery = .97
xspace = .05
yspace = .11
xwidth = (upperx-lowerx-2*xspace)/3.
ywidth = (uppery-lowery-yspace)/2.
fig = plt.figure(figsize=(figuresizex,figuresizey))
ax1 = fig.add_axes([lowerx,lowery+ywidth+yspace,xwidth,ywidth])
ax2 = fig.add_axes([lowerx+xwidth+xspace,lowery+ywidth+yspace,xwidth,ywidth])
ax3 = fig.add_axes([lowerx+2*xwidth+2*xspace,lowery+ywidth+yspace,xwidth,ywidth])
ax4 = fig.add_axes([lowerx,lowery,xwidth,ywidth])
ax5 = fig.add_axes([lowerx+xwidth+xspace,lowery,xwidth,ywidth])
ax6 = fig.add_axes([lowerx+2*xwidth+2*xspace,lowery,xwidth,ywidth])
axlist = [ax1,ax2,ax3,ax4,ax5,ax6]
#Start plotting images
image = np.identity(5)
for i in range(0,3):
vmin, vmax = image.min(),image.max()
axuse = axlist[i]
im = axuse.imshow(image, vmin=vmin, vmax=vmax)
if i == 3:
cbar = axuse.colorbar(im)
cbar = plt.colorbar(im)
image_2 = np.arange(16).reshape((4,4))
for i in range(0,3):
vmin, vmax = image_2.min(),image_2.max()
axuse = axlist[i+3]
axuse.imshow(image_2,vmin=vmin, vmax=vmax)
if i == 3:
cbar = axuse.colorbar()
cbar = plt.colorbar()
plt.show()
我建议采用 this question 中概述的方法。
除了可以直接添加颜色条而不取决于第三张图片(应该是 i==2)之外,ImageGrid 的使用消除了显式(痛苦地?)定义所有 6 个的需要如果您的图像数量发生变化,轴会变得更加灵活。
更新:我添加了第三行以表明通过使用 vmin 和 vmax 参数可以将相同的比例应用于每一行中的所有图像。
import numpy as np
from matplotlib import pyplot as plt
from mpl_toolkits.axes_grid1 import ImageGrid
figuresizex = 9.0
figuresizey = 6.1
# generate images
image1 = np.identity(5)
image2 = np.arange(16).reshape((4,4))
fig = plt.figure(figsize=(figuresizex,figuresizey))
# create your grid objects
top_row = ImageGrid(fig, 311, nrows_ncols = (1,3), axes_pad = .25,
cbar_location = "right", cbar_mode="single")
middle_row = ImageGrid(fig, 312, nrows_ncols = (1,3), axes_pad = .25,
cbar_location = "right", cbar_mode="single")
bottom_row = ImageGrid(fig, 313, nrows_ncols = (1,3), axes_pad = .25,
cbar_location = "right", cbar_mode="single")
# plot the images
for i in range(3):
vmin, vmax = image1.min(),image1.max()
ax = top_row[i]
im1 = ax.imshow(image1, vmin=vmin, vmax=vmax)
for i in range(3):
vmin, vmax = image2.min(),image2.max()
ax =middle_row[i]
im2 = ax.imshow(image2, vmin=vmin, vmax=vmax)
# Update showing how to use identical scale across all 3 images
# make some slightly different images and get their bounds
image2s = [image2,image2 + 5,image2 - 5]
# inelegant way to get the absolute upper and lower bounds from the three images
i_max, i_min = 0,0
for im in image2s:
if im.max() > i_max:
i_max= im.max()
if im.min() < i_min:
i_min = im.min()
# plot these as you would the others, but use identical vmin and vmax for all three plots
for i,im in enumerate(image2s):
ax = bottom_row[i]
im2_scaled = ax.imshow(im, vmin = i_min, vmax = i_max)
# add your colorbars
cbar1 = top_row.cbar_axes[0].colorbar(im1)
middle_row.cbar_axes[0].colorbar(im2)
bottom_row.cbar_axes[0].colorbar(im2_scaled)
# example of titling colorbar1
cbar1.set_label_text("label"))
# readjust figure margins after adding colorbars,
# left and right are unequal because of how
# colorbar labels don't appear to factor in to the adjustment
plt.subplots_adjust(left=0.075, right=0.9)
plt.show()
我正在尝试用六个单独的地块制作一个图形,组织成两行,每行三个地块。每行图都应该有自己的颜色条,对应于水平组中三个图中显示的图像。从视觉上看,该图应如下所示:
image_type1 | image_type1 | image_type1 | colorbar_for_type1_images
image_type2 | image_type2 | image_type2 | colorbar_for_type2_images
上图中的竖线只是为了分隔图中的不同部分。我实际上不需要图中的垂直线。
下面显示了我正在尝试做的事情的示例,以及我尝试让颜色条与每行中的第三个图像一起绘制的失败尝试。
我过去曾使用类似于下面的代码成功地做到了这一点,当时我使用自己的颜色图绘制一系列线条,而不是而不是我在下面尝试做的图像。
import numpy as np
from matplotlib import pyplot as plt
from matplotlib.cbook import get_sample_data
#Make 6 plotting areas of the same dimensions
figuresizex = 9.0
figuresizey = 6.1
lowerx = .07
lowery = .09
upperx = .92
uppery = .97
xspace = .05
yspace = .11
xwidth = (upperx-lowerx-2*xspace)/3.
ywidth = (uppery-lowery-yspace)/2.
fig = plt.figure(figsize=(figuresizex,figuresizey))
ax1 = fig.add_axes([lowerx,lowery+ywidth+yspace,xwidth,ywidth])
ax2 = fig.add_axes([lowerx+xwidth+xspace,lowery+ywidth+yspace,xwidth,ywidth])
ax3 = fig.add_axes([lowerx+2*xwidth+2*xspace,lowery+ywidth+yspace,xwidth,ywidth])
ax4 = fig.add_axes([lowerx,lowery,xwidth,ywidth])
ax5 = fig.add_axes([lowerx+xwidth+xspace,lowery,xwidth,ywidth])
ax6 = fig.add_axes([lowerx+2*xwidth+2*xspace,lowery,xwidth,ywidth])
axlist = [ax1,ax2,ax3,ax4,ax5,ax6]
#Start plotting images
image = np.identity(5)
for i in range(0,3):
vmin, vmax = image.min(),image.max()
axuse = axlist[i]
im = axuse.imshow(image, vmin=vmin, vmax=vmax)
if i == 3:
cbar = axuse.colorbar(im)
cbar = plt.colorbar(im)
image_2 = np.arange(16).reshape((4,4))
for i in range(0,3):
vmin, vmax = image_2.min(),image_2.max()
axuse = axlist[i+3]
axuse.imshow(image_2,vmin=vmin, vmax=vmax)
if i == 3:
cbar = axuse.colorbar()
cbar = plt.colorbar()
plt.show()
我建议采用 this question 中概述的方法。
除了可以直接添加颜色条而不取决于第三张图片(应该是 i==2)之外,ImageGrid 的使用消除了显式(痛苦地?)定义所有 6 个的需要如果您的图像数量发生变化,轴会变得更加灵活。
更新:我添加了第三行以表明通过使用 vmin 和 vmax 参数可以将相同的比例应用于每一行中的所有图像。
import numpy as np
from matplotlib import pyplot as plt
from mpl_toolkits.axes_grid1 import ImageGrid
figuresizex = 9.0
figuresizey = 6.1
# generate images
image1 = np.identity(5)
image2 = np.arange(16).reshape((4,4))
fig = plt.figure(figsize=(figuresizex,figuresizey))
# create your grid objects
top_row = ImageGrid(fig, 311, nrows_ncols = (1,3), axes_pad = .25,
cbar_location = "right", cbar_mode="single")
middle_row = ImageGrid(fig, 312, nrows_ncols = (1,3), axes_pad = .25,
cbar_location = "right", cbar_mode="single")
bottom_row = ImageGrid(fig, 313, nrows_ncols = (1,3), axes_pad = .25,
cbar_location = "right", cbar_mode="single")
# plot the images
for i in range(3):
vmin, vmax = image1.min(),image1.max()
ax = top_row[i]
im1 = ax.imshow(image1, vmin=vmin, vmax=vmax)
for i in range(3):
vmin, vmax = image2.min(),image2.max()
ax =middle_row[i]
im2 = ax.imshow(image2, vmin=vmin, vmax=vmax)
# Update showing how to use identical scale across all 3 images
# make some slightly different images and get their bounds
image2s = [image2,image2 + 5,image2 - 5]
# inelegant way to get the absolute upper and lower bounds from the three images
i_max, i_min = 0,0
for im in image2s:
if im.max() > i_max:
i_max= im.max()
if im.min() < i_min:
i_min = im.min()
# plot these as you would the others, but use identical vmin and vmax for all three plots
for i,im in enumerate(image2s):
ax = bottom_row[i]
im2_scaled = ax.imshow(im, vmin = i_min, vmax = i_max)
# add your colorbars
cbar1 = top_row.cbar_axes[0].colorbar(im1)
middle_row.cbar_axes[0].colorbar(im2)
bottom_row.cbar_axes[0].colorbar(im2_scaled)
# example of titling colorbar1
cbar1.set_label_text("label"))
# readjust figure margins after adding colorbars,
# left and right are unequal because of how
# colorbar labels don't appear to factor in to the adjustment
plt.subplots_adjust(left=0.075, right=0.9)
plt.show()