python - Matplotlib:在 2 点之间绘制一条线……但以一种不寻常的方式
问题描述
我正在学习使用 Matplotlib 可视化数据,我想以非常定制的方式绘制一条线。我是 Matplotlib 的新手,我不知道我想做的事情是否可行。开始:
设置:假设您有一组用于折线图的随机 (x,y) 点。出于说明目的,我将 4 个不同的折线图压缩成一个图,但想象一下,如果下面的 4 条线中的每一条都被分解成各自的图。
[![在此处输入图像描述][1]][1]
步骤 1) 对于每个折线图 A、B、C、D 去全局最大值并将其称为“X”。
第 4 步可能吗?)画一条连接“X”和“Y”的线。是否可以在 matplotlib 中绘制这条线?谢谢你。
相关代码如下:
import pandas as pd
import numpy as np
df = pd.DataFrame(np.random.randn(50, 4),
index=pd.date_range('1/1/2000', periods=50), columns=list('ABCD'))
df = df.cumsum()
df.plot();
解决方案
我认为您需要定义计算局部最大值的特定逻辑,而不仅仅是使用“时钟”隐喻,但是一旦您使用 或其他库定义了该逻辑scipi
,pandas
您就可以像我一样创建一个数据框。从那里,您应该能够从下面生成结果。
如果您对seaborn
(构建在 之上matplotlib
)没问题,我认为这会更容易一些,因为您可以传递hue
参数以在一行代码中为每个类别创建所有行。您需要使用lines
要绘制的这些创建一个新的数据框。我通过对值进行排序并获取每组的尾值来做到这一点。请参阅下面的可重现示例。
示例 1(绘制局部最大值):
import pandas as pd
import numpy as np
import matplotlib.pyplot as plt
import matplotlib.dates as mdates
import seaborn as sns
fig, ax = plt.subplots()
plt.style.use('classic')
df = pd.DataFrame(np.random.randn(50, 4),
index=pd.date_range('1/1/2000', periods=50), columns=list('ABCD'))
df = df.cumsum()
df = df.melt(ignore_index=False).reset_index()
sns.lineplot(data=df, x="index", y="value", hue="variable", ax=ax)
lines_max = (df.sort_values('value').groupby("variable").tail(1)).sort_values('variable')
lines_local_max = df[((df['variable'] == lines_max['variable'].iloc[0]) & (df['index'] > lines_max['index'].iloc[0]))
| ((df['variable'] == lines_max['variable'].iloc[1]) & (df['index'] > lines_max['index'].iloc[1]))
| ((df['variable'] == lines_max['variable'].iloc[2]) & (df['index'] > lines_max['index'].iloc[2]))
| ((df['variable'] == lines_max['variable'].iloc[3]) & (df['index'] > lines_max['index'].iloc[3]))]
lines_local_max = (lines_local_max.sort_values(['variable', 'value']).groupby("variable").tail(1))
lines = lines_max.append(lines_local_max).sort_values('variable')
lines
sns.lineplot(data=lines, x="index", y="value", hue="variable", marker="o",
style='variable', dashes=[(2, 2), (2, 2), (2, 2), (2, 2)], legend=False, ax=ax)
x_dates = pd.to_datetime(df['index'].unique())
plt.xticks(x_dates[0::7], rotation=45, ha='center')
ax.xaxis.set_major_formatter(mdates.DateFormatter('%b-%d-%Y'))
示例 2(只是在末尾画一条线,而不是定义局部最大值 - 目的只是向您展示如何从最大点画一条线到另一个定义的点):
import pandas as pd
import seaborn as sns
import matplotlib.pyplot as plt
fig, ax = plt.subplots()
plt.style.use('classic')
fmri = sns.load_dataset("fmri")
fmri = fmri.groupby(['event', 'timepoint'], as_index=False)['signal'].mean()
sns.lineplot(data=fmri, x="timepoint", y="signal", hue="event")
lines_max = (fmri.sort_values('signal').groupby("event").tail(1))
lines_last = (fmri.sort_values('timepoint').groupby("event").tail(1))
lines = lines_max.append(lines_last)
sns.lineplot(data=lines, x="timepoint", y="signal", hue="event", marker="o", style='event', dashes=[(2, 2), (2, 2)])
示例 3(另一个示例使用您提供的数据绘制一条线,但未定义局部最大值 - 目的只是向您展示如何从最大点绘制一条线到另一个定义的点):使用您拥有的数据的示例假如:
import pandas as pd
import numpy as np
fig, ax = plt.subplots()
df = pd.DataFrame(np.random.randn(50, 4),
index=pd.date_range('1/1/2000', periods=50), columns=list('ABCD'))
df = df.cumsum()
df = df.melt(ignore_index=False).reset_index()
sns.lineplot(data=df, x="index", y="value", hue="variable", ax=ax)
lines_max = (df.sort_values('value').groupby("variable").tail(1))
lines_last = (df.sort_values('index').groupby("variable").tail(1))
lines = lines_max.append(lines_last).sort_values('variable')
sns.lineplot(data=lines, x="index", y="value", hue="variable", marker="o",
style='variable', dashes=[(2, 2), (2, 2), (2, 2), (2, 2)], legend=False, ax=ax)
x_dates = df['index'].dt.strftime('%Y-%m-%d').sort_values().unique()
ax.set_xticklabels(labels=x_dates, rotation=45, ha='center')
推荐阅读
- c++ - 为什么从另一个构造函数内部调用的 C++ 构造函数不修改类变量?
- azure-devops - 将新标签推送到 github.com 时,如何在 Azure Pipelines 中触发构建?
- r - ifelse() 条件不适用于 ggplot
- angular - 以角度形式获取资源列表
- c# - 错误 405,在 C# 中的 HTTPRequest 上不允许使用方法
- python-3.x - PyCharm 不会安装 PyTorch - 构建轮失败
- javascript - WebSocket 在代码中返回 undefined 但在控制台中没有
- java - 更改约束中元素的可见性。组
- c++ - 创建 25 个应用程序窗口时 Qt Quick 应用程序锁定
- sas - 结合 IN、KEEP、DROP 和 RENAME 语句