我正在嘗試繪制有關一堆設備的資料,無論它們是在線還是離線。設備在線時發出信號 1,離線時發出信號 0。中間沒有資料。
對于一個設備,我使用階梯圖(step=post),效果很好。現在我想在一個或多個設備在線時顯示一行。
有沒有人有關于如何可視化這個資料集的任何提示/技巧?我嘗試在每個信號之前添加額外的行以獲得更連續的資料集,然后繪制 OnOff 的值,但隨后我丟失了類別。我需要將其轉換為 broken_barh 圖嗎?還是有其他想法?

資料:
import pandas as pd
import matplotlib.pyplot as plt
TESTDATA = u"""\
Index;OnOff;Device
12-10-2021 10:04:04;1;device1
12-10-2021 10:04:12;0;device3
12-10-2021 10:05:05;1;device2
12-10-2021 19:05:11;0;device2
13-10-2021 05:25:17;1;device2
13-10-2021 19:26:22;0;device2
14-10-2021 15:44:44;1;device2
14-10-2021 20:54:12;0;device2
15-10-2021 04:21:42;1;device2
15-10-2021 09:15:11;0;device2
15-10-2021 17:05:05;0;device1
15-10-2021 17:05:25;1;device3
15-10-2021 17:56:45;1;device1
15-10-2021 17:57:09;1;device2
15-10-2021 21:10:20;0;device2
16-10-2021 01:51:50;1;device2
19-10-2021 10:00:13;0;device1
19-10-2021 10:04:19;0;device2
"""
df = pd.read_csv(StringIO(TESTDATA), index_col=0, sep=';', engine='python')
df.index = pd.to_datetime(df.index, format='%d-%m-%Y %H:%M:%S')
print(df)
# plot
fig, ax = plt.subplots(figsize=[16,9])
devices = list(set(df['Device']))
devices.sort(reverse=True)
for device in devices:
ax.plot(df.index[df['Device'] == device], df['Device'][df['Device'] == device], label=device)
plt.show()
uj5u.com熱心網友回復:
問題出在 ax.plot 引數中。ax.plot 需要 x 和 y,例如 ax.plot(x, y) 你的 x, y 是: x - df.index[df['Device'] == device]- 這是正確的 y - df['Device'][df['Device'] == device- 這是不正確的
更改
df['Device'][df['Device'] == device
為
df.loc[df['Device'] == device, 'OnOff']
df.loc 通過過濾行和列來作業:
df.loc[row_filter, column_filter]
row_filter = df['Device'] == device # give me all rows whre 'Device' column's value == device variable value
column_filter = 'OnOff' # give me just the OnOff column
您將看到的圖表可能不是您想要的。

您可能希望將 替換為ax.plot以ax.step查看以下內容,但資料會重疊并且不會太重:

最終的解決方案可能是在共享 x 軸上繪制 3 個軸,每個設備 1 個軸:
# plot
fig, axs = plt.subplots(3,1, figsize=[16,9], sharex=True)
devices = list(set(df['Device']))
devices.sort(reverse=True)
for device_idx, device in enumerate(devices):
axs[device_idx].step(df.index[df['Device'] == device], df.loc[df['Device'] == device, 'OnOff'] , label=device )

uj5u.com熱心網友回復:
Datetime 物件的行為確實很困難,因為并非所有 pandas/numpy/matplotlib 函式都接受所有版本或可能以不同方式解釋它們。但是,我們可以將
大多數代碼只是處理原始資料幀未明確宣告開頭或結尾狀態的情況所必需的。但是,狀態為 1 和 0 使得編碼更容易,因為它可以直接轉換為索引。
PS 設備 3 的第一條在原始圖中可見,但在存盤在 SO 上的下采樣影像中不可見。
uj5u.com熱心網友回復:
# first I would assume that all devices have to start from the unknow state, instead of assuming they are off,
# thus lets add one row at the begining
new_index_first_element = df.index[0]-pd.Timedelta(seconds=1)
new_index = [new_index_first_element] df.index.to_list()
devices = sorted(df.Device.unique())
# lets create a new dataframe where each device will have its own column and
# each entry will track the state of each device
df2 = pd.DataFrame(index = new_index, columns=devices)
for i_iloc in range(1,len(df2)): # i have to be able to reffer to previous row, thus I will go with iloc, instead of loc
# first copy previous status of all devices to current row
df2.iloc[i_iloc] = df2.iloc[i_iloc-1]
# now lets update the status for device that changed
current_row_idx = df2.iloc[[i_iloc]].index
device_to_update = df.loc[current_row_idx, 'Device']
status_to_update = df.loc[current_row_idx, 'OnOff']
df2.at[current_row_idx, device_to_update] = status_to_update
df2

這就是 DF 的樣子,它有一個帶有 NaN 的附加行,因為我們不知道這些設備的狀態是什么。
# and plot
fig, ax = plt.subplots(figsize=[16,9])
df2.plot(kind='bar', stacked=True, color=['red', 'skyblue', 'green'], ax=ax)

我不認為在這里繪制一個“broken_barh 圖”會做得很好,這個堆疊的條形圖會更好。
轉載請註明出處,本文鏈接:https://www.uj5u.com/houduan/445143.html
標籤:Python 熊猫 matplotlib
