Python Matplotlib:在两个点之间绘制一条线…但以一种不同寻常的方式

Python Matplotlib:在两个点之间绘制一条线…但以一种不同寻常的方式,python,matplotlib,matplotlib-basemap,Python,Matplotlib,Matplotlib Basemap,我正在学习使用Matplotlib可视化数据,我想以非常定制的方式绘制一条线。我是Matplotlib新手,我不知道我想做的事情是否可能。下面是: 设置:假设您有一组随机(x,y)点用于直线图。为了便于说明,我将4个不同的折线图压缩成一个图,但想象一下,如果下面4条线中的每一条都被分解成各自的图 [![在此处输入图像描述][1][1] 步骤1)对于每个折线图A、B、C、D,转到全局最大值并将其称为“X” 第4步可能吗?)画一条连接“X”和“Y”的线。可以在matplotlib中绘制这条线吗?多谢

我正在学习使用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
参数在一行代码中为每个类别创建所有行。您需要使用这些要打印的
行创建一个新的数据框。我通过对值进行排序并获得每组的尾值来实现这一点。参见下面的可复制示例

示例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(仅在末尾画一条线,而不定义局部最大值-目的只是向您展示如何从最大值点到另一个定义点画一条线):

示例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')

您能提供您的数据和代码吗?完成。不幸的是,没有静态数据,它是随机生成的。请参阅我对您问题的回答。很明显,有很多事情是你可以理解的,但如果我已经回答了你的问题,那么请接受作为解决方案。非常感谢。您对局部最大值的定义是在最大值之后的某个时间点发生的最高点吗?如果您正在寻找其他内容,那么请包括您将要使用的代码或方法。^^^^如果这就是您正在寻找的原因,那么很容易在与我当前答案具有相同结构的pandas数据框架中获得它。当我从训练中回来时,我会更新我的答案。@phan我以为你对找出问题的
matplotib
方面更感兴趣。有多种方法可以找到局部最大值,您可能会使用不同的方法,具体取决于数据和您试图实现的其他目标。从这个答案()中,您可以使用两种不同于最热门答案的方法。如果没有显示计算局部最大值的尝试以及符合局部最大值条件的点的期望输出,这个问题是不完整的。嗯,我想知道Matplotlib是否能够以我描述的方式从X到Y进行绘图。我只是不知道。如果答案是肯定的,我可以对方法进行编码以获得局部最大值。我想要的输出只是用一条线连接点“X”和“Y”。让我再考虑一下,看看是否可以生成确定点“Y”的代码。另外,我感谢您的帮助。我对Seaborn一点也不熟悉,但我愿意去看看并学习它。@phan没问题(见第一个例子),但我猜这会给你你想要的东西。我建议您在标题中显示您试图生成局部最大值的代码,而不是“时钟”示例和“但以一种不同寻常的方式”。您需要用示例输入和预期输出数据更清楚地定义不寻常的方式,并用代码显示您的尝试。同意并完成!感谢您在回复中投入的大量时间、精力和关怀。它们非常有助于加快理解Matplotlib的进程。另外,感谢您对Seaborn的介绍。
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')