【问题标题】:Matplotlib 2 y axis with meanMatplotlib 2 y轴与平均值
【发布时间】:2026-02-02 16:40:01
【问题描述】:

您好,我一直在试图弄清楚如何将我的数据框绘制到图表中。我的数据框看起来像这样。

Country | exports 2015 | exports 2016 | Gdp 2015 | GDP 2016| 
  A     |     500      |     600      |   34324  |  23525  | 
  B     |     435      |     335      |    3243  |   2324  |
  C     |     222      |     324      |    23423 |   1233  | 
  D     |     7756     |     9000     |    32424 |  65545  | 

基本上,我想比较所有列的平均值并将它们绘制在一个图表上,其中 1 x 轴作为年份,2 y 轴作为出口和 GDP。我只能做1年。基本上我想得到 ​​p>

         |                                    |
         |                                    |
         |                                    |
 Mean    |                                    |
Exports  |                                    | Mean GDP
         |                                    |
         |                                    |
         |____________________________________|  
              2015                  2016

在绘制图表时我是否需要以某种方式将数据转换为平均值,或者我是否需要做另一列?任何建议都会非常感谢:)

【问题讨论】:

  • 您基本上是在问如何在图中使用两个 y 轴。 Hereherehere 是可以解决您问题的众多链接中的一部分。您只需要在 DataFrames 中搜索计算均值。我也可以提供他们的链接,但我想你明白了。我投票决定将此问题作为重复问题结束。
  • Herehere 是另外两个链接
  • 这看起来像两个问题,一个是pandas 问题,一个是matplotlib 问题。分开可能会更好。也将使搜索答案(使用 google 和 site:*.com)更容易。
  • Hereherehere 是一些关于如何计算 pandas 平均值的链接

标签: python pandas numpy matplotlib


【解决方案1】:

这是一种可能的解决方案,使用pandas。唯一的困难是设置图例位置,因为您必须为每个 y 轴设置标签。请记住,双轴图非常令人困惑。

import pandas as pd
import matplotlib.pyplot as plt


# Stacked input data 
df = pd.DataFrame({'Country': ['A','B', 'C', 'D','A','B', 'C', 'D'],
                   'Year': ['2015','2015','2015','2015','2016','2016','2016','2016'],
                   'Export': [500, 435, 222, 7756,600, 335, 324, 9000],
                   'GDP': [34324, 3243, 23423, 32424,23525, 2324, 1233, 65545]})

# Calculate yearly means
year_means = df.groupby('Year').mean().reset_index()

# Plot the means
ax = year_means.plot(x='Year',
                     y=['Export', 'GDP'],
                     secondary_y= 'GDP',
                     kind= 'bar',
                     mark_right=False)

#Set labels
ax.set_ylabel('Exports')
ax.right_ax.set_ylabel('GDP')

# Adjust legend position
ax.legend(bbox_to_anchor=(1,1), loc="upper left")
ax.right_ax.legend(bbox_to_anchor=(1.2,1), loc="upper left")

plt.show()

编辑: OP 没有堆叠的输入数据。解决它的一种方法是单独转换变量,然后将它们组合成单帧。以下解决方案远非最佳。

# Not stacked input data 
df = pd.DataFrame({'Country': ['A','B', 'C', 'D'],
                   'Export 2015': [500, 435, 222, 7756],
                   'Export 2016': [600, 335, 324, 9000],
                   'GDP 2015': [34324, 3243, 23423, 32424],
                   'GDP 2016': [23525, 2324, 1233, 65545]})


def stack_variable(df, variable):

    # Get columns of the input dataframe
    names = df.columns

    # Get column names with variable of interest
    var_columns = [name for name in names if variable in name]

    # Extract years
    years = [y.split(variable + ' ')[1] for y in var_columns]

    # Empty dataframe to store results
    stacked_df = pd.DataFrame(columns = [variable, 'Year'])

    # Fill the empty frame
    for idx, col in enumerate(var_columns):
             current = pd.DataFrame({variable: df[col],
                                     'Year': years[idx]})

             stacked_df = stacked_df.append(current)



    return stacked_df


exports = stack_variable(df, 'Export')
gdp = stack_variable(df, 'GDP')

stacked_df = pd.concat([exports, gdp['GDP']], axis=1).reset_index(drop=True)

哪个会返回:

stacked_df

       Export   Year    GDP
    0   500     2015    34324
    1   435     2015    3243
    2   222     2015    23423
    3   7756    2015    32424
    4   600     2016    23525
    5   335     2016    2324
    6   324     2016    1233
    7   9000    2016    65545

【讨论】:

  • 我明白你的意思。但是,我的数据框与我上面的问题中显示的完全一样。我不能让它正确堆叠,因为它们有不同的列名?例如 GDP 2015 和 GDP 2016。这是因为我也从 csv 文件中读取它
  • 显示一些主动性,您可能可以调整 csv 文件或编写简单的函数来做到这一点...查看我的编辑。