我想在 python 中使用 matplotlib.pyplot 在子图中绘制数据。每个子图将包含不同范围的数据。我想使用 pyplot.scatter 绘制它们,并为整个绘图使用一个颜色条。因此,颜色条应包含每个子图中的整个值范围。但是,当我使用循环绘制子图并在循环外调用颜色条时,它仅使用最后一个子图的值范围。许多可用示例都涉及颜色条位置的大小调整,因此这个答案(如何为多个子图制作一个通用颜色条)并不明显。
我有以下独立的示例代码。在这里,渲染了两个子图,一个用俄罗斯典型的寒冷温度着色,另一个用巴西的热带温度着色。但是,最终结果显示的颜色条仅涵盖巴西热带地区的温度,从而导致俄罗斯子图错误:
import numpy as np
import pandas as pd
import matplotlib.pyplot as plt
core_list = ['Russia', 'Brazil']
core_depth = [0, 2, 4, 6, 8, 10]
lo = [-33, 28]
hi = [10, 38]
df = pd.DataFrame([], columns = ['Location', 'Depth', '%TOC', 'Temperature'])
#Fill df
for ii, name in enumerate(core_list):
for jj in core_depth:
df.loc[len(df.index)] = [name, jj, (np.random.randint(1, 20))/10, np.random.randint(lo[ii], hi[ii])]
#Russia data have much colder temperatures than Brazil data due to hi and lo
#Plot data from each location using scatter plots
fig, axs = plt.subplots(nrows = 1, ncols = 2, sharey = True)
for nn, name in enumerate(core_list):
core_mask = df['Location'] == name
data = df.loc[core_mask]
plt.sca(axs[nn])
plt.scatter(data['Depth'], data['%TOC'], c = data['Temperature'], s = 50, edgecolors = 'k')
axs[nn].set_xlabel('%TOC')
plt.text(1.25*min(data['%TOC']), 1.75, name)
if nn == 0:
axs[nn].set_ylabel('Depth')
cbar = plt.colorbar()
cbar.ax.set_ylabel('Temperature, degrees C')
#How did Russia get so warm?!? Temperatures and ranges of colorbar are set to last called location.
#How do I make one colorbar encompass global temperature range of both data sets?
我们凭直觉知道,从数据来看,这是错误的。那么,我们如何告诉 pyplot 正确绘制它?
答案 0 :(得分:1)
使用 pyplot.scatter
的 vmax 和 vmin 控件,答案很简单。这些必须使用通用范围的数据进行设置,而不仅仅是在循环的任何一次迭代中关注的数据。因此,要更改上面的代码:
import numpy as np
import pandas as pd
import matplotlib.pyplot as plt
core_list = ['Russia', 'Brazil']
core_depth = [0, 2, 4, 6, 8, 10]
lo = [-33, 28]
hi = [10, 38]
df = pd.DataFrame([], columns = ['Location', 'Depth', '%TOC', 'Temperature'])
#Fill df
for ii, name in enumerate(core_list):
for jj in core_depth:
df.loc[len(df.index)] = [name, jj, (np.random.randint(1, 20))/10, np.random.randint(lo[ii], hi[ii])]
#Russia data have much colder temperatures than Brazil data due to hi and lo
#Plot data from each location using scatter plots
fig, axs = plt.subplots(nrows = 1, ncols = 2, sharey = True)
for nn, name in enumerate(core_list):
core_mask = df['Location'] == name
data = df.loc[core_mask]
plt.sca(axs[nn])
plt.scatter(data['Depth'], data['%TOC'], c = data['Temperature'], s = 50, edgecolors = 'k', vmax = max(df['Temperature']), vmin = min(df['Temperature']))
axs[nn].set_xlabel('%TOC')
plt.text(1.25*min(data['%TOC']), 1.75, name)
if nn == 0:
axs[nn].set_ylabel('Depth')
cbar = plt.colorbar()
cbar.ax.set_ylabel('Temperature, degrees C')
现在,输出显示了俄罗斯和巴西之间的温差,这是粗略浏览数据后的预期结果。修复此问题的更改发生在 for 循环中,但它引用所有数据以查找最大值和最小值:
plt.scatter(data['Depth'], data['%TOC'], c = data['Temperature'], s = 50, edgecolors = 'k',
vmax = max(df['Temperature']), vmin = min(df['Temperature']) )