杰瑞科技汇

ggplot Python 图例如何自定义?

Of course! This is a very common and important task when creating data visualizations in Python. The ggplot library is a port of R's famous ggplot2, and its syntax for legends is powerful and consistent.

ggplot Python 图例如何自定义?-图1
(图片来源网络,侵删)

Here’s a comprehensive guide to creating and customizing legends in Python's ggplot.

The Foundation: How Legends are Created

In ggplot, a legend is automatically generated whenever you use an aesthetic (aes()) that maps a variable to a visual property. The most common aesthetics that create legends are:

  • color or colour: For points, lines, and fills.
  • fill: For the inside of bars, polygons, etc.
  • shape: For point markers.
  • size: For the size of points or lines.
  • linetype: For dashed/dotted lines.
  • alpha: For transparency.

Key Concept: The legend is created based on the mapping inside aes(), not the setting outside of it.


Basic Example: Automatic Legend Creation

Let's start with a simple scatter plot where we map the species column to the color aesthetic. ggplot will automatically create a legend for us.

ggplot Python 图例如何自定义?-图2
(图片来源网络,侵删)
import pandas as pd
from plotnine import ggplot, aes, geom_point, labs
# Sample data (the famous Iris dataset)
from plotnine.data import mtcars
# For a more colorful example, let's use a built-in dataset
from plotnine.data import mpg
# Create the plot
# We map 'class' to color and 'displ' to size
plot = (
    ggplot(mpg, aes(x='displ', y='hwy', color='class', size='cty'))
    + geom_point()
    + labs(
        title="MPG Dataset",
        x="Engine Displacement (L)",
        y="Highway Miles Per Gallon",
        color="Vehicle Class",  # Custom legend title for color
        size="City MPG"          # Custom legend title for size
    )
)
print(plot)

What's happening here?

  • aes(color='class'): This tells ggplot to use a different color for each unique value in the class column (e.g., "compact", "suv", "2seater"). This mapping is what triggers the legend to be created.
  • labs(color='Vehicle Class'): This is used to give the legend a more descriptive title. You can use labs() for color, fill, size, shape, etc.

Customizing the Legend Title

As shown above, you can set the legend title directly in labs().

from plotnine import ggplot, aes, geom_point, labs
plot = (
    ggplot(mpg, aes(x='displ', y='hwy', color='class'))
    + geom_point()
    + labs(
        title="Custom Legend Title",
        color="Type of Car"  # This changes the legend title for 'color'
    )
)
print(plot)

Hiding a Legend

Sometimes you don't want a legend to appear. You have two main ways to do this.

Method A: Remove a Specific Legend

If you have multiple aesthetics mapped (e.g., color and size), you can remove just one of them.

from plotnine import ggplot, aes, geom_point, guides
plot = (
    ggplot(mpg, aes(x='displ', y='hwy', color='class', size='cty'))
    + geom_point()
    + guides(color="none")  # Hide the legend for the 'color' aesthetic
)
print(plot)

Method B: Hide All Legends

If you want to remove all legends from the plot at once, you can use theme().

from plotnine import ggplot, aes, geom_point, theme
plot = (
    ggplot(mpg, aes(x='displ', y='hwy', color='class', size='cty'))
    + geom_point()
    + theme(legend_position="none") # The most direct way to hide all legends
)
print(plot)

Customizing Legend Items (Labels and Order)

This is a very common requirement. You want to change the text labels in the legend or reorder them.

Method A: Using scale_*_manual()

This is the most flexible and powerful method. You explicitly provide the labels and the order.

from plotnine import ggplot, aes, geom_point, scale_color_manual, labs
# Define the order and labels for the legend items
legend_order = ["suv", "compact", "pickup", "subcompact"]
legend_labels = ["SUV (Largest)", "Compact (Small)", "Pickup (Work)", "Subcompact (Tiny)"]
plot = (
    ggplot(mpg, aes(x='displ', y='hwy', color='class'))
    + geom_point()
    + scale_color_manual(
        name="Vehicle Type",  # Legend title
        labels=legend_labels, # Custom labels for each item
        values=legend_order   # The order of items in the legend
    )
)
print(plot)

Note: In scale_color_manual, the values argument can also be used to assign specific colors. For example: values=["red", "blue", "green", "yellow"].

Method B: Using factor() and .cat.reorder()

If your data is in a pandas Categorical, you can reorder it directly, and ggplot will respect that order.

import pandas as pd
from plotnine import ggplot, aes, geom_point
# Create a Categorical type with a specific order
mpg['class'] = pd.Categorical(mpg['class'], categories=["pickup", "suv", "compact", "subcompact"], ordered=True)
plot = (
    ggplot(mpg, aes(x='displ', y='hwy', color='class'))
    + geom_point()
)
print(plot)
# The legend will now be in the order: pickup, suv, compact, subcompact

Changing the Legend Position

By default, legends are placed on the right side of the plot. You can change this using the legend_position argument in theme().

  • "right" (default), "left", "top", "bottom"
  • "none" (to hide it, as seen before)
  • You can also use numeric coordinates like (0.1, 0.9) for fine-grained control.
from plotnine import ggplot, aes, geom_point, theme
# Place legend at the bottom
plot_bottom = (
    ggplot(mpg, aes(x='displ', y='hwy', color='class'))
    + geom_point()
    + theme(legend_position="bottom")
)
# Place legend in the top-left corner
plot_top_left = (
    ggplot(mpg, aes(x='displ', y='hwy', color='class'))
    + geom_point()
    + theme(legend_position=(0.02, 0.98)) # x, y coordinates (0-1 range)
)
print(plot_bottom)
print(plot_top_left)

Modifying the Legend Appearance (Background, Box, Keys)

You can use the theme() function to control almost every aspect of the legend's appearance.

  • legend_key: The box around the legend symbol (e.g., the colored square).
  • legend_background: The background of the entire legend box.
  • legend_text: The text of the legend labels.
  • legend_title: The text of the legend title.
from plotnine import ggplot, aes, geom_point, theme, element_blank, element_rect, element_text
plot = (
    ggplot(mpg, aes(x='displ', y='hwy', color='class'))
    + geom_point()
    + theme(
        legend_position="bottom",
        legend_key=element_rect(fill="lightblue", color="black", size=0.5), # Add a border and fill to legend keys
        legend_background=element_rect(fill="yellow", alpha=0.3), # Add a semi-transparent background to the whole legend
        legend_text=element_text(color="purple", size=10), # Change label text color and size
        legend_title=element_text(face="bold.italic", size=12, color="darkblue") # Style the title
    )
)
print(plot)

Complete Example: Putting It All Together

Let's create a final, polished example that combines several of these techniques.

import pandas as pd
from plotnine import (
    ggplot, aes, geom_point, geom_smooth,
    scale_color_manual, labs, theme,
    element_rect, element_text
)
# Sample data
df = pd.DataFrame({
    'x': [1, 2, 3, 4, 5, 6, 7, 8, 9, 10],
    'y': [2.1, 3.9, 6.2, 7.8, 10.1, 12.3, 13.8, 16.
分享:
扫描分享到社交APP
上一篇
下一篇