Article Categories
- All Categories
-
Data Structure
-
Networking
-
RDBMS
-
Operating System
-
Java
-
MS Excel
-
iOS
-
HTML
-
CSS
-
Android
-
Python
-
C Programming
-
C++
-
C#
-
MongoDB
-
MySQL
-
Javascript
-
PHP
-
Economics & Finance
How to place customized legend symbols on a plot using Matplotlib?
Matplotlib allows you to create customized legend symbols by inheriting from legend handler classes. This is useful when you want legend symbols that differ from the actual plot elements or need special shapes like ellipses.
Creating Custom Legend Handler
First, we create a custom handler class that inherits from HandlerPatch to define how our legend symbol should appear ?
import matplotlib.pyplot as plt
import matplotlib.patches as mpatches
from matplotlib.legend_handler import HandlerPatch
class HandlerEllipse(HandlerPatch):
def create_artists(self, legend, orig_handle, xdescent, ydescent, width, height, fontsize, trans):
center = 0.5 * width - 0.5 * xdescent, 0.5 * height - 0.5 * ydescent
p = mpatches.Ellipse(xy=center, width=width + xdescent, height=height + ydescent)
self.update_prop(p, orig_handle, legend)
p.set_transform(trans)
return [p]
print("Custom handler class created successfully")
Custom handler class created successfully
Complete Example with Custom Legend
Now let's create a plot with a circle patch and display it with an elliptical legend symbol ?
import matplotlib.pyplot as plt
import matplotlib.patches as mpatches
from matplotlib.legend_handler import HandlerPatch
plt.rcParams["figure.figsize"] = [7.50, 3.50]
plt.rcParams["figure.autolayout"] = True
class HandlerEllipse(HandlerPatch):
def create_artists(self, legend, orig_handle, xdescent, ydescent, width, height, fontsize, trans):
center = 0.5 * width - 0.5 * xdescent, 0.5 * height - 0.5 * ydescent
p = mpatches.Ellipse(xy=center, width=width + xdescent, height=height + ydescent)
self.update_prop(p, orig_handle, legend)
p.set_transform(trans)
return [p]
# Create a circle patch
c = mpatches.Circle((0.5, 0.5), 0.25, facecolor="green", edgecolor="red", linewidth=1)
plt.gca().add_patch(c)
# Add legend with custom ellipse handler
plt.legend([c], ["Custom Ellipse Legend"],
handler_map={mpatches.Circle: HandlerEllipse()})
plt.xlim(0, 1)
plt.ylim(0, 1)
plt.title("Custom Legend Symbol Example")
plt.show()
How It Works
The HandlerEllipse class overrides the create_artists method to:
- Calculate center position − Based on legend box dimensions
-
Create ellipse patch − Using
mpatches.Ellipsewith calculated dimensions -
Apply properties − Transfer properties from original handle using
update_prop - Set transform − Apply coordinate transformation for proper positioning
- Return patch list − Return the ellipse patch in a list format
Alternative Custom Handlers
You can create different custom legend symbols by modifying the handler ?
import matplotlib.pyplot as plt
import matplotlib.patches as mpatches
from matplotlib.legend_handler import HandlerPatch
class HandlerRectangle(HandlerPatch):
def create_artists(self, legend, orig_handle, xdescent, ydescent, width, height, fontsize, trans):
center = 0.5 * width - 0.5 * xdescent, 0.5 * height - 0.5 * ydescent
p = mpatches.Rectangle((center[0] - width/4, center[1] - height/4),
width/2, height/2)
self.update_prop(p, orig_handle, legend)
p.set_transform(trans)
return [p]
# Create plot elements
circle = mpatches.Circle((0.3, 0.7), 0.1, facecolor="blue", edgecolor="black")
square = mpatches.Rectangle((0.6, 0.6), 0.2, 0.2, facecolor="red", edgecolor="black")
plt.gca().add_patch(circle)
plt.gca().add_patch(square)
# Use different handlers for different elements
plt.legend([circle, square], ["Ellipse Legend", "Rectangle Legend"],
handler_map={mpatches.Circle: HandlerEllipse(),
mpatches.Rectangle: HandlerRectangle()})
plt.xlim(0, 1)
plt.ylim(0, 1)
plt.title("Multiple Custom Legend Handlers")
plt.show()
Conclusion
Custom legend handlers allow you to create legend symbols that differ from your actual plot elements. Inherit from HandlerPatch and override create_artists to define custom legend appearances for better visual communication.
