<jupyter_start><jupyter_text>Customized Plot Legends<jupyter_code>%matplotlib inline
import matplotlib.pyplot as plt
plt.style.use('classic')
import numpy as np
# Demo basic plt.legend() view:
x = np.linspace(0, 10, 1000)
fig, ax = plt.subplots()
ax.plot(x, np.sin(x), '-b', label='Sine')
ax.plot(x, np.cos(x), '--r', label='Cosine')
ax.axis('equal')
leg = ax.legend();
# Legend: Specify location, turn off frame
ax.legend(loc='upper left', frameon=False)
fig
ax.legend(frameon=False, loc='lower center', ncol=2)
fig
# fancybox -> use rounded box, alpha -> frame transparency, borderpad -> text padding amount
ax.legend(fancybox=True, framealpha=1, shadow=True, borderpad=1)
fig<jupyter_output><empty_output><jupyter_text>Choose elements for the legendplt.legend() includes all labeled elements by default.We can specify a subset of labeled elements to include in our legend a few ways.<jupyter_code># First approach, store line instances returned by plt.plot, slice that list and specify labels
y = np.sin(x[:, np.newaxis] + np.pi * np.arange(0, 2, 0.5))
lines = plt.plot(x, y)
plt.legend(lines[:2], ['first', 'second']);
# Preferable approach: when adding a line to plot, label the ones you want to have in legend.
plt.plot(x, y[:, 0], label='first')
plt.plot(x, y[:, 1], label='second')
plt.plot(x, y[:, 2:])
plt.legend(framealpha=1, frameon=True);<jupyter_output><empty_output><jupyter_text>Legend for Meaningful Point SizeIn the following example, the size of a point on our plot is meaningful.By plotting empty lists, we create labled plot objects which are pickedup by the legend, revealing the visual scale.We must do this as the legend will always reference an object on the plot,but we don't want the scale reference on the actual plot.<jupyter_code># Get input data
import pandas as pd
cities = pd.read_csv('../data/california_cities.csv')
lat, lon = cities['latd'], cities['longd']
population, area = cities['population_total'], cities['area_total_km2']

# Scatter the points, using size and color, without labels.
plt.scatter(lon, lat, label=None,
            c=np.log10(population), cmap='viridis',
            s=area, linewidth=0, alpha=0.5)
plt.axis(aspect='equal')
plt.xlabel('longitude')
plt.ylabel('latitude')
plt.colorbar(label='log$_{10}$(population)')
plt.clim(3, 7)

# Create legend: plot empty lists with desired areas + labels.
for area in [100, 300, 500]:
    plt.scatter([], [], c='k', alpha=0.3, s=area,
                label=str(area) + ' km$^2$')
plt.legend(scatterpoints=1, frameon=False, labelspacing=1, title='City Area')
plt.title('California Cities: Area and Population');<jupyter_output><empty_output><jupyter_text>^^ For some reason, that entire block works only if run at once. Or moreover, after a single-shot plt, we lose lat, lon, pop, area. I knew plots were single-use, but that seems odd to me.  Multiple Legends:Sometimes it makes sends to add multiple legends to the same axes,but plt.legend() only allows for 1.To work around this, we must create a new legend artist ourselves,then use the ax.add_artist() method to add the second artist to the plot.<jupyter_code>fig, ax = plt.subplots()
lines = []
styles = ['-', '--', '-.', ':']
x = np.linspace(0, 10, 1000)

for i in range(4):
    lines += ax.plot(x, np.sin(x - i * np.pi / 2), styles[i], color='black')

ax.axis('equal')

# Create the first legend as usual.
ax.legend(lines[:2], ['line A', 'line B'], loc='upper right', frameon=False)

# Create the second legend and add the artist
from matplotlib.legend import Legend
leg = Legend(ax, lines[2:], ['line C', 'line D'],
             loc='lower right', frameon=False)
ax.add_artist(leg);<jupyter_output><empty_output>
{'fraction_non_alphanumeric': 0.14235069539132805, 'fraction_numerical': 0.014998636487592037, 'mean_word_length': 5.062809917355372, 'pattern_counts': {'":': 0, '<': 17, '<?xml version=': 0, '>': 20, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'chain_length': '4', 'dir': 'jupyter-structured-clean-dedup', 'id': '269064', 'license': 'MIT', 'n_tokens_mistral': 1273, 'n_tokens_neox': 1204, 'n_words': 412, 'path': '4-matplotlib-ipynb/4.06-customized-plot-legends.ipynb', 'repo_name': 'pgiardiniere/notes-PythonDataScienceHandbook', 'size': '3667'}