如何在Python中实现类似R的多图合并(grid.arrange/facet_wrap)功能?
How to Combine Density Plots by Weekday in Python (Like R's
facet_wrap or grid.arrange) Great question! In Python, you have two go-to approaches to replicate the facetting/arranging workflow you’re familiar with from R. Let’s walk through both—one that’s quick and high-level (using seaborn) and another for full manual control (using matplotlib).
Option 1: Use Seaborn's FacetGrid (Most Like R's facet_wrap)
Seaborn is built on matplotlib and has a FacetGrid class that’s perfect for creating grouped subplots just like facet_wrap. It handles the layout and subplot mapping automatically, so you can focus on your density plots.
Example Code:
import seaborn as sns import matplotlib.pyplot as plt import pandas as pd import numpy as np # Create sample data (replace with your actual dataset) df = pd.DataFrame({ "weekday": pd.Categorical( ["Mon", "Tue", "Wed", "Thu", "Fri", "Sat", "Sun"], categories=["Mon", "Tue", "Wed", "Thu", "Fri", "Sat", "Sun"], ordered=True # Ensures weekdays stay in correct order ), "category": ["A", "B"] * 350, # Your categorical variable "value": np.random.normal(loc=0, scale=1, size=700) # Your continuous variable }) # Set up the facet grid g = sns.FacetGrid( df, col="weekday", # Split subplots by weekday col_wrap=3, # Number of subplots per row height=3, # Height of each subplot aspect=1 # Width-to-height ratio of each subplot ) # Map the density plot to each subplot g.map( sns.kdeplot, "value", hue="category", # Differentiate by your categorical variable fill=True, # Fill under the density curve common_norm=False # Keep densities per subplot independent ) # Add a shared legend and clean up the layout g.add_legend(title="Category") plt.tight_layout() plt.show()
Key Notes:
col_wraplets you control how many subplots fit in each row, just likefacet_wrap’sncolparameter.- Using
pd.Categoricalwithordered=Trueensures your weekdays appear in the correct order (not alphabetical). common_norm=Falseensures each subplot’s density is scaled independently, which is often useful for comparing distributions across days.
Option 2: Manual Layout with Matplotlib subplots (Like R's grid.arrange)
If you want full control over every aspect of the subplot layout, use matplotlib’s subplots function. This is analogous to manually arranging plots with grid.arrange in R.
Example Code:
import matplotlib.pyplot as plt import seaborn as sns import pandas as pd import numpy as np # Reuse the same sample data (or replace with yours) df = pd.DataFrame({ "weekday": pd.Categorical( ["Mon", "Tue", "Wed", "Thu", "Fri", "Sat", "Sun"], categories=["Mon", "Tue", "Wed", "Thu", "Fri", "Sat", "Sun"], ordered=True ), "category": ["A", "B"] * 350, "value": np.random.normal(loc=0, scale=1, size=700) }) # Create a 3x3 grid of subplots (fits 7 weekdays with 2 empty spots) fig, axes = plt.subplots(nrows=3, ncols=3, figsize=(12, 9)) axes = axes.flatten() # Convert 2D array of axes to 1D for easier looping # Loop through each weekday and plot its density for idx, day in enumerate(df["weekday"].cat.categories): # Filter data for the current weekday day_data = df[df["weekday"] == day] # Plot density curves for each category sns.kdeplot( data=day_data, x="value", hue="category", fill=True, common_norm=False, ax=axes[idx] # Assign plot to the correct subplot axis ) # Customize subplot titles and labels axes[idx].set_title(f"Density: {day}") axes[idx].set_xlabel("Continuous Variable") axes[idx].set_ylabel("Density") # Hide any empty subplots (since 3x3=9, but we only have 7 days) for ax in axes[len(df["weekday"].cat.categories):]: ax.axis("off") # Clean up spacing between subplots plt.tight_layout() plt.show()
Key Notes:
figsizelets you control the overall size of the combined plot.- Flattening the axes array makes it easy to loop through each subplot position.
- You can fully customize each subplot (titles, labels, colors) individually if needed.
Which Should You Choose?
- Use Seaborn
FacetGridif you want a quick, clean solution that handles most of the layout work for you (perfect for replicatingfacet_wrap). - Use Matplotlib
subplotsif you need granular control over every part of the plot layout (likegrid.arrange).
内容的提问来源于stack exchange,提问作者SRVFan
相关产品推荐
相关产品推荐

