繁体   English   中英

将垂直线样式添加到 matplotlib 图例到由数据框制作的绘图中

[英]Adding Vertical Line styles to a matplotlib legend to a plot made from a dataframe

我希望添加一个标签,指示蓝色垂直虚线表示长入口点,黑色垂直虚线表示短入口点。

其他两行(基准和手动策略组合)来自数据框。 如何为两种垂直线条样式添加图例?

这是我现有的代码和相应的图表。 数据框是共享日期索引(x)并具有 y 值的值的两列数据框。 正如您所料,blue_x_coords 和 black_x_coords 是垂直线的日期索引。 提前致谢!

    ax = df.plot(title=title, fontsize=12, color=["tab:purple", "tab:red"])
    ax.set_xlabel(xlabel)
    ax.set_ylabel(ylabel)
    for xc in blue_x_coords:
        plt.axvline(x=xc, color="blue", linestyle="dashed", label="Long Entry points")
    for xc in black_x_coords:
        plt.axvline(x=xc, color="black", linestyle="dashed", label="Short Entry points")
    plt.savefig('./images/' + filename)
    plt.clf()

在此处输入图像描述

你可以在plt.legend() plt.show()但在这里你需要使用vlines()这里需要yminymax

ax=df.plot(color=["green","red"])
ax.set_title("Test")
ax.set_xlabel("X")
ax.set_ylabel("Y")
ax.vlines(range(0,100,25),label="Long Entry points",linestyle="--",ymin=0,ymax=100,color="blue") 
# you can pass blue_x_coords instead of range
ax.vlines(range(0,100,15),label="Short Entry points",linestyle="--",ymin=0,ymax=100,color="black") 
# you can pass black_x_coords instead of range
plt.legend()
plt.show()

输出:
输出 1


如果使用axvline那么您可以遵循以下方法:

您可以使用Axes.add_artist()添加新图例以在现有图中添加新图例。

  • plt.legend()将在这里工作,因为您在axvline()中添加了label ,但是有一个问题,因为它是通过循环添加的,然后添加了许多label
  • plt.axvline中删除了label ,因为它被多次添加,因此图例中会有很多不同的label
  • 添加新legend时,您还需要传递loc ,否则它将仅在默认位置。
  • 它将作为另一个图例添加,而不是合并到同一个图例中(如果有人知道,我不知道添加同一个图例的方法,请显示)
ax=df.plot(color=["green","red"])
ax.set_title("Test")
ax.set_xlabel("X")
ax.set_ylabel("Y")
for xc in range(0,100,25):
    line1=plt.axvline(x=xc, color="blue", linestyle="dashed")
for xc in range(0,100,15):
    line2=plt.axvline(x=xc, color="black", linestyle="dashed")
new_legend=plt.legend([line1,line2],["Long Entry points","Short Entry points"],loc="lower right")
ax.add_artist(new_legend)
plt.legend()
plt.show()

输出:
图形输出

答:似乎最简单的方法是替换 for 循环:

    ax.vlines(x=blue_x_coords, colors="blue", ymin=bottom, ymax=top, linestyles="--", label="Long Entry Points")
    ax.vlines(x=black_x_coords, colors="black", ymin=bottom, ymax=top, linestyles="--", label="Short Entry Points")
    ax.legend()

您可以通过简单地自己指定图例来完成此操作,而不是依靠pandas为您完成。

每次调用ax.axvline都会在您的图例中添加另一个条目,因此我们需要做的唯一技巧是对共享相同标签的图例条目进行重复数据删除。 从那里我们只需调用带有相应句柄和标签的ax.legend

from matplotlib.pyplot import subplots, show
from pandas import DataFrame, date_range, to_datetime
from numpy.random import default_rng
from matplotlib.dates import DateFormatter

rng = default_rng(0)

df = DataFrame({
    'Benchmark': rng.normal(0, .1, size=200),
    'Manual Strategy Portfolio': rng.uniform(-.1, .1, size=200).cumsum(),
}, index=date_range('2007-12', freq='7D', periods=200))

ax = df.plot(color=['tab:purple', 'tab:red'])

blue_x_coords = to_datetime(['2008-07', '2009-11', '2010-10-12'])
black_x_coords = to_datetime(['2008-02-15', '2009-01-15', '2011-09-23'])

for xc in blue_x_coords:
    blue_vline = ax.axvline(x=xc, color="blue", linestyle="dashed", label="Long Entry points")
for xc in black_x_coords:
    black_vline = ax.axvline(x=xc, color="black", linestyle="dashed", label="Short Entry points")

# De-duplicate all legend entries based on their label
legend_entries = {label: artist for artist, label in zip(*ax.get_legend_handles_labels())}

# Restructure data to pass into ax.legend
labels, handles = zip(*legend_entries.items())

ax.legend(labels=labels, handles=handles, loc='center left', bbox_to_anchor=(1.02, .5))

在此处输入图像描述

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM