NeuroAgent

How to Position Legend Outside Plot in Matplotlib

Complete guide to positioning legends outside plot areas in Matplotlib. Learn how to place legends on the right side and reduce font size for compact, professional data visualizations.

Question

How to Position a Legend Outside the Plot Area in Data Visualization

I’m creating a figure with 20 individual plots (not subplots) and need to place the legend outside the plot area to the right. I want to maintain the current figure size without reducing the axes dimensions.

Specifically, I need help with:

  1. How to position the legend box outside the plot area, specifically on the right side
  2. Methods to reduce the font size within the legend to make the legend box more compact
NeuroAgent

To position a legend outside the plot area to the right in Matplotlib, use the bbox_to_anchor parameter with coordinates like (1.1, 1) and combine it with the loc='upper right' parameter to anchor the legend outside the plot boundaries. For reducing legend font size, use the fontsize parameter within the legend() function to make the legend box more compact while maintaining your current figure size.

Contents


Basic Method for Right-Side Legend Positioning

The most straightforward approach to position a legend outside the plot area to the right involves using the bbox_to_anchor parameter in combination with the loc parameter. This method allows you to precisely control where the legend appears relative to the plot boundaries.

Using bbox_to_anchor and loc

The key parameters you’ll need are:

  • bbox_to_anchor: A tuple (x, y) that specifies the anchor point relative to the axes
  • loc: A string that specifies where the legend should be positioned relative to the anchor point

For right-side positioning, common combinations include:

python
plt.legend(loc='upper right', bbox_to_anchor=(1.1, 1))

This places the legend’s upper-right corner at 110% of the axes width (x=1.1) and 100% of the axes height (y=1), effectively positioning it outside the plot area to the right.

Understanding Coordinate System

The coordinate system for bbox_to_anchor works as follows:

  • (0, 0) corresponds to the bottom-left corner of the axes
  • (1, 1) corresponds to the top-right corner of the axes
  • Values greater than 1 extend outside the axes boundaries
  • Values less than 0 extend to the left or below the axes

For centering the legend perfectly on the right side, you can use:

python
plt.legend(loc='center left', bbox_to_anchor=(1, 0.5))

This positions the legend’s center at the right edge of the plot (x=1) and vertically centered (y=0.5).

Advanced Positioning Techniques

For more complex scenarios involving multiple plots or precise positioning requirements, several advanced techniques can be employed.

Using fig.legend() for Shared Legends

When working with multiple plots that share the same legend entries, using fig.legend() is more efficient than creating individual legends for each plot:

python
fig, ax = plt.subplots()
ax.plot([1, 2, 3], label='Line 1')
ax.plot([3, 2, 1], label='Line 2')

# Create a shared legend outside all plots
fig.legend(loc='outside upper right', bbox_to_anchor=(1.1, 1))
plt.tight_layout()

As the official Matplotlib documentation explains, fig.legend() creates a legend that can be shared across multiple subplots or axes.

Adjusting Layout with tight_layout()

To ensure the legend doesn’t overlap with other elements and the plot area remains properly sized, use tight_layout():

python
plt.legend(loc='upper right', bbox_to_anchor=(1.1, 1))
plt.tight_layout(rect=[0, 0, 0.9, 1])  # Leave space on the right

The rect parameter specifies the rectangle within to adjust the plot, allowing you to reserve space for the legend.

Fine-Tuning Legend Position

For precise positioning, you can experiment with different coordinate values:

python
# Different right-side positioning options
plt.legend(loc='upper right', bbox_to_anchor=(1.15, 1))      # Further right
plt.legend(loc='center right', bbox_to_anchor=(1.2, 0.5))    # Centered right, further out
plt.legend(loc='lower right', bbox_to_anchor=(1.05, 0))      # Bottom right

According to the GeeksforGeeks guide, the bbox_to_anchor=(1.1, 1) parameter is particularly effective for placing legends in the upper-right corner outside the plot area.

Reducing Legend Font Size for Compact Display

When positioning legends outside the plot area, especially in figures with multiple plots, reducing the font size can help create a more compact and readable legend.

Using the fontsize Parameter

The simplest way to reduce legend font size is by using the fontsize parameter:

python
plt.legend(loc='upper right', bbox_to_anchor=(1.1, 1), fontsize='small')

Common font size options include:

  • 'xx-small', 'x-small', 'small', 'medium', 'large', 'x-large', 'xx-large'
  • Numeric values (e.g., fontsize=8, fontsize=10)
  • Relative sizes (e.g., fontsize=0.8)

Setting Different Font Sizes for Legend Title and Labels

For more granular control, you can set different font sizes for the legend title and individual labels:

python
legend = plt.legend(loc='upper right', bbox_to_anchor=(1.1, 1))
legend.get_title().set_fontsize('medium')    # Legend title
for text in legend.get_texts():
    text.set_fontsize('small')                 # Legend labels

Using prop Parameter for Font Properties

For even more control over font appearance, use the prop parameter:

python
plt.legend(loc='upper right', bbox_to_anchor=(1.1, 1), 
          prop={'size': 8, 'family': 'sans-serif'})

