0

I would like to have a legend like the one appearing on the plot below: As you can see the legend entry shows the red line and the blue line on the same entry.

PD: In my case, the red line is always the same curve, a horizontal straight line.

Example graph How can I do this? I have tried with the examples in this guide, but they do not apply to my case, since I do not find a "handlebox artist" which applies to my case.

Edit: I have tried to apply @Mr.T answer, but in my case I am plotting the blue plot as a bar plot in matplotlib, and I get the following error AttributeError: 'BarContainer' object has no attribute '_transform'.

What I am doing is

blue_bars = axes[i].bar(bins[:-1], Wi, width = binsize, label = label_W)
red_line = axes[i].hlines(0, tstart, tstop, color='red', linewidth = 0.8)
axes[i].legend([red_line, blue_bars], labels = label_W,
            handler_map={blue_bars: HandlerLine2D(numpoints=5)},
            loc='upper right')

Note that I am creating several subplots in the same axes object, within a for loop that iterates over the variable i. This works with no problem.

Miguel
  • 96
  • 8
  • Currently, you don't ask a question. Have you tried to implement any of the methods suggested in the [matplotlib docs](https://matplotlib.org/stable/tutorials/intermediate/legend_guide.html#legend-handlers)? – Mr. T Feb 09 '22 at 16:53
  • None of those methods apply to my case. I have tried to use the accepted answer from [this question](https://stackoverflow.com/questions/31478077/how-to-make-two-markers-share-the-same-label-in-the-legend-using-matplotlib), but it does not apply exactly to what I am trying to do. – Miguel Mar 01 '22 at 15:26

1 Answers1

1

Based on the linked examples, we can construct a legend entry from scratch as you did not tell us how you plot the graph:

import matplotlib.pyplot as plt
import matplotlib.lines as mlines
from matplotlib.legend_handler import HandlerLine2D

fig, ax = plt.subplots()
red_hline = mlines.Line2D([], [], color="red")
blue_uptick = mlines.Line2D([], [], color="blue", lw=0, marker=2, markersize=5)
orange_downtick = mlines.Line2D([], [], color="orange", lw=0, marker=3, markersize=5)

ax.legend(handles=[(red_hline, blue_uptick), (red_hline, orange_downtick)], 
          labels=["the ups", "and the downs"], 
          handler_map={blue_uptick: HandlerLine2D(numpoints=5), orange_downtick: HandlerLine2D(numpoints=3)})

plt.show()

Sample output: enter image description here

Mr. T
  • 11,960
  • 10
  • 32
  • 54
  • This does not work in my case, (I think) since my blue lines are plotted with a Bar Plot. I am using [plt.Bar](https://matplotlib.org/3.5.1/api/_as_gen/matplotlib.pyplot.bar.html) for this and I get the error `AttributeError: 'BarContainer' object has no attribute '_transform'. – Miguel Mar 25 '22 at 12:21
  • As this legend is constructed from scratch without any input from the artists plotted in this axis object, I do not know why you would need the bar containers. – Mr. T Mar 25 '22 at 12:53
  • Well, the bar plot is input in the legend handler_map (in your example is `blue_uptick: HandlerLine2D(numpoints=5)`), but in my case blue_uptick is built with a bar plot (see my update in the question) – Miguel Mar 25 '22 at 13:05
  • This is understood. But I don't know why you want to use the bar rectangle patch to generate your legend - it will be more complicated and does not look much different. But you will have your reasons, so maybe someone else will provide what you want. – Mr. T Mar 25 '22 at 17:37