mgplot
Description
mgplot is an open-source Python frontend for matplotlib designed for time-series chart creation with PeriodIndex data. It simplifies common economic and financial plots while:
- producing time-series charts that can be tricky to create directly,
- finalising (or publishing) charts with titles, labels, annotations, etc.,
- minimising code duplication, and maintaining a consistent style.
Installation
pip install mgplot
Or using uv:
uv add mgplot
Requirements: Python 3.10+, pandas, matplotlib, numpy
Import
import mgplot as mg
Quick Example
import pandas as pd
import mgplot as mg
# Create sample data with PeriodIndex
data = pd.Series(
[100, 102, 105, 103, 108],
index=pd.period_range("2024Q1", periods=5, freq="Q")
)
# Plot and finalise in one step
mg.line_plot_finalise(data, title="Quarterly Data", ylabel="Value")
Plot Functions
All plot functions take a pandas Series or DataFrame with a PeriodIndex as the first argument and return a matplotlib Axes object. Keyword arguments control styling and behavior:
bar_plot()-- bar plot (grouped or stacked) with intelligent PeriodIndex labeling;horizontal=Trueplots categorical data as horizontal bars (categories on the y-axis, values along the x-axis)fill_between_plot()-- shaded region between two bounds (requires 2-column DataFrame)growth_plot()-- plots annual and periodic growth rates (requires 2-column DataFrame with pre-calculated growth)line_plot()-- one or more lines with optional annotationspostcovid_plot()-- data as a line with pre-COVID linear projectionrevision_plot()-- designed to plot ABS-style data revisionsrun_plot()-- line plot with background highlighting for monotonic increasing/decreasing runsseastrend_plot()-- seasonal and trend components on one plotseries_growth_plot()-- calculates and plots annual (line) and periodic (bars) growth from a single Seriessummary_plot()-- latest data point against historical range with z-score visualization
For ranked-category charts (states, industries, expenditure classes),
use horizontal=True with a string-indexed Series or DataFrame:
vacancies = vacancies.sort_values() # smallest at the bottom
mg.bar_plot_finalise(
vacancies,
horizontal=True,
annotate=True, # value labels at the bar ends
above=True,
x0=True, # zero line on the value axis
title="Job vacancies by industry",
xlabel="'000",
)
horizontal=True is for categorical data: with a PeriodIndex it warns
and falls back to a vertical plot.
Finalising Plots
Once a plot is generated, finalise it with titles, labels, and save to file:
ax = mg.line_plot(data)
mg.finalise_plot(ax, title="My Chart", ylabel="Units", tag="my_chart")
Axis Tick Labels
For PeriodIndex data, x-axis tick labels are generated contextually:
the tick density is chosen to fit within max_ticks, and labels show
the period with years marked at transitions (e.g. a monthly axis shows
Feb Mar ... 2024 ... Feb, a quarterly axis shows Q2 Q3 2025 Q2).
Three keyword arguments control the labels on the period-indexed plot
functions (line_plot, bar_plot, growth_plot, fill_between_plot,
run_plot, and their *_finalise variants):
max_ticks-- the maximum number of ticks (suggestive, not exact). The global default ismg.get_setting("max_ticks").tick_relabel-- a callable applied to each generated label string, after the contextual labelling has run. Use it to restyle labels without losing the transition logic.label_rotation-- (bar_plotonly) rotates the x-axis tick labels.
For example, to convert 4-digit year labels to 2-digit years:
import re
def two_digit_years(label: str) -> str:
"""Shorten 4-digit years to 2 digits (e.g. 2024 -> 24)."""
return re.sub(r"\b(?:19|20)(\d{2})\b", r"\1", label)
# default labels: 2010 2012 2014 ... 2024 2026
# with tick_relabel: 10 12 14 ... 24 26
mg.line_plot_finalise(data, title="My Chart", tick_relabel=two_digit_years)
Because tick_relabel operates on the label strings, this works
unchanged on quarterly or monthly axes too: a label such as 2024
marking a year transition becomes 24, while the Q2/Mar labels
between transitions pass through untouched.
These options are stashed on the matplotlib Axes when the plot is drawn,
and finalise_plot() honours them when it refreshes the tick labels
just before saving. Editing tick labels directly on the Axes (e.g. with
set_xticklabels()) does not survive that refresh -- use tick_relabel
instead.
Multi-Panel Figures
finalise_plot() works on a single Axes. For a figure with several
panels, finalise each panel with axes_only=True (axes-level styling
only: titles, labels, legends), then make the last call a normal
finalise_plot() carrying the figure-level arguments (suptitle,
lfooter, rfooter, figsize, ...), which also saves and closes
the figure:
fig, (ax_left, ax_right) = plt.subplots(1, 2)
mg.line_plot(left_data, ax=ax_left)
mg.line_plot(right_data, ax=ax_right)
mg.finalise_plot(ax_left, title="Left Panel", ylabel="Index", axes_only=True)
mg.finalise_plot(
ax_right,
title="Right Panel",
ylabel="Index",
suptitle="Both Panels Together", # also used for the filename
lfooter="Australia. Seasonally adjusted.",
rfooter="Source: ABS",
figsize=(9, 4.5),
)
Convenience Finalisers
For every plot function, there is a *_finalise() variant that combines
the plot and finalise steps:
bar_plot_finalise()fill_between_plot_finalise()growth_plot_finalise()line_plot_finalise()postcovid_plot_finalise()revision_plot_finalise()run_plot_finalise()seastrend_plot_finalise()series_growth_plot_finalise()summary_plot_finalise()
Multi-Plot Chaining
Chain plotting operations together for batch processing:
plot_then_finalise()-- chains a plot function withfinalise_plot()multi_start()-- creates multiple plots with different start datesmulti_column()-- creates separate plots for each DataFrame column
Settings and Configuration
Manage global defaults for figure size, colors, output directory, etc.:
mg.set_setting("figsize", (10, 5))
mg.set_setting("dpi", 150)
mg.set_chart_dir("./charts")
# Get current setting
current_dpi = mg.get_setting("dpi")
Color Utilities
Built-in support for Australian state/territory and political party colors:
mg.get_color("NSW") # Returns 'deepskyblue'
mg.get_color("Labor") # Returns Labor party color
mg.colorise_list(["NSW", "VIC", "QLD"]) # Returns list of colors
Documentation
API documentation is generated from docstrings using pdoc. To view locally:
# Generate and serve docs
uv run pdoc src/mgplot
# Or open the pre-built docs
open docs/mgplot.html
Development
# Install dependencies
uv sync
# Run type checking
uv run pyright src/
# Run linting
uv run ruff check src/
uv run ruff format src/
License
MIT License - see LICENSE file for details.
Release files for mgplot 0.2.34
For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.
Source distribution (sdist)
| File | Size | Uploaded | |
|---|---|---|---|
| mgplot-0.2.34.tar.gz | 2.7 MB | Details |
Built distribution (wheel)
| File | Interpreter | ABI | Platform | Reset |
|---|---|---|---|---|
| mgplot-0.2.34-py3-none-any.whl | Python 3 | none | any | Details |
Total release size: 2.8 MB
Release files / mgplot-0.2.34.tar.gz
| Download URL | mgplot-0.2.34.tar.gz |
|---|---|
| Size | 2.7 MB |
| Tags | Source |
|
SHA-256 checksum How to use checksums |
d8b880230ec243c1be1ec639fd1aaf3f303803c6d2db14ad2271d858c4c666d1
|
|
BLAKE2b-256 checksum How to use checksums |
af9ea8bcb250c10dbcd159ac783e3f2a8ffbc5b9b12ee44320cba4c4189eb11b
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
uv/0.9.22 {"installer":{"name":"uv","version":"0.9.22","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":{"name":"macOS","version":null,"id":null,"libc":null},"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":null}
|
Release files / mgplot-0.2.34-py3-none-any.whl
| Download URL | mgplot-0.2.34-py3-none-any.whl |
|---|---|
| Size | 63.8 kB |
| Tags | Python 3 |
|
SHA-256 checksum How to use checksums |
cddaf5746d3346d01d8c0c08a3296d3f315dc75ce6d16d9815cbea7553d5f5e2
|
|
BLAKE2b-256 checksum How to use checksums |
ee3d5ef5902be17560635e42a99152bf2df0bac097fdb0cef9021ff73ab74c29
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
uv/0.9.22 {"installer":{"name":"uv","version":"0.9.22","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":{"name":"macOS","version":null,"id":null,"libc":null},"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":null}
|