Skip to main content

pybumpchart

A Python library for creating bump chart visualizations showing how rankings change over time.

PyPI version Python 3.9+ License: MIT

Installation

pip install pybumpchart

For seaborn color palette support:

pip install pybumpchart[seaborn]

Quick Start

import pandas as pd
import pybumpchart as bc

# Create sample data
df = pd.DataFrame({
    'year': [2020, 2020, 2020, 2021, 2021, 2021, 2022, 2022, 2022],
    'team': ['A', 'B', 'C', 'A', 'B', 'C', 'A', 'B', 'C'],
    'rank': [1, 2, 3, 3, 1, 2, 2, 3, 1]
})

# Create a bump chart
ax = bc.bumpchart(df, time_col='year', entity_col='team', rank_col='rank')
ax.figure.savefig('bumpchart.png')

Features

  • Automatic rank calculation: Provide values and let pybumpchart calculate ranks
  • Multiple tie-breaking methods: average, min, max, first, dense
  • Customizable appearance: colors, line widths, markers, labels
  • Entity highlighting: Emphasize specific entities while dimming others
  • Label collision avoidance: Automatic adjustment of overlapping labels
  • Matplotlib integration: Returns standard Axes objects for further customization

API Reference

bumpchart()

The main function for creating bump charts.

bc.bumpchart(
    df,                          # DataFrame with your data
    time_col,                    # Column name for time values (x-axis)
    entity_col,                  # Column name for entity identifiers
    rank_col=None,               # Column with pre-calculated ranks
    value_col=None,              # Column with values to rank by
    ascending=True,              # Lower values = better rank (when using value_col)
    tie_method='average',        # How to handle ties: 'average', 'min', 'max', 'first', 'dense'
    ax=None,                     # Existing matplotlib Axes to draw on
    figsize=(10, 6),             # Figure size if creating new figure
    palette=None,                # Color palette: colormap name, list, or None for default
    highlight=None,              # List of entities to highlight
    highlight_color=None,        # Custom color for highlighted entities
    show_labels=True,            # True, False, 'left', 'right', or 'both'
    label_padding=0.3,           # Distance between line and label
    min_label_distance=0.5,      # Minimum vertical space between labels
    label_fontsize=10,           # Font size for labels
    linewidth=2.5,               # Line thickness
    markersize=10.0,             # Marker size
    marker='o',                  # Marker style
    show_grid=True,              # Show horizontal grid lines
    show_points=True,            # Show markers at each time point
)

Returns: matplotlib.axes.Axes - The axes containing the bump chart.

Examples

Using Pre-calculated Ranks

import pandas as pd
import pybumpchart as bc

df = pd.DataFrame({
    'year': [2020, 2020, 2020, 2021, 2021, 2021],
    'team': ['Warriors', 'Lakers', 'Celtics', 'Warriors', 'Lakers', 'Celtics'],
    'rank': [1, 2, 3, 2, 1, 3]
})

ax = bc.bumpchart(df, time_col='year', entity_col='team', rank_col='rank')

Calculating Ranks from Values

df = pd.DataFrame({
    'quarter': ['Q1', 'Q1', 'Q1', 'Q2', 'Q2', 'Q2'],
    'product': ['Widget', 'Gadget', 'Gizmo', 'Widget', 'Gadget', 'Gizmo'],
    'sales': [1000, 800, 900, 850, 950, 920]
})

# Higher sales = better rank (rank 1)
ax = bc.bumpchart(
    df,
    time_col='quarter',
    entity_col='product',
    value_col='sales',
    ascending=False  # Higher values get lower (better) ranks
)

Highlighting Specific Entities

ax = bc.bumpchart(
    df,
    time_col='year',
    entity_col='team',
    rank_col='rank',
    highlight=['Warriors'],
    palette='tab10'
)

Custom Styling

ax = bc.bumpchart(
    df,
    time_col='year',
    entity_col='team',
    rank_col='rank',
    palette=['#e41a1c', '#377eb8', '#4daf4a'],  # Custom colors
    linewidth=4,
    markersize=12,
    show_labels='right',  # Labels only on the right
    figsize=(12, 8)
)

