Python中是否有类gridExtra/cowplot的包配合Plotnine实现子图(含边际分布)对齐?
Great question! Aligning subplots—especially creating marginal plots like scatterplots with histograms/density plots—with plotnine is definitely feasible in Python, even if the official docs don’t spell it out clearly. Let’s break down your questions and practical solutions:
Current Workarounds (No Wait for Plotnine Extensions)
You don’t need to rely on plotnine adding support for matplotlib’s geometry manager (from MEP #1109) right now. Here are two solid approaches to get perfectly aligned plots:
1. Manual Alignment with Matplotlib GridSpec
Since plotnine plots are built on matplotlib, you can convert them to matplotlib axes objects and use GridSpec to precisely control layout. This is the most flexible method for creating marginal plots:
from plotnine import ggplot, aes, geom_point, geom_histogram, theme_minimal, coord_flip from matplotlib.gridspec import GridSpec import matplotlib.pyplot as plt import pandas as pd import numpy as np # Generate sample data df = pd.DataFrame({ 'x': np.random.normal(0, 1, 1000), 'y': np.random.normal(0, 1, 1000) }) # Create individual plotnine plots scatter_plot = (ggplot(df, aes('x', 'y')) + geom_point(alpha=0.5) + theme_minimal() + theme(axis_title_x='', axis_title_y='')) top_hist = (ggplot(df, aes('x')) + geom_histogram(bins=20, fill='steelblue', alpha=0.6) + theme_minimal() + theme(axis_title_x='', axis_text_x='', axis_ticks_major_x='', axis_title_y='', axis_text_y='', axis_ticks_major_y='')) right_hist = (ggplot(df, aes('y')) + geom_histogram(bins=20, fill='steelblue', alpha=0.6) + theme_minimal() + theme(axis_title_x='', axis_text_x='', axis_ticks_major_x='', axis_title_y='', axis_text_y='', axis_ticks_major_y='') + coord_flip()) # Convert plotnine plots to matplotlib axes objects scatter_ax = scatter_plot.draw().axes top_ax = top_hist.draw().axes right_ax = right_hist.draw().axes # Set up grid layout fig = plt.figure(figsize=(8, 8)) gs = GridSpec(2, 2, width_ratios=[4, 1], height_ratios=[1, 4]) # Assign axes to grid positions main_ax = fig.add_subplot(gs[1, 0]) top_ax_sub = fig.add_subplot(gs[0, 0]) right_ax_sub = fig.add_subplot(gs[1, 1]) # Copy plot content from plotnine axes to grid axes def transfer_plot_content(src, dest): for artist in src.get_children(): if isinstance(artist, (plt.Line2D, plt.Patch, plt.Text)): dest.add_artist(artist) dest.set_xlim(src.get_xlim()) dest.set_ylim(src.get_ylim()) transfer_plot_content(scatter_ax, main_ax) transfer_plot_content(top_ax, top_ax_sub) transfer_plot_content(right_ax, right_ax_sub) # Clean up redundant ticks/labels top_ax_sub.tick_params(axis='both', which='both', bottom=False, left=False, labelbottom=False, labelleft=False) right_ax_sub.tick_params(axis='both', which='both', bottom=False, left=False, labelbottom=False, labelleft=False) # Adjust spacing for perfect alignment plt.tight_layout() plt.show()
2. Hybrid Approach with Seaborn JointGrid
If you want a quicker setup for marginal plots, you can use Seaborn’s JointGrid (which handles alignment natively) and add plotnine elements to it. This is less "pure" plotnine, but it’s a huge time-saver:
import seaborn as sns from plotnine import ggplot, aes, geom_point, theme_minimal # Initialize JointGrid g = sns.JointGrid(data=df, x='x', y='y') # Add plotnine scatter plot to the main axis g.ax_joint.clear() _ = (ggplot(df, aes('x', 'y')) + geom_point(alpha=0.5) + theme_minimal()) g.ax_joint = plt.gca() # Add marginal histograms with Seaborn g.plot_marginals(sns.histplot, bins=20, fill='steelblue', alpha=0.6) plt.show()
Plotnine Support for Matplotlib’s Geometry Manager
As of 2024, plotnine hasn’t officially extended support for the geometry manager from MEP #1109. However, since plotnine is built directly on matplotlib, the manual alignment method above works reliably. There’s definitely demand for a plot_grid-style function (like cowplot) in plotnine—you can see this from active discussions in the plotnine GitHub repo and community forums.
If you want to simplify this workflow long-term, you could even wrap the GridSpec logic into a reusable function that mimics cowplot’s plot_grid behavior for plotnine plots.
内容的提问来源于stack exchange,提问作者codingknob

