首页 > 解决方案 > 绘制从同一图形 Python 中的循环获得的两个数据帧

问题描述

我想dfs用两种不同的颜色绘制两个。对于每个df,我需要添加两个标记。这是我尝试过的:

for stats_file in stats_files:
    data = Graph(stats_file)
    Graph.compute(data)
    data.servers_df.plot(x="time", y="percentage", linewidth=1, kind='line')
    plt.plot(data.first_measurement['time'], data.first_measurement['percentage'], 'o-', color='orange')
    plt.plot(data.second_measurement['time'], data.second_measurement['percentage'], 'o-', color='green')
plt.show()

使用这段代码,我得到了servers_df带有标记的绘图,但在单独的图表上。如何将两个图表放在一个图表中以更好地比较它们?

谢谢。

标签: pythonpandasdataframematplotlibplot

解决方案


TL;博士

您要求data.servers_df.plot()总是创建一个新的情节,并plt.plot()在已创建的最新情节上绘制。解决方案是为要绘制的所有内容创建专用轴。

前言

我假设你的变量如下

  • data.servers_df:具有两个浮点列的数据框"time""percentage"
  • data.first_measurements:带有键"time"和“百分比”的字典,每个都是浮点数列表
  • data.second_measurements: 带有键"time"和的字典"percentage",每个都是浮点数列表

我跳过了生成stat_files,因为您没有显示做什么Graph(),只是创建了一个 dummy 列表data

如果data.first_measurements并且data.second_measurements也是数据框,请告诉我,还有更好的解决方案。

理论——幕后

每个matplotlib图(线、条等)都存在于一个matplotlib.axes.Axes元素上。这些就像坐标系的规则轴。现在这里发生了两件事:

  • 当您使用plt.plot()时,没有指定轴,因此,matplotlib 查找当前轴元素(在后台),如果没有,它将创建一个空的并使用它,并设置为默认值。第二次调用plt.plot()then 找到这些轴并使用它们。
  • DataFrame.plot()另一方面,如果没有给它,总是创建一个新的轴元素(可能通过ax参数)

因此,在您的代码中,data.servers_df.plot()首先在窗帘后面创建一个轴元素(然后是默认值),然后以下两个plt.plot()调用获取默认轴并在其上绘制 - 这就是为什么您得到两个图而不是一个的原因。

解决方案

以下解决方案首先创建一个专用的matplotlib.axes.Axesusing plt.subplots(). 然后使用该轴元素在其上绘制所有线。特别注意ax=axin data.server_df.plot()。请注意,我将标记的显示从更改o-o(因为我们不想显示线 ( -) 而只显示标记 ( o))。模拟数据可以在下面找到

fig, ax = plt.subplots()  # Here we create the axes that all data will plot onto
for i, data in enumerate(stat_files):
    y_column = f'percentage_{i}'  # Make the columns identifiable
    data.servers_df \
        .rename(columns={'percentage': y_column}) \
        .plot(x='time', y=y_column, linewidth=1, kind='line', ax=ax)
    ax.plot(data.first_measurement['time'], data.first_measurement['percentage'], 'o', color='orange')
    ax.plot(data.second_measurement['time'], data.second_measurement['percentage'], 'o', color='green')
plt.show()

在此处输入图像描述

模拟数据

import random

import pandas as pd
import matplotlib.pyplot as plt

# Generation of dummy data
random.seed(1)
NUMBER_OF_DATA_FILES = 2
X_LENGTH = 10


class Data:
    def __init__(self):
        self.servers_df = pd.DataFrame(
            {
                'time': range(X_LENGTH),
                'percentage': [random.randint(0, 10) for _ in range(X_LENGTH)]
            }
        )
        self.first_measurement = {
            'time': self.servers_df['time'].values[:X_LENGTH // 2],
            'percentage': self.servers_df['percentage'].values[:X_LENGTH // 2]
        }
        self.second_measurement = {
            'time': self.servers_df['time'].values[X_LENGTH // 2:],
            'percentage': self.servers_df['percentage'].values[X_LENGTH // 2:]
        }


stat_files = [Data() for _ in range(NUMBER_OF_DATA_FILES)]

推荐阅读