为不同范围的多个matplotlib子批次设置“全局”颜色栏范围

2024-09-26 22:45:31 发布

您现在位置:Python中文网/ 问答频道 /正文

我想在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?

该代码的输出显示巴西和俄罗斯的温度在相同的颜色范围内: enter image description here

通过浏览数据,我们直觉地知道这是错误的。那么,我们如何让pyplot正确地绘制这个呢


Tags: 数据namecoredfdata颜色绘制plt
1条回答
网友
1楼 · 发布于 2024-09-26 22:45:31

答案很简单,使用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']))

enter image description here

相关问题 更多 >

    热门问题