【问题标题】:Plotting multiple columns on the same figure using pandas使用熊猫在同一个图形上绘制多列
【发布时间】:2021-07-14 02:13:01
【问题描述】:

我正在尝试使用 pandas 和 matplotlib 在同一张图上绘制多条不同的线。

我有一系列 100 条合成温度历史记录,我想绘制这些历史记录,全部为灰色,与我用来生成数据的原始真实温度历史记录相对应。

如何在同一张图表上绘制所有这些系列?我知道如何在 MATLAB 中执行此操作,但我在该项目中使用 Python,并且 Pandas 是我发现从输出文件中读取每一列而无需单独指定每一列的最简单方法。数据的列数将从 100 变为 1000,所以我需要一个通用的解决方案。我的代码单独绘制了每个数据系列,但我只需要弄清楚如何将它们都添加到同一个图中。

这是目前为止的代码:

# dirPath is the path to my working directory
outputFile = "output.csv"
original_data = "temperature_data.csv"

# Read in the synthetic temperatures from the output file, time is the index in the first column
data = pd.read_csv(outputFile,header=None, skiprows=1, index_col=0)

# Read in the original temperature data, time is the index in the first column
orig_data = pd.read_csv(dirPath+original_data,header=None, skiprows=1, index_col=0)

# Convert data to float format
data = data.astype(float)
orig_data = orig_data.astype(float)

# Plot all columns of synthetic data in grey
data = data.plot.line(title="ARMA Synthetic Temperature Histories",
                        xlabel="Time (yrs)",
                        ylabel=("Synthetic avergage hourly temperature (C)"),
                        color="#929591",
                        legend=None)

# Plot one column of original data in black
orig_data = orig_data.plot.line(color="k",legend="Original temperature data")

# Create and save figure
fig = data.get_figure()
fig = orig_data.get_figure()
fig.savefig("temp_arma.png")

这是输出数据的一些示例数据:

这是原始数据:

单独绘制每个图表会给出这些图表 - 我只是希望它们叠加!

【问题讨论】:

    标签: python pandas


    【解决方案1】:

    您的 data.plot.line 返回一个 AxesSubplot 实例,您可以捕获它并将其提供给您的第二个命令:

    # plot 1
    ax = data.plot.line(…)
    
    # plot 2
    data.plot.line(…, ax=ax)
    

    尝试运行这段代码:

    # convert data to float format
    data = data.astype(float)
    orig_data = orig_data.astype(float)
    
    # Plot all columns of synthetic data in grey
    ax = data.plot.line(title="ARMA Synthetic Temperature Histories",
                        xlabel="Time (yrs)",
                        ylabel=("Synthetic avergage hourly temperature (C)"),
                        color="#929591",
                        legend=None)
    
    # Plot one column of original data in black
    
    
    orig_data.plot.line(color="k",legend="Original temperature data", ax=ax)
    
    # Create and save figure
    ax.figure.savefig("temp_arma.png")
    

    【讨论】:

    • 这样做会给我错误“AttributeError: 'DataFrame' object has no attribute 'get_figure'”
    • 为什么要用变量“data”来捕捉data.plot.line(...)的返回? pandas.DataFrame.plot.line 返回一个 matplotlib.axes.Axes 对象。您可以尝试运行我编辑的答案中的代码吗?
    【解决方案2】:

    您应该直接使用matplotlib 函数。它提供了更多的控制,并且易于使用。

    第 1 部分 - 读取文件(借用您的代码)

    # Read in the synthetic temperatures from the output file, time is the index in the first column
    data = pd.read_csv(outputFile,header=None, skiprows=1, index_col=0)
    
    # Read in the original temperature data, time is the index in the first column
    orig_data = pd.read_csv(dirPath+original_data,header=None, skiprows=1, index_col=0)
    
    # Convert data to float format
    data = data.astype(float)
    orig_data = orig_data.astype(float)
    

    第 2 部分 - 绘图

    fig = plt.figure(figsize=(10,8))
    ax = plt.gca()
    
    # Plotting all histories:
    # 1st column contains time hence excluding
    for col in data.columns[1:]:
        ax.plot(data["Time"], data[col], color='grey')
    
    # Orig
    ax.plot(orig_data["Time"], orig_data["Temperature"], color='k')
    
    # axis labels
    ax.set_xlabel("Time (yrs)")
    ax.set_ylabel("avergage hourly temperature (C)")
    
    fig.savefig("temp_arma.png")
    

    【讨论】:

      【解决方案3】:

      尝试以下方法:

      import matplotlib.pyplot as plt
      
      fig, ax = plt.subplots()
      data.plot.line(ax=ax,
                     title="ARMA Synthetic Temperature Histories",
                     xlabel="Time (yrs)",
                     ylabel="Synthetic avergage hourly temperature (C)",
                     color="#929591",
                     legend=False)
      orig_data.rename(columns={orig_data.columns[0]: "Original temperature data"},
                       inplace=True)
      orig_data.plot.line(ax=ax, color="k")
      

      这几乎是您的原始代码,稍作修改:

      获取ax 对象

      fig, ax = plt.subplots()
      

      并将其用于绘图

      data.plot.line(ax=ax, ...
      ...
      orig_data.plot.line(ax=ax, ...)
      

      一些随机生成的样本数据的结果:

      import random  # For sample data only
      
      # Sample data
      data = pd.DataFrame({
          f'col_{i}': [random.random() for _ in range(25)]
          for i in range(1, 50)
      })
      orig_data = pd.DataFrame({
          'col_0': [random.random() for _ in range(25)]
      })
      

      【讨论】:

        猜你喜欢
        • 2022-01-20
        • 1970-01-01
        • 2021-06-16
        • 1970-01-01
        • 2021-07-25
        • 1970-01-01
        相关资源
        最近更新 更多