bbcstyle
bbcstyle is a lightweight Python package that applies a BBC News-inspired visual theme to Matplotlib and Seaborn plots. It helps you create clean, publication-ready charts with consistent typography, minimalist gridlines, and optional source annotations or logos. Inspired by the R package bbplot but tailored for Python, this theme is ideal for reports, dashboards, and data journalism.
Quick start
1. Install the package
pip install bbcstyle
2. Enable the theme
Call the theme hook once at the start of your script/notebook:
import bbcstyle as bbc
bbc.set_theme()
3. Finish figures with the finaliser
After you build your Matplotlib figure, call finalise_pot to add the BBC-style framing (title, subtitle, divider abot the source, and optional logo) and to save it if you provide a path.
Example A - line chart:
import matplotlib.pyplot as plt
import numpy as np
import bbcstyle as bbc
from bbcstyle import finalise_plot
bbc.set_theme()
x = np.arange(0, 24)
fig, ax = plt.subplots(figsize=(9, 5), dpi=150)
ax.plot(x, np.cumsum(np.random.normal(0, 0.8, size=x.size)), linewidth=2, label="North")
ax.plot(x, np.cumsum(np.random.normal(0, 0.8, size=x.size)), linewidth=2, label="South")
ax.plot(x, np.cumsum(np.random.normal(0, 0.8, size=x.size)), linewidth=2, label="East")
ax.plot(x, np.cumsum(np.random.normal(0, 0.8, size=x.size)), linewidth=2, label="West")
ax.legend(frameon=False, ncols=2)
ax.spines[["top", "right"]].set_visible(False)
ax.set_xlabel("Hour")
ax.set_ylabel("Index")
finalise_plot(
fig=fig,
title="Regional index over the day",
subtitle="Synthetic data, 24 hours",
source="Source: Example data",
logo_path=None, # e.g. "assets/bbc_logo.png"
output_path="out/line_chart.png", # omit to skip saving
dpi=300,
)
Example B - bar chart using theme colors
The theme defines the color cycle in axes.prop_cycle. Use it directly so bars follow the theme palette.
import matplotlib.pyplot as plt
import bbcstyle as bbc
from bbcstyle import finalise_plot
bbc.set_theme()
cats = ["A", "B", "C", "D", "E"]
vals = [5, 7, 3, 6, 4]
# Pull colors from the active theme cycle
colors = plt.rcParams["axes.prop_cycle"].by_key()["color"]
fig, ax = plt.subplots(figsize=(8, 5), dpi=150)
ax.bar(cats, vals, color=colors[: len(cats)])
ax.spines[["top", "right"]].set_visible(False)
ax.set_xlabel("Category")
ax.set_ylabel("Value")
finalise_plot(
fig=fig,
title="Example: Bar Chart",
subtitle="Five categories coloured by the theme",
source="Source: Example data",
logo_path=None,
output_path="out/bar_chart.png",
dpi=300,
)
Notes
-
Call
bbc.set_theme()before creating figures so rcParams apply to everything you draw. -
finalise_plot:
- Keeps your figure size unless you pass
enforce_size=True. - Places a divider a fixed distance (in points) above the source line.
- If
logo_pathandsourceare provided, the logo is anchored bottom-right, aligned to the source baseline.
- Keeps your figure size unless you pass
-
Avoid
plt.tight_layout()afterfinalise_plot; the finaliser manages margins for title/subtitle/source.
Gallery
examples/gallery/01_bar_chart.py
examples/gallery/02_line_chart.py
examples/gallery/03_scatter_plot.py
examples/gallery/04_histograms.py
examples/gallery/05_bubble_scatter.py
Run them to generate PNGs in examples/gallery/out/.
License
This project is licensed under the MIT License. See LICENSE for details.
Note: “BBC” is a trademark of the British Broadcasting Corporation. This project is not affiliated with, endorsed by, or sponsored by the BBC. “BBC-inspired” refers to the general look & feel of certain public graphics.
Issues & support
Found a bug or have a feature request? Please open an issue and include:
- a minimal code snippet that reproduces the problem
- your Python, Matplotlib, and Seaborn versions, plus OS
- what you expected vs what you observed, and any screenshots
See bug report and feature request for details.
Contributing
Contributions are welcome! A good first PR is often:
- a small fix to styling defaults,
- an additional gallery example in
examples/gallery/, - or a doc improvement.
See contributing for details.
Quick dev setup:
python -m venv .venv && source .venv/bin/activate
python -m pip install -U pip
python -m pip install -e .
python -m pip install -U pytest ruff pre-commit
pre-commit install
pytest -q
Guidelines
Open an issue before large changes. Keep examples pure-Python (no notebooks) and save images to examples/gallery/out/. Run ruff and the pre-commit hooks; keep PRs focused and small. Add or update a test when changing behavior. See contributing for details.
Code of Conduct
We follow the Contributor Covenant. By participating, you agree to uphold this standard.
Authorship & credits
Created and maintained by Alessandro Tomassini (@ale-tom). Thanks to contributors and the broader visualization community for inspiration. Any similarities to BBC graphics are purely stylistic; this project is independent of the BBC.
Citation
If this package helps your work, please cite it:
@software{bbcstyle,
title = {bbcstyle: BBC-inspired theme for Matplotlib/Seaborn},
author = {Alessandro Tomassini},
year = {2025},
version = {0.1.0},
url = {https://github.com/ale-tom/bbcstyle}
}
Metadata
Release files for bbcstyle 0.1.1
For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.
Source distribution (sdist)
| File | Size | Uploaded | |
|---|---|---|---|
| bbcstyle-0.1.1.tar.gz | 8.4 kB | Details |
Built distribution (wheel)
| File | Interpreter | ABI | Platform | Reset |
|---|---|---|---|---|
| bbcstyle-0.1.1-py3-none-any.whl | Python 3 | none | any | Details |
Total release size: 16.3 kB
Release files / bbcstyle-0.1.1.tar.gz
| Download URL | bbcstyle-0.1.1.tar.gz |
|---|---|
| Size | 8.4 kB |
| Tags | Source |
|
SHA-256 checksum How to use checksums |
d89d3aa63abfe26e8ebef91c9fc8a136731670ee05fc6bf6603378dfb11f00a1
|
|
BLAKE2b-256 checksum How to use checksums |
52f5395912ca47f58197265701e02d790bd1b34701ac54fa50d446657ca18973
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
Yes |
| Uploaded via |
twine/6.1.0 CPython/3.13.7
|
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.
PyPI Publish Attestation
PyPI verified that this artifact, at this checksum, originated from the publisher listed below.
Signed by GitHub Actions, verified by PyPI on Oct 17, 2025.
Transparency logRelease files / bbcstyle-0.1.1-py3-none-any.whl
| Download URL | bbcstyle-0.1.1-py3-none-any.whl |
|---|---|
| Size | 7.9 kB |
| Tags | Python 3 |
|
SHA-256 checksum How to use checksums |
d1c09125e53d55894c72c62a0e9009dd817a714a70ca9e8e53dbd9e04539dbd6
|
|
BLAKE2b-256 checksum How to use checksums |
1af5a7346a563e7b35c0634fac9b39d20f3380d003255fafb9adde5083088092
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
Yes |
| Uploaded via |
twine/6.1.0 CPython/3.13.7
|
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.
PyPI Publish Attestation
PyPI verified that this artifact, at this checksum, originated from the publisher listed below.
Signed by GitHub Actions, verified by PyPI on Oct 17, 2025.
Transparency log