python - Matplotlib 将多条折线图绘制成一个轴
问题描述
我对 Matplotlib 很陌生,似乎我不明白如何用自定义的 x,y 轴绘制图形。我有一个数据框(请求的 csv 文件),每天有 2 个元素(时间)。我想使用一个 x 轴成对地绘制元素。这是我的代码:
#creating an example dataframe
low = ['08:20','11:50','09:44','11:12']
high = ['10:45','08:05','11:55','09:10']
low = pd.to_datetime(low).time
high = pd.to_datetime(high).time
col_name = ['lowtide','hightide']
ind_val = pd.date_range(start='01-01-2021',periods=4)
df = pd.DataFrame(data= zip(low,high),columns=col_name,index=ind_val)
print(df)
lowtide hightide
2021-01-01 08:20:00 10:45:00
2021-01-02 11:50:00 08:05:00
2021-01-03 09:44:00 11:55:00
2021-01-04 11:12:00 09:10:00
在 x 轴上应该有一个时间线,而 y 轴只有低潮和高潮点。我转置了 DataFrame,因为我不知道如何按行绘制并将 column.names 用作 y 轴值并将每个元素设置为 dtype=str,因为 Matplotlib 争论使用 datetime 对象。
#transpose df for plotting because I don't know how to plot row wise
tides = df.T
print(tides)
2021-01-01 2021-01-02 2021-01-03 2021-01-04
lowtide 08:20:00 11:50:00 09:44:00 11:12:00
hightide 10:45:00 08:05:00 11:55:00 09:10:00
#because of errors while trying to plot I convert all into str
tides = tides.astype(str)
my_xaxis=pd.date_range(start='08:00',end='12:00',freq='5min').time
fig,ax = plt.subplots()
plt.xticks(range(len(my_xaxis)), my_xaxis, rotation='vertical')
plt.yticks(range(len(tides.index)),tides.index)
for column in tides.columns:
plt.plot(tides[column],tides.index)
我想得到的是:
我很感激任何帮助
解决方案
您应该以这种方式重新塑造您的数据框(也许有一种更简单的重新塑造我不知道的方法):
df = df.reset_index()\
.melt(id_vars = 'index', var_name = 'tide', value_name = 'time')\
.set_index('time').pivot(columns = 'index', values = 'tide')\
.replace({'lowtide': 0, 'hightide': 1})
df.index = df.index.map(lambda x: datetime(year = 2021, month = 1, day = 1,
hour = x.hour, minute = x.minute, second = x.second))
所以你有了:
index 2021-01-01 2021-01-02 2021-01-03 2021-01-04
time
2021-01-01 08:05:00 NaN 1.0 NaN NaN
2021-01-01 08:20:00 0.0 NaN NaN NaN
2021-01-01 09:10:00 NaN NaN NaN 1.0
2021-01-01 09:44:00 NaN NaN 0.0 NaN
2021-01-01 10:45:00 1.0 NaN NaN NaN
2021-01-01 11:12:00 NaN NaN NaN 0.0
2021-01-01 11:50:00 NaN 0.0 NaN NaN
2021-01-01 11:55:00 NaN NaN 1.0 NaN
现在您可以绘制:
fig, ax = plt.subplots()
for col in df.columns:
df[~df[col].isna()][col].plot(label = col.date())
ax.legend(frameon = True)
ax.set_yticks([0, 1])
ax.set_yticklabels(['lowtide', 'hightide'])
ax.xaxis.set_major_locator(md.MinuteLocator(interval = 10))
ax.xaxis.set_major_formatter(md.DateFormatter('%H:%M:%S'))
plt.setp(ax.xaxis.get_majorticklabels(), rotation = 90)
plt.tight_layout()
plt.show()
完整代码
import pandas as pd
import matplotlib.pyplot as plt
import matplotlib.dates as md
from datetime import datetime
low = ['08:20','11:50','09:44','11:12']
high = ['10:45','08:05','11:55','09:10']
low = pd.to_datetime(low).time
high = pd.to_datetime(high).time
col_name = ['lowtide','hightide']
ind_val = pd.date_range(start='01-01-2021',periods=4)
df = pd.DataFrame(data= zip(low,high),columns=col_name,index=ind_val)
df = df.reset_index()\
.melt(id_vars = 'index', var_name = 'tide', value_name = 'time')\
.set_index('time').pivot(columns = 'index', values = 'tide')\
.replace({'lowtide': 0, 'hightide': 1})
df.index = df.index.map(lambda x: datetime(year = 2021, month = 1, day = 1,
hour = x.hour, minute = x.minute, second = x.second))
fig, ax = plt.subplots()
for col in df.columns:
df[~df[col].isna()][col].plot(label = col.date())
ax.legend(frameon = True)
ax.set_yticks([0, 1])
ax.set_yticklabels(['lowtide', 'hightide'])
ax.xaxis.set_major_locator(md.MinuteLocator(interval = 10))
ax.xaxis.set_major_formatter(md.DateFormatter('%H:%M:%S'))
plt.setp(ax.xaxis.get_majorticklabels(), rotation = 90)
plt.tight_layout()
plt.show()
推荐阅读
- visual-studio - 通过快捷键在解决方案资源管理器中使用相对路径打开文件
- css - 如何在 css 中创建 3d 堆叠长方体
- blazor-webassembly - 无法在启用热重载功能的情况下运行 blazor 程序集项目(.net 6 预览版 5)
- smtp - SAP Hybris SMTP 已配置,但邮件输入欺诈报告而不是创建新票证
- react-native - 如何在 react-navigation 4 中导航到选项卡内的新屏幕
- electron - 在 Electron 应用程序中运行 cli 命令找不到代码命令
- php - 如何获取 PSID Facebook 信使
- python - 运行 linux 可执行文件时出错使 bu pyinstaller
- c# - Microsoft Bot C# SDK 在使用自适应卡片附件的 WaterfallStepContext 期间从卡片提交操作中获取错误
- python - Doc2Vec __init__() 有一个意外的关键字参数“大小”