Skip to content

UltraPlot v2.1.5: Choropleth, Custom labels semantic plots, and bug fixes

Latest

Choose a tag to compare

@cvanelteren cvanelteren released this 30 Mar 23:45
· 2 commits to main since this release

UltraPlot v2.1.5

The biggest additions are richer semantic size legends and first-class
choropleth support for geographic axes, alongside typing, plotting, CI, and
documentation improvements.

Highlights

Custom labels for Axes.sizelegend

sizelegend can now describe marker magnitudes in domain language instead of
just echoing the raw numeric levels.

scatter_polished
Snippet
import numpy as np

import ultraplot as uplt

np.random.seed(42)
cities = [
    "Tokyo",
    "Delhi",
    "Shanghai",
    "Sao Paulo",
    "Mumbai",
    "Cairo",
    "Beijing",
    "Dhaka",
    "Osaka",
    "Lagos",
    "Istanbul",
    "London",
]
population = np.array(
    [37.4, 32.9, 29.2, 22.4, 21.7, 21.3, 20.9, 23.2, 19.1, 16.6, 15.8, 9.5]
)
gdp_pc = np.array([42, 8, 23, 12, 7, 4, 22, 3, 38, 3, 14, 55])
growth = np.array([0.2, 2.8, 0.5, 0.7, 1.1, 1.9, 0.4, 3.1, 0.1, 3.5, 1.4, 0.8])

fig, ax = uplt.subplots(refwidth=4.5, refaspect=1.1)
ax.scatter(
    gdp_pc,
    growth,
    s=population * 12,
    c="cherry red",
    edgecolor="gray8",
    linewidth=0.5,
    alpha=0.85,
    absolute_size=True,
)
for i, city in enumerate(cities):
    offset = (5, 5)
    if city == "Osaka":
        offset = (5, -10)
    elif city == "Beijing":
        offset = (-5, 8)
    ax.annotate(
        city,
        (gdp_pc[i], growth[i]),
        fontsize=6,
        textcoords="offset points",
        xytext=offset,
        color="gray8",
    )
ax.sizelegend(
    [10 * 12, 20 * 12, 35 * 12],
    labels={10 * 12: "10M", 20 * 12: "20M", 35 * 12: "35M"},
    title="Population",
    loc="ur",
    frameon=False,
    color="gray6",
    edgecolor="gray8",
)
ax.format(
    title="Megacities: Wealth vs Growth",
    xlabel="GDP per capita (k USD)",
    ylabel="Annual growth rate (%)",
    xgrid=True,
    ygrid=True,
    xlim=(-2, 62),
    ylim=(-0.3, 4.2),
)
fig.show()

GeoAxes.choropleth for thematic maps

You can now color countries and polygon features directly from numeric values
while keeping the same UltraPlot formatting and colorbar workflow used on
cartesian plots.

choropleth_polished
Snippet
import numpy as np

import ultraplot as uplt

values = {
    "United States of America": 83.6,
    "Canada": 81.7,
    "Mexico": 75.1,
    "Brazil": 75.9,
    "Argentina": 76.7,
    "United Kingdom": 81.0,
    "France": 82.5,
    "Germany": 80.9,
    "Italy": 83.5,
    "Spain": 83.4,
    "Norway": 83.2,
    "Sweden": 83.0,
    "Russia": 73.2,
    "China": 78.2,
    "Japan": 84.8,
    "South Korea": 83.7,
    "India": 70.8,
    "Australia": 83.3,
    "New Zealand": 82.1,
    "South Africa": 64.9,
    "Nigeria": 53.9,
    "Egypt": 72.1,
    "Saudi Arabia": 76.5,
    "Turkey": 76.0,
    "Indonesia": 71.9,
    "Thailand": 78.7,
}

fig, ax = uplt.subplots(proj="merc", proj_kw={"lon0": 10}, refwidth=5.5)
m = ax.choropleth(
    values,
    country=True,
    cmap="Glacial",
    vmin=50,
    vmax=88,
    edgecolor="none",
    linewidth=0,
    colorbar="b",
    colorbar_kw={"label": "Life expectancy (years)", "length": 0.7},
    missing_kw={"facecolor": "gray8", "hatch": "///", "edgecolor": "gray5"},
)
ax.format(
    title="Global Life Expectancy (2023)",
    land=True,
    landcolor="gray2",
    ocean=True,
    oceancolor="gray1",
    coast=True,
    coastcolor="gray4",
    coastlinewidth=0.3,
    borders=True,
    borderscolor="gray4",
    borderslinewidth=0.2,
    longrid=False,
    latgrid=False,
)
fig.show()

Other changes

  • Better static-analysis support for the lazy top-level API.
  • Numeric scatter plots with explicit numeric colors now respect cmap.
  • Shared boxplot tick labels no longer duplicate.
  • SubplotGrid single-item 2D slices now keep returning SubplotGrid.
  • Helper and release-metadata coverage expanded and the CI flow was tightened.

What's Changed

New Contributors

Full Changelog: v2.1.3...v2.1.5

What's Changed

New Contributors

Full Changelog: v2.1.3...v2.1.5