ILA
ILA

Reputation: 3

Handle legend markers independently

I have a plot with two types of lines: solid and dashed. Both solid and dashed lines represent the same quantity for different conditions and they have the same color.

Now, I'd like to add in an ax.text() the marker of the solid line to say that the solid line represents the quantity in that condition and another ax.text() with the marker of the dashed line to indicate the other condition. Somehow I mean something like this:

ax.text(0.9, 0.5, solid_marker + 'condition 1')
ax.text(0.9, 0.4, dashed_marker + 'condition 2')

Well, something like in this picture:

Example of what I want to do:

enter image description here

Does anybody knows how to do it? It is possible to use the symbols of the markers in random text in the plot?

Thanks!

Upvotes: 0

Views: 1477

Answers (2)

ILA
ILA

Reputation: 3

Thanks to @swatchai. I modified his answer to fit my code. So that I got:

import numpy as np
import matplotlib.lines as mlines
import matplotlib.pyplot as plt

# my fig and my axes
fig, ax1 = plt.subplots(figsize=(6, 6))

# my plots
ax1.plot(temp, zn,  color=cycle[0], label=r'$z_n$')
ax1.plot(temp, zp,  color=cycle[1], label=r'$z_p$')
ax1.plot(temp, zpi, color=cycle[2], label=r'$z_\pi$')

# the other plots
ax1.plot(temp, zn2,  color=cycle[0], linestyle='--')
ax1.plot(temp, zp2,  color=cycle[1], linestyle='--')
ax1.plot(temp, zpi2, color=cycle[2], linestyle='--')

# Second legend 'imaginary' lines
line_solid = mlines.Line2D([], [], color='black', linestyle='-',    \
        linewidth=1.5, label=r'$n_b = n_0$')
line_dashed = mlines.Line2D([], [], color='black', linestyle='--',  \
        linewidth=1.5, label=r'$n_b = n_0/2$')

# original legend
leg1 = ax1.legend()

# set second legend (will remove first one)
leg2 = ax1.legend(handles=[line_solid, line_dashed], loc='best', \
            bbox_to_anchor=(0.5, 0.20, 0.5, 0.6))

leg2.set_frame_on(False)    # remove legend frame
# manually add the first legend back
ax1.add_artist(leg1)

The output (notice that the above code is not runnable and it seem I cannot embed pictures yet):

result

I actually wanted to avoid having to go through this step of creating new imaginary lines to assign a legend to them. I would have liked to know if it is possible to use the markers in a text too. But well, this at least solves my problem.

Thanks!

Upvotes: 0

swatchai
swatchai

Reputation: 18782

Your legend's spec is not standard. You need to create it manually. Here is a runnable code that can produce what you need.

#import matplotlib.patches as mpatches
import matplotlib.lines as mlines
import matplotlib.pyplot as plt

# Need to create legends manually

# First legend
#red_patch = mpatches.Patch(color='red', label='The red data')
black_line = mlines.Line2D([], [], color='black', linewidth=1.5, label=r'$Z_n$')
green_line = mlines.Line2D([], [], color='green', linewidth=1.5, label=r'$Z_p$')
red_line = mlines.Line2D([], [], color='red', linewidth=1.5, label=r'$Z_\pi$')

# Second legend
line_solid = mlines.Line2D([], [], color='black', linestyle='-', linewidth=1.5, label=r'$n_\beta = n_o$')
line_dashed = mlines.Line2D([], [], color='black', linestyle='--', linewidth=1.5, label=r'$n_\beta = n_o/2$')

first_legend = plt.legend(handles=[black_line, green_line, red_line], loc=1)
ax = plt.gca().add_artist(first_legend)
second_legend = plt.legend(handles=[line_solid, line_dashed], loc='best', \
                           bbox_to_anchor=(0.5, 0.20, 0.5, 0.5)) #best upper-right
second_legend.set_frame_on(False)

plt.show()

The output plot:

legend01

Upvotes: 1

Related Questions