python - 绘制从同一图形 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
带有标记的绘图,但在单独的图表上。如何将两个图表放在一个图表中以更好地比较它们?
谢谢。
解决方案
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.Axes
using plt.subplots()
. 然后使用该轴元素在其上绘制所有线。特别注意ax=ax
in 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)]
推荐阅读
- node.js - 理解 NodeJS 中 require 的行为
- laravel - 带有分组前缀的 nuxt 的 Laravel 7 cors 问题
- c++ - soci 给出致命错误:mysql.h:没有这样的文件或目录
- javascript - BrowserWindow 控制台中的安全警告(电子^9.2.0)
- database - 从 Oracle 数据库向其他应用程序发送增量数据:- 即使是很小的建议也会很有帮助
- javascript - 为什么排序会立即完成?
- git - Azure DevOps ,git fetch failed with exit code 128,fatal:Authentication failed for
- java - When we use this type of syntax :- int a[]=new int[3<<1];
- python - 如何在 Tkinter 中强制注意弹出窗口
- angular - Common object change in all component when one of them edit it