As mentioned in the PSYCHOLOGICAL STATISTICS guide, Matplotlib provides comprehensive font customization options through various arguments within the legend() function.

Handling Multiple Plots and Legends

When working with 20 individual plots as mentioned in your question, you’ll need strategies to manage legends effectively without cluttering your visualization.

Creating a Single Shared Legend

For plots that share the same data series, create a single shared legend:

python
fig, axes = plt.subplots(4, 5, figsize=(20, 16))  # 4x5 grid for 20 plots

# Plot data on each axis with same labels
for i, ax in enumerate(axes.flat):
    ax.plot([1, 2, 3], label='Series A')
    ax.plot([3, 2, 1], label='Series B')
    ax.set_title(f'Plot {i+1}')

# Create one shared legend
fig.legend(loc='outside upper right', bbox_to_anchor=(1.1, 1))
plt.tight_layout()

Positioning Legend for Multiple Figure Layouts

For different figure layouts, adjust the positioning accordingly:

python
# For horizontal arrangement of plots
fig, axes = plt.subplots(1, 20, figsize=(40, 3))
for i, ax in enumerate(axes):
    ax.plot([1, 2, 3], label=f'Data {i+1}')

# Position legend below the plots
fig.legend(loc='outside center right', bbox_to_anchor=(1.1, 0.5))
plt.tight_layout()

The Saturn Cloud Blog suggests that adjusting the right parameter in tight_layout() can help accommodate legends outside the plot area on the right side.

Complete Example with Code

Here’s a complete example demonstrating how to position a legend outside the plot area to the right with reduced font size:

python
import matplotlib.pyplot as plt
import numpy as np

# Create sample data
x = np.linspace(0, 10, 100)
y1 = np.sin(x)
y2 = np.cos(x)

# Create figure and plot
fig, ax = plt.subplots(figsize=(10, 6))
ax.plot(x, y1, label='Sine Wave', linewidth=2)
ax.plot(x, y2, label='Cosine Wave', linewidth=2, linestyle='--')

# Position legend outside to the right with reduced font size
legend = ax.legend(
    loc='center left', 
    bbox_to_anchor=(1.05, 0.5),  # Right side, centered vertically
    fontsize='small',            # Reduced font size
    frameon=True,                # Add frame
    fancybox=True,               # Rounded corners
    shadow=True                  # Add shadow
)

# Adjust layout to make room for legend
plt.tight_layout(rect=[0, 0, 0.85, 1])  # Leave space on right side

# Add title and labels
ax.set_title('Trigonometric Functions with External Legend')
ax.set_xlabel('X-axis')
ax.set_ylabel('Y-axis')
ax.grid(True, alpha=0.3)

plt.show()

This example creates a professional-looking plot with the legend positioned outside to the right and uses a smaller font size to keep the legend compact.

Troubleshooting Common Issues

When positioning legends outside the plot area, you may encounter several common issues:

Legend Being Cut Off

If part of your legend is cut off, adjust the layout parameters:

python
plt.tight_layout(rect=[0, 0, 0.9, 1])  # Increase right margin

The Better Stack Community confirms that (1, 1) places the legend in the upper-right corner outside the plot area, but proper layout adjustment is needed to prevent cutoff.

Legend Overlapping with Other Elements

Use bbox_inches='tight' when saving figures:

python
plt.savefig('plot_with_legend.png', bbox_inches='tight')

Legend Not Responding to Font Size Changes

If font size changes don’t take effect, try updating the legend after creation:

python
legend = plt.legend(loc='upper right', bbox_to_anchor=(1.1, 1))
for text in legend.get_texts():
    text.set_fontsize(8)

Sources

  1. How to put the legend outside the plot - Stack Overflow
  2. Legend guide — Matplotlib 3.10.7 documentation
  3. How to Place Legend Outside of the Plot in Matplotlib? - GeeksforGeeks
  4. How to Put the Legend outside the Plot | Better Stack Community
  5. How to Place the Legend Outside the Plot in Matplotlib | Built In
  6. Enhancing Data Visualization: Moving Legends Outside the Plot with Matplotlib in Python | Saturn Cloud Blog
  7. Python 🐍 Put Legend Outside Plot 📈 – Easy Guide – Be …
  8. Add a Title to Matplotlib Legend (With Examples) - PSYCHOLOGICAL STATISTICS

Conclusion

Key takeaways for positioning legends outside the plot area to the right:

  1. Use bbox_to_anchor parameter with coordinates greater than 1 (e.g., (1.1, 1)) to position legends outside the plot boundaries
  2. Combine with loc parameter to control alignment relative to the anchor point
  3. Reduce legend font size using fontsize parameter or by updating legend text properties individually
  4. Always use tight_layout() to prevent legend overlap and ensure proper spacing
  5. For multiple plots, consider using fig.legend() to create shared legends that save space

For your specific case with 20 individual plots, I recommend creating a shared legend using fig.legend() with reduced font size and positioning it with bbox_to_anchor=(1.05, 0.5) for optimal right-side placement. Experiment with different font sizes and coordinate values to achieve the perfect balance between readability and compactness.