# Further customize with matplotlib
ax.set_title('Team Rankings Over Time', fontsize=14)
ax.set_xlabel('Year')
ax.set_ylabel('Rank')

Using with Existing Axes

import matplotlib.pyplot as plt

fig, (ax1, ax2) = plt.subplots(1, 2, figsize=(16, 6))

bc.bumpchart(df1, time_col='year', entity_col='team', rank_col='rank', ax=ax1)
ax1.set_title('Sports Rankings')

bc.bumpchart(df2, time_col='quarter', entity_col='product', value_col='sales', ax=ax2)
ax2.set_title('Product Sales Rankings')

plt.tight_layout()
plt.savefig('comparison.png')

Data Format

Your DataFrame should have:

  1. Time column: Values representing time periods (years, quarters, dates, etc.)
  2. Entity column: Identifiers for the items being ranked (team names, product names, etc.)
  3. Rank or value column: Either pre-calculated ranks OR values to rank by

Each entity should appear once per time period.

Dependencies

  • Python >= 3.9
  • matplotlib >= 3.5
  • pandas >= 1.4
  • numpy >= 1.21
  • seaborn >= 0.12 (optional, for extended palette support)

Contributing

Contributions are welcome! Please feel free to submit a Pull Request.

License

MIT License - see LICENSE for details.

Metadata

Release files for pybumpchart 0.1.0

For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.

Source distribution (sdist)

Source distribution for pybumpchart 0.1.0
File Size Uploaded Provenance Actions
pybumpchart-0.1.0.tar.gz 18.3 kB Without provenance Details for pybumpchart-0.1.0.tar.gz

Built distribution (wheel)

Table of built distributions (wheels) for pybumpchart 0.1.0
File Interpreter ABI Platform Actions
pybumpchart-0.1.0-py3-none-any.whl Python 3 none any Details for pybumpchart-0.1.0-py3-none-any.whl

Total release size: 33.8 kB

Release files / pybumpchart-0.1.0.tar.gz

Download URL pybumpchart-0.1.0.tar.gz
Size 18.3 kB
Tags Source
SHA-256 checksum
How to use checksums
0f99c072bb44e64de5a1bafe0732710cc7fa9953e7f4b7a6a1cd2aa8e28d1c27
BLAKE2b-256 checksum
How to use checksums
5e32d850d333e551ee91b2a54ede23ccd48a8c60d5c258c0fce9a81fe4787f48
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via twine/6.2.0 CPython/3.13.9

Release files / pybumpchart-0.1.0-py3-none-any.whl

Download URL pybumpchart-0.1.0-py3-none-any.whl
Size 15.5 kB
Tags Python 3
SHA-256 checksum
How to use checksums
db4c7d27dab18c8b5f425fc1caaf03b1aa6846aaef75a1e4015a7572c739fc4a
BLAKE2b-256 checksum
How to use checksums
4b86e429e53446a4a845f59db456a2a48095a9cb6d03dada89c19de6a6d2c2df
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via twine/6.2.0 CPython/3.13.9

Security for pybumpchart 0.1.0

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

No provenance found

None of the files in this release were uploaded with provenance metadata.

A note on package security

PyPI is a repository for distributing packages, not a service for auditing them. While third-party security researchers and our staff do their best to detect and remove malicious packages, PyPI cannot guarantee the quality, security or suitability of any given package.

To learn more about protecting yourself from malicious actors, visit our package security documentation.

Release history Release notifications | RSS feed

This release

0.1.0 This release

2 release files No provenance

Anthropic, PBC Visionary sponsor Bloomberg Visionary sponsor Hudson River Trading Visionary sponsor Meta Visionary sponsor NVIDIA Visionary sponsor Microsoft Sustainability sponsor Depot Continuous Integration AWS Cloud computing and Security Sponsor Datadog Monitoring Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page