Issue
I want to add a legend for the blue vertical dashed lines and black vertical dashed lines with label long entry points and short entry points respectively. The other two lines (benchmark and manual strategy portfolio) came from the dataframe.
How do I add a legend for the two vertical line styles?
Here is my existing code and the corresponding graph. The dataframe is a two column dataframe of values that share date indices (the x) and have y values. The blue_x_coords
and black_x_coords
are the date indices for the vertical lines, as you would expect. Thanks in advance!
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()
Solution
You can do this by simply specifying the legend yourself instead of relying on pandas
to do it for you.
Each call to ax.axvline
will add another entry to your legend, so the only trick we'll need to do is deduplicate legend entries who share the same label. From there we simply call ax.legend
with the corresponding handles and labels.
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))
Answered By - Cameron Riddell
0 comments:
Post a Comment
Note: Only a member of this blog may post a comment.