CtrlK
BlogDocsLog inGet started
Tessl Logo

tessl/pypi-plotnine

A Grammar of Graphics for Python providing a declarative approach to data visualization similar to R's ggplot2

Pending
Overview
Eval results
Files

position-adjustments.mddocs/

Position Adjustments

Position adjustments modify the position of geometric objects to handle overlapping data points, create specialized layouts, and improve plot readability. They are essential for bar charts, box plots, and other visualizations where multiple data points share the same coordinate space.

Capabilities

Basic Position Adjustments

Core position adjustment functions for handling overlapping and grouped data.

def position_identity():
    """
    No position adjustment (default for most geoms).
    
    Objects are plotted at their exact data coordinates without any adjustment.
    Use when you want precise positioning or when overlapping is desired.
    """

def position_dodge(width=None):
    """
    Dodge overlapping objects side-by-side.
    
    Places overlapping objects next to each other horizontally. Essential
    for grouped bar charts, box plots, and other grouped visualizations.
    
    Parameters:
    - width: float, width of dodging in data units. Default uses 80% of
             the resolution of the data (0.8 * smallest difference between values)
    
    Usage: Grouped bar charts, side-by-side box plots, grouped points
    """

def position_dodge2(width=None, preserve='total', padding=0.1, reverse=False):
    """
    Enhanced dodging with additional control options.
    
    Improved version of position_dodge with better handling of different
    group sizes and more control over positioning behavior.
    
    Parameters:
    - width: float, dodging width
    - preserve: str, what to preserve when dodging ('total' or 'single')
    - padding: float, padding between groups
    - reverse: bool, whether to reverse the order of groups
    """

def position_stack():
    """
    Stack overlapping objects on top of each other.
    
    Cumulative positioning where each object is placed on top of the previous one.
    Standard for stacked bar charts and area plots.
    
    Usage: Stacked bar charts, stacked area plots, cumulative histograms
    """

def position_fill():
    """
    Stack objects and normalize to 100%.
    
    Like position_stack, but normalizes the total height to 1.0 (100%),
    showing proportions rather than absolute values.
    
    Usage: Proportional stacked bar charts, percentage area plots
    """

Jittering and Random Adjustments

Position adjustments that add controlled randomness to reduce overplotting.

def position_jitter(width=None, height=None, seed=None):
    """
    Add random noise to positions to reduce overplotting.
    
    Adds small random offsets to point positions to reveal overlapping
    data points. Essential for discrete variables with many observations.
    
    Parameters:
    - width: float, amount of horizontal jittering (data units)
    - height: float, amount of vertical jittering (data units)  
    - seed: int, random seed for reproducible jittering
    
    Default widths/heights are 40% of the resolution of the data.
    
    Usage: Scatter plots with discrete variables, strip charts
    """

def position_jitterdodge(jitter_width=None, jitter_height=None, dodge_width=None,
                         seed=None):
    """
    Combine dodging and jittering.
    
    First dodges groups side-by-side, then adds jittering within each group.
    Useful for grouped data with many overlapping points.
    
    Parameters:
    - jitter_width: float, width of jittering within groups
    - jitter_height: float, height of jittering
    - dodge_width: float, width of dodging between groups
    - seed: int, random seed
    
    Usage: Grouped scatter plots, grouped strip charts
    """

Nudging and Manual Adjustments

Functions for making small manual adjustments to object positions.

def position_nudge(x=0, y=0):
    """
    Nudge objects by constant offsets.
    
    Applies fixed offsets to object positions. Useful for fine-tuning
    placement of labels, annotations, or separating overlapping elements.
    
    Parameters:
    - x: float, horizontal offset in data units
    - y: float, vertical offset in data units
    
    Usage: Label positioning, annotation adjustments, creating separation
    """

Usage Patterns

Bar Chart Position Adjustments

# Default stacked bar chart
ggplot(data, aes(x='category', y='value', fill='group')) + \
    geom_col(position='stack')  # or position_stack()

# Side-by-side grouped bars
ggplot(data, aes(x='category', y='value', fill='group')) + \
    geom_col(position='dodge')  # or position_dodge()

# Proportional stacked bars (100% stacked)
ggplot(data, aes(x='category', y='value', fill='group')) + \
    geom_col(position='fill')  # or position_fill()

# Custom dodge width
ggplot(data, aes(x='category', y='value', fill='group')) + \
    geom_col(position=position_dodge(width=0.7))

Handling Overplotting with Jitter

# Basic jittered scatter plot
ggplot(data, aes(x='group', y='value')) + \
    geom_point(position='jitter')  # or position_jitter()

# Custom jitter amounts
ggplot(data, aes(x='treatment', y='response')) + \
    geom_point(position=position_jitter(width=0.2, height=0))

# Reproducible jittering
ggplot(data, aes(x='category', y='measurement')) + \
    geom_point(position=position_jitter(seed=123))

# Box plot with jittered points
ggplot(data, aes(x='group', y='value')) + \
    geom_boxplot() + \
    geom_point(position=position_jitter(width=0.2), alpha=0.6)

Grouped Visualizations

# Grouped box plots
ggplot(data, aes(x='treatment', y='response', fill='gender')) + \
    geom_boxplot(position='dodge')

# Grouped points with dodging and jittering
ggplot(data, aes(x='category', y='value', color='group')) + \
    geom_point(position=position_jitterdodge(dodge_width=0.8, jitter_width=0.2))

# Enhanced dodging for uneven groups
ggplot(data, aes(x='category', y='value', fill='treatment')) + \
    geom_col(position=position_dodge2(preserve='single'))

Label and Annotation Positioning

# Nudge labels away from points
ggplot(data, aes(x='x', y='y', label='name')) + \
    geom_point() + \
    geom_text(position=position_nudge(y=0.1))

# Nudge in both directions
ggplot(data, aes(x='score1', y='score2', label='student')) + \
    geom_point() + \
    geom_text(position=position_nudge(x=0.5, y=-0.2))

# Different nudging for different groups
ggplot(data, aes(x='x', y='y', label='text', color='group')) + \
    geom_point() + \
    geom_text(data=data.query('group == "A"'), 
              position=position_nudge(y=0.1)) + \
    geom_text(data=data.query('group == "B"'), 
              position=position_nudge(y=-0.1))

Advanced Position Combinations

# Stacked bars with error bars
summary_data = data.groupby(['category', 'group']).agg({
    'value': ['mean', 'std']
}).reset_index()

ggplot(summary_data, aes(x='category', y='value_mean', fill='group')) + \
    geom_col(position='stack') + \
    geom_errorbar(aes(ymin='value_mean - value_std', 
                     ymax='value_mean + value_std'),
                  position=position_dodge(width=0.9), width=0.2)

# Multiple position adjustments in layers
ggplot(data, aes(x='treatment', y='response', fill='gender')) + \
    geom_boxplot(position='dodge', alpha=0.7) + \
    geom_point(position=position_jitterdodge(), alpha=0.3) + \
    stat_summary(fun='mean', geom='point', 
                position=position_dodge(width=0.75), 
                color='red', size=3)

Histogram and Density Position Adjustments

# Stacked histogram
ggplot(data, aes(x='value', fill='group')) + \
    geom_histogram(position='stack', bins=20)

# Side-by-side histogram (dodged)
ggplot(data, aes(x='value', fill='group')) + \
    geom_histogram(position='dodge', bins=20)

# Identity position for overlapping histograms
ggplot(data, aes(x='value', fill='group')) + \
    geom_histogram(position='identity', alpha=0.6, bins=20)

# Fill position for proportional histogram
ggplot(data, aes(x='value', fill='group')) + \
    geom_histogram(position='fill', bins=20)

Time Series and Line Plots

# Dodged points in time series
ggplot(time_data, aes(x='date', y='value', color='series')) + \
    geom_point(position=position_dodge(width=1)) + \
    geom_line(aes(group='series'))

# Jittered time points to reduce overlap
ggplot(events_data, aes(x='timestamp', y='category', color='type')) + \
    geom_point(position=position_jitter(height=0.1))

Statistical Plots with Position Adjustments

# Mean and error bars with dodging
ggplot(data, aes(x='treatment', y='response', fill='gender')) + \
    stat_summary(fun='mean', geom='col', position='dodge') + \
    stat_summary(fun_data='mean_se', geom='errorbar', 
                position=position_dodge(width=0.9), width=0.2)

# Violin plots with dodging
ggplot(data, aes(x='group', y='measurement', fill='condition')) + \
    geom_violin(position='dodge') + \
    geom_boxplot(position=position_dodge(width=0.9), width=0.1)

Customizing Position Parameters

# Fine-tune dodging width
ggplot(data, aes(x='category', y='value', fill='group')) + \
    geom_col(position=position_dodge(width=0.8)) + \
    geom_text(aes(label='value'), 
              position=position_dodge(width=0.8), vjust=-0.5)

# Control jitter seed for reproducibility
set.seed(123)  # For consistent jittering across runs
ggplot(data, aes(x='treatment', y='response')) + \
    geom_boxplot() + \
    geom_point(position=position_jitter(width=0.3, seed=123), alpha=0.6)

# Combine multiple position adjustments
ggplot(data, aes(x='category', y='value', color='group')) + \
    geom_point(position=position_jitterdodge(
        jitter_width=0.2, jitter_height=0.1, dodge_width=0.8
    ), alpha=0.7) + \
    stat_summary(fun='mean', geom='point', size=3,
                position=position_dodge(width=0.8))

Position Adjustment Best Practices

Choosing the Right Position Adjustment

# For categorical x with continuous y and groups:
# - position_dodge: Compare groups side-by-side  
# - position_stack: Show totals and contributions
# - position_fill: Show proportions

# For overplotting:
# - position_jitter: Discrete variables
# - position_identity with alpha: Continuous variables

# For labels:
# - position_nudge: Small manual adjustments
# - position_dodge: Align with dodged geoms

Consistent Position Parameters

# Use same dodge width across layers
dodge_width = 0.8

ggplot(data, aes(x='group', y='value', fill='treatment')) + \
    geom_col(position=position_dodge(width=dodge_width)) + \
    geom_errorbar(aes(ymin='value - se', ymax='value + se'),
                  position=position_dodge(width=dodge_width), width=0.2) + \
    geom_text(aes(label='label'), 
              position=position_dodge(width=dodge_width), vjust=-0.5)

Install with Tessl CLI

npx tessl i tessl/pypi-plotnine

docs

aesthetic-mappings.md

coordinate-systems.md

core-plotting.md

faceting.md

geometric-objects.md

guides-and-legends.md

index.md

labels-and-annotations.md

position-adjustments.md

sample-datasets.md

scales-and-axes.md

statistical-transformations.md

themes-and-styling.md

watermarks.md

tile.json