Releases: Ultraplot/UltraPlot
Bug fixes for Geo dms coordinates and reverse colors/colormaps
What's Changed
- Add citation metadata (CITATION.cff, .zenodo.json) to support scholarly use by @cvanelteren in #284
- Update CITATON.cff by @cvanelteren in #286
- Add citation links to README. by @cvanelteren in #287
- Mv dynamic function to the subplotgrid by @cvanelteren in #281
- add downloads badge by @cvanelteren in #290
- replace color to orange by @cvanelteren in #291
- Hotfix add all locations to colorbar label by @cvanelteren in #295
- Fix DMS not set on some projections by @cvanelteren in #293
- Bump mamba-org/setup-micromamba from 2.0.4 to 2.0.5 in the github-actions group by @dependabot in #299
- fix late binding and proper reversal for funcs by @cvanelteren in #296
Full Changelog: v1.57.1...v1.57.2
Zenodo release
This PR integrates Zenodo with the UltraPlot repository to enable citation via DOI.
From now on, every GitHub release will be archived by Zenodo and assigned a unique DOI, allowing researchers and users to cite UltraPlot in a standardized, persistent way.
We’ve also added a citation file and BibTeX entry for convenience. Please refer to the GitHub “Cite this repository” section or use the provided BibTeX in your work.
This marks an important step in making UltraPlot more visible and citable in academic and scientific publications.
🔗 DOI: https://doi.org/10.5281/zenodo.15733565
Cite as
@software{vanElteren2025,
author = {Casper van Elteren and Matthew R. Becker},
title = {UltraPlot: A succinct wrapper for Matplotlib},
year = {2025},
version = {1.57.1},
publisher = {GitHub},
url = {https://github.com/Ultraplot/UltraPlot}
}
What's Changed
- Fix a few tests by @cvanelteren in #267
- set rng per test by @cvanelteren in #268
- Add xdist to image compare by @cvanelteren in #266
- Fix issue where view is reset on setting ticklen by @cvanelteren in #272
- Racing condition xdist fix by @cvanelteren in #273
- Replace spring with forceatlas2 by @cvanelteren in #275
- Revert xdist addition by @cvanelteren in #277
- fix: pass layout_kw in network test function by @beckermr in #278
- fix: this one needs a seed too by @beckermr in #279
- rm paren by @cvanelteren in #280
Full Changelog: v1.57...v1.57.1
v1.57 Support matplotlib 3.10 and python 3.13
What's Changed
- Fix unused parameters being passed to pie chart by @cvanelteren in #260
- Update return requirements pytest 8.4.0 by @cvanelteren in #265
- Bump python to 3.13 by @cvanelteren in #264
- Update matplotlib to mpl 3.10 by @cvanelteren in #263
Full Changelog: v1.56...v1.57
v1.56 🐝 Feature addition: Beeswarm plot
We are introducing a new plot type with this release: a beeswarm plot. A beeswarm plot is a data visualization technique that displays individual data points in a way that prevents overlap while maintaining their relationship to categorical groups, creating a distinctive "swarm" pattern that resembles bees clustering around a hive.
Unlike traditional box plots or violin plots that aggregate data, beeswarm plots show every individual observation, making them ideal for datasets with moderate sample sizes where you want to see both individual points and overall distribution patterns, identify outliers clearly, and compare distributions across multiple categories without losing any information through statistical summaries.
This plot mimics the beeswarm from SHAP
library, but lacks the more sophisticated patterns they apply such as inline group clustering. UltraPlot does not aim to add these features but instead provide an interface that is simpler that users can tweak to their hearts desires.
snippet
import ultraplot as uplt, numpy as np
# Create mock data
n_points, n_features = 50, 4
features = np.arange(n_features)
data = np.empty((n_points, n_features))
feature_values = np.repeat(
features,
n_points,
).reshape(data.shape)
for feature in features:
data[:, feature] = np.random.normal(feature * 1.5, 0.6, n_points)
cmap = uplt.Colormap(uplt.rc["cmap.diverging"])
# Create plot and style
fig, (left, right) = uplt.subplots(ncols=2, share=0)
left.beeswarm(
data,
orientation="vertical",
alpha=0.7,
cmap=cmap,
)
left.format(
title="Traditional Beeswarm Plot",
xlabel="Category",
ylabel="Value",
xticks=features,
xticklabels=["Group A", "Group B", "Group C", "Group D"],
)
right.beeswarm(
data,
feature_values=feature_values,
cmap=cmap,
colorbar="right",
)
right.format(
title="Feature Value Beeswarm Plot",
xlabel="SHAP Value",
yticks=features,
yticklabels=["A", "B", "C", "D"],
ylabel="Feature",
)
uplt.show(block=1)
What's Changed
- Hotfix GeoAxes indicate zoom. by @cvanelteren in #249
- Feature: Beeswarm plot by @cvanelteren in #251
- GeoTicks not responsive by @cvanelteren in #253
- add top level ignores for local testing by @cvanelteren in #255
- Update .gitignore by @cvanelteren in #257
- Refactor beeswarm by @cvanelteren in #254
Full Changelog: V1.55...v1.56
V1.55. Bug fixes.
This release continues our ongoing mission to squash pesky bugs and make your plotting experience smoother and more intuitive.
✨ New Features
-
Centered Labels for pcolormesh
You can now enable center_labels when using pcolormesh, making it easier to annotate discrete diverging colormaps—especially when including zero among the label values. Ideal for visualizing data with meaningful central thresholds. -
Direct Bar Labels for bar and hbar
Bar labels can now be added directly via the bar and hbar commands. No more extra steps—just call the method and get your labeled bars out of the box.
🐞 Bug Fixes
Various internal improvements and minor bug fixes aimed at ensuring a more robust and predictable plotting experience.
As always, thank you for using UltraPlot! Feedback, issues, and contributions are welcome.
What's Changed
- Cartesian docs links fixed by @cvanelteren in #226
- minor fix for mpl3.10 by @cvanelteren in #229
- Adjust the ticks to center on 'nice' values by @cvanelteren in #228
- rm unnecessary show by @cvanelteren in #241
- Feat bar labels by @cvanelteren in #240
- Fix links for 1d plots in docs by @cvanelteren in #242
- Deprecate basemap by @cvanelteren in #243
- Hotfix get_border_axes by @cvanelteren in #236
- Hotfix panel by @cvanelteren in #238
- Hot fix twinned y labels by @cvanelteren in #246
Full Changelog: v1.50.2...V1.55
v1.50.2
What's Changed
- perf: run comparison tests at the same time as the main tests by @beckermr in #213
- fix cycler setting to 1 when only 1 column is parsed by @cvanelteren in #218
- Skip sharing logic when colorbar is added to GeoPlots. by @cvanelteren in #219
- Restore redirection for tricontourf for GeoPlotting by @cvanelteren in #222
- Fix numerous geo docs visuals by @cvanelteren in #223
- Allow rasterization on GeoFeatures. by @cvanelteren in #220
- more fixes by @cvanelteren in #224
- Docs fix3 by @cvanelteren in #225
Full Changelog: v1.50.1...v1.50.2
v1.50.1
v1.50: Networks, lollipops and sharing
UltraPlot v1.50
Version v1.50 is a major milestone for UltraPlot. As we become more familiar with the codebase, we’ve opened the door to new features—balancing innovation with continuous backend improvements and bug fixes.
🌍 GeoAxes Sharing
You can now share axes between subplots using GeoAxes, as long as they use the same rectilinear projection. This enables cleaner, more consistent layouts when working with geographical data. |
![]() |
🕸️ Network Graphs
UltraPlot now supports network visualizations out of the box. With smart defaults and simple customization options, creating beautiful network plots is easier than ever. |
![]() |
Network plotting code
import networkx as nx, ultraplot as uplt
n = 100
g = nx.random_geometric_graph(n, radius=0.2)
c = uplt.colormaps.get_cmap("viko")
c = c(np.linspace(0, 1, n))
node = dict(
node_size=np.random.rand(n) * 100,
node_color=c,
)
fig, ax = uplt.subplots()
ax.graph(g, layout="kamada_kawai", node_kw=node)
fig.show()
🍭 Lollipop Graphs
A sleek alternative to bar charts, lollipop graphs are now available directly through UltraPlot. They shine when visualizing datasets with many bars, reducing visual clutter while retaining clarity. |
![]() |
Lollipop example code
import ultraplot as uplt, pandas as pd, numpy as np
data = np.random.rand(5, 5).cumsum(axis=0).cumsum(axis=1)[:, ::-1]
data = pd.DataFrame(
data,
columns=pd.Index(np.arange(1, 6), name="column"),
index=pd.Index(["a", "b", "c", "d", "e"], name="row idx"),
)
fig, ax = uplt.subplots(ncols=2, share=0)
ax[0].lollipop(
data,
stemcolor="green",
stemwidth=2,
marker="d",
edgecolor="k",
)
ax[1].lollipoph(data, linestyle="solid")
What's Changed
- separate logger for ultraplot and matplotlib by @cvanelteren in #178
- Capture warning by @cvanelteren in #180
- tmp turning of test by @cvanelteren in #183
- Skip missing tests if added in PR by @cvanelteren in #175
- Revert "Skip missing tests if added in PR" by @beckermr in #184
- rm conftest from codecov by @cvanelteren in #187
- skip tests properly by @cvanelteren in #186
- Fix colorbar loc by @cvanelteren in #182
- Fix bar alpha by @cvanelteren in #192
- make import uplt to be consistent with rest of repo by @cvanelteren in #195
- Ensure that shared labels are consistently updated. by @cvanelteren in #177
- sensible defaults and unittest by @cvanelteren in #189
- Deprecation fix mpl 3.10 and beyond by @cvanelteren in #69
- Add network plotting to UltraPlot by @cvanelteren in #169
- Hotfix test by @cvanelteren in #196
- Discrete colors for quiver by @cvanelteren in #198
- correct url for basemap objects by @cvanelteren in #202
- override logx/y/log with updated docstring by @cvanelteren in #203
- Add lollipop graph by @cvanelteren in #194
- Fix network linking in docs and api refs by @cvanelteren in #205
- Avoid getting edges and setting centers for some shaders by @cvanelteren in #208
- Fix some references in inset docs by @cvanelteren in #209
- rm dep warning by @cvanelteren in #210
- [Feature add] Share Axes in GeoPlot + bug fixes by @cvanelteren in #159
Full Changelog: v1.11...v1.5
Various bug fixes
What's Changed
- Update intersphinx links by @cvanelteren in #128
- Update geo doc by @cvanelteren in #129
- Hotfix update geo doc by @cvanelteren in #130
- New site, who dis? by @cvanelteren in #132
- Add about page by @cvanelteren in #133
- Make it mobile friendly by @cvanelteren in #134
- Add gallery to github page by @cvanelteren in #140
- Fix readme by @cvanelteren in #142
- Fix readme fixed sizes by @cvanelteren in #143
- added page for errors by @cvanelteren in #141
- Bump dawidd6/action-download-artifact from 2 to 6 in /.github/workflows by @dependabot in #144
- fix: checkout from correct fork by @beckermr in #145
- Set seed prior to test to ensure fidelity by @cvanelteren in #148
- Move warning inside pytest config by @cvanelteren in #151
- Fix scaler parsing by @cvanelteren in #153
- Update site logo by @cvanelteren in #154
- Fix minor grid showing on cbar by @cvanelteren in #150
- Add option to place abc indicator outside the axis bbox by @cvanelteren in #139
- Add unitests for ultraplot.internals.fonts by @cvanelteren in #156
- Minor refactor of unittests by @cvanelteren in #157
- Make anchor_mode default by @cvanelteren in #161
- Ipy rc kernel reset by @cvanelteren in #164
- allow subfigure formatting by @cvanelteren in #167
- make cbar labelloc possible for all direction by @cvanelteren in #165
- Add pyarrow to rm pandas error by @cvanelteren in #171
- Center figures in docs by @cvanelteren in #170
- mv toc to left by @cvanelteren in #172
- surpress warnings on action by @cvanelteren in #174
Full Changelog: v1.10.0...v1.11
v1.10.0 Ticks for Geoaxes
This release marks a newly added feature: ticks on GeoAxes
This allows for users to set ticks for the x and or y axis. These can be controlled by lonticklen
, latticklen
or ticklen
for controlling the x
, y
or both axis at the same time. This works independently to the major and minor gridlines allow for optimal control over the look and feel of your plots.
What's Changed
- prod: add me to maintainers by @beckermr in #117
- prod: only use readthedocs for PR tests by @beckermr in #118
- feat: enable test coverage with codecov by @beckermr in #121
- dynamically build what's new by @cvanelteren in #122
- rm extra == line by @cvanelteren in #123
- bugfix for Axes.legend when certain keywords are set to str by @syrte in #124
- reduce verbosity of extension by @cvanelteren in #127
- allow ticks for geoaxes by @cvanelteren in #126
New Contributors
Full Changelog: v1.0.9...v1.10.0