英文:
How to reduce the gap between a pcolormesh and a colorbar in matplotlib?
问题
以下是您提供的代码的翻译部分:
import numpy as np
import matplotlib.pyplot as plt
from matplotlib import gridspec
xs = np.linspace(0.1, 0.2, 100)
ys = np.linspace(0, 2*np.pi*0.1, 400)
x_mesh, y_mesh = np.meshgrid(xs, ys)
# 模拟数据数组
A = np.full_like(x_mesh, 1.0)
B = np.full_like x_mesh, 1.0)
C = np.full_like(x_mesh, 1.0)
D = np.full_like(x_mesh, 1.0)
fig = plt.figure()
gs = gridspec.GridSpec(nrows=2, ncols=4, height_ratios=(0.5, 0.5), width_ratios=(0.45, 0.05, 0.45, 0.05))
ax0 = fig.add_subplot(gs[0, 0])
ax0_cbar = fig.add_subplot(gs[0, 1])
ax1 = fig.add_subplot(gs[0, 2])
ax1_cbar = fig add_subplot(gs[0, 3])
ax2 = fig.add_subplot(gs[1, 0])
ax2_cbar = fig.add_subplot(gs[1, 1])
ax3 = fig.add_subplot(gs[1, 2])
ax3_cbar = fig.add_subplot(gs[1, 3])
a = ax0.pcolormesh(x_mesh/1.0e-2, y_mesh/1.0e-2, A, \
shading='auto')
cb1 = plt.colorbar(a, cax=ax0_cbar)
cb1.set_label("A")
b = ax1.pcolormesh(x_mesh/1.0e-2, y_mesh/1.0e-2, B, \
shading='auto')
cb1 = plt.colorbar(b, cax=ax1_cbar)
cb1.set_label("B")
c = ax2.pcolormesh(x_mesh/1.0e-2, y_mesh/1.0e-2, C, \
shading='auto')
cb1 = plt.colorbar(c, cax=ax2_cbar)
cb1.set_label("C")
d = ax3.pcolormesh(x_mesh/1.0e-2, y_mesh/1.0e-2, D, \
shading='auto')
cb1 = plt.colorbar(d, cax=ax3_cbar)
cb1.set_label("D")
ax0.xaxis.set_ticklabels([])
ax1.xaxis.set_ticklabels([])
fig.tight_layout()
请注意,这段代码主要是用于绘制包含4个子图(每个子图都是pcolormesh以及其相关colorbar)的图表。此外,您还提到了希望减少pcolormesh和colorbars之间的大间隙,以及使用fig.tight_layout()
和gridspec
中的width_ratios
来实现这一目标。
英文:
I have a dataset that I want to plot as 4 panels (each a pcolormesh with its associated colorbar). This is the code I'm using to do this, with some mocked up data
import numpy as np
import matplotlib.pyplot as plt
from matplotlib import gridspec
xs = np.linspace(0.1, 0.2, 100)
ys = np.linspace(0, 2*np.pi*0.1, 400)
x_mesh, y_mesh = np.meshgrid(xs, ys)
# mocked up data arrays
A = np.full_like(x_mesh, 1.0)
B = np.full_like(x_mesh, 1.0)
C = np.full_like(x_mesh, 1.0)
D = np.full_like(x_mesh, 1.0)
fig = plt.figure()
gs = gridspec.GridSpec(nrows = 2, ncols = 4, height_ratios = (0.5, 0.5), width_ratios = (0.45, 0.05, 0.45, 0.05))
ax0 = fig.add_subplot(gs[0,0])
ax0_cbar = fig.add_subplot(gs[0,1])
ax1 = fig.add_subplot(gs[0,2])
ax1_cbar = fig.add_subplot(gs[0,3])
ax2 = fig.add_subplot(gs[1,0])
ax2_cbar = fig.add_subplot(gs[1,1])
ax3 = fig.add_subplot(gs[1,2])
ax3_cbar = fig.add_subplot(gs[1,3])
a = ax0.pcolormesh(x_mesh/1.0e-2, y_mesh/1.0e-2, A, \
shading = 'auto')
cb1 = plt.colorbar(a, cax=ax0_cbar)
cb1.set_label(r"A")
b = ax1.pcolormesh(x_mesh/1.0e-2, y_mesh/1.0e-2, B, \
shading = 'auto')
cb1 = plt.colorbar(b, cax=ax1_cbar)
cb1.set_label(r"B")
c = ax2.pcolormesh(x_mesh/1.0e-2, y_mesh/1.0e-2, C, \
shading = 'auto')
cb1 = plt.colorbar(c, cax=ax2_cbar)
cb1.set_label(r"C")
d = ax3.pcolormesh(x_mesh/1.0e-2, y_mesh/1.0e-2, D, \
shading = 'auto')
cb1 = plt.colorbar(d, cax=ax3_cbar)
cb1.set_label(r"D")
ax0.xaxis.set_ticklabels([])
ax1.xaxis.set_ticklabels([])
fig.tight_layout()
But when I actually do this, I find that there are really large gaps between the pcolormesh and the colorbars that are really unappealing (picture attached). How can I reduce these? I though I would be able to do it with fig.tight_layout()
and width_ratios
in gridspec
答案1
得分: 1
您不需要为颜色条添加新的轴元素,只需使用ax关键字参数来为每个子图指定颜色条。matplotlib文档显示,使用ax将产生从父轴ax中获取的颜色条轴(https://matplotlib.org/stable/api/_as-gen/matplotlib.pyplot.colorbar.html)。文档应该是您的首要参考,始终如此!
这里我为您编写了一个可工作的代码版本:
import numpy as np
import matplotlib.pyplot as plt
from matplotlib import gridspec
xs = np.linspace(0.1, 0.2, 100)
ys = np.linspace(0, 2*np.pi*0.1, 400)
x_mesh, y_mesh = np.meshgrid(xs, ys)
# 模拟数据数组
A = np.full_like(x_mesh, 1.0)
B = np.full_like(x_mesh, 1.0)
C = np.full_like(x_mesh, 1.0)
D = np.full_like(x_mesh, 1.0)
fig = plt.figure(figsize=(6,4))
gs = gridspec.GridSpec(nrows=2, ncols=2, height_ratios=(0.5, 0.5), width_ratios=(0.5, 0.5))
ax0 = fig.add_subplot(gs[0,0])
ax1 = fig.add_subplot(gs[0,1])
ax2 = fig.add_subplot(gs[1,0])
ax3 = fig add_subplot(gs[1,1])
a = ax0.pcolormesh(x_mesh/1.0e-2, y_mesh/1.0e-2, A, shading='auto')
cb1 = plt.colorbar(a, ax=ax0)
cb1.set_label("A")
b = ax1.pcolormesh(x_mesh/1.0e-2, y_mesh/1.0e-2, B, shading='auto')
cb1 = plt.colorbar(b, ax=ax1)
cb1.set_label("B")
c = ax2.pcolormesh(x_mesh/1.0e-2, y_mesh/1.0e-2, C, shading='auto')
cb1 = plt.colorbar(c, ax=ax2)
cb1.set_label("C")
d = ax3.pcolormesh(x_mesh/1.0e-2, y_mesh/1.0e-2, D, shading='auto')
cb1 = plt.colorbar(d, ax=ax3)
cb1.set_label("D")
ax0.xaxis.set_ticklabels([])
ax1.xaxis.set_ticklabels([])
fig.tight_layout()
plt.show()
祝您编程愉快!
英文:
You don't require new axes elements for your colorbars, simply use the ax keyword argument to specify the colorbars for each subplot. The matplotlib documentation shows that using ax will produce a colorbar axis stolen from the parent axes ax (https://matplotlib.org/stable/api/_as_gen/matplotlib.pyplot.colorbar.html). The documentation should be your first port of call, always!
Here I have written a working version of your code:
import numpy as np
import matplotlib.pyplot as plt
from matplotlib import gridspec
xs = np.linspace(0.1, 0.2, 100)
ys = np.linspace(0, 2*np.pi*0.1, 400)
x_mesh, y_mesh = np.meshgrid(xs, ys)
# mocked up data arrays
A = np.full_like(x_mesh, 1.0)
B = np.full_like(x_mesh, 1.0)
C = np.full_like(x_mesh, 1.0)
D = np.full_like(x_mesh, 1.0)
fig = plt.figure(figsize=(6,4))
gs = gridspec.GridSpec(nrows = 2, ncols = 2, height_ratios = (0.5, 0.5), width_ratios = (0.5, 0.5))
ax0 = fig.add_subplot(gs[0,0])
ax1 = fig.add_subplot(gs[0,1])
ax2 = fig.add_subplot(gs[1,0])
ax3 = fig.add_subplot(gs[1,1])
a = ax0.pcolormesh(x_mesh/1.0e-2, y_mesh/1.0e-2, A, \
shading = 'auto')
cb1 = plt.colorbar(a, ax=ax0)
cb1.set_label(r"A")
b = ax1.pcolormesh(x_mesh/1.0e-2, y_mesh/1.0e-2, B, \
shading = 'auto')
cb1 = plt.colorbar(b, ax=ax1)
cb1.set_label(r"B")
c = ax2.pcolormesh(x_mesh/1.0e-2, y_mesh/1.0e-2, C, \
shading = 'auto')
cb1 = plt.colorbar(c, ax=ax2)
cb1.set_label(r"C")
d = ax3.pcolormesh(x_mesh/1.0e-2, y_mesh/1.0e-2, D, \
shading = 'auto')
cb1 = plt.colorbar(d, ax=ax3)
cb1.set_label(r"D")
ax0.xaxis.set_ticklabels([])
ax1.xaxis.set_ticklabels([])
fig.tight_layout()
plt.show()
Happy coding
答案2
得分: 0
The approach above is correct. It can break down if you have equal aspect axes, for which you can now use layout='compressed'
for simple cases to remove white space:
fig, axs = plt.subplots(2, 2, layout='compressed', figsize=(6, 3))
for ax in axs.flat:
pc = ax.pcolormesh(np.random.randn(10, 10))
ax.set_aspect(1)
fig.colorbar(pc, ax=ax)
plt.show()
See also: https://matplotlib.org/stable/gallery/subplots_axes_and_figures/colorbar_placement.html
英文:
The approach above is correct. It can break down if you have equal aspect axes, for which you can now use layout='compressed'
for simple cases to remove white space:
fig, axs = plt.subplots(2, 2, layout='compressed', figsize=(6, 3))
for ax in axs.flat:
pc = ax.pcolormesh(np.random.randn(10, 10))
ax.set_aspect(1)
fig.colorbar(pc, ax=ax)
plt.show()
See also: https://matplotlib.org/stable/gallery/subplots_axes_and_figures/colorbar_placement.html
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论