Skip to content

Conversation

@zmoon
Copy link
Contributor

@zmoon zmoon commented Aug 30, 2025

Overview

As discussed in #1353, this PR introduces a pixel_ratio setting to the UxDataArray.to_raster() method, allowing you to easily control the resolution of the rasterization when using Matplotlib+Cartopy without HoloViz.

One issue is that the get-faces-containing-points gets pretty slow as you increase pixel ratio. So I also added an option to pass in a pre-computed mapping (pixel_mapping). Example use-cases could be if you are making a lot of plots of the same scene, or overlaying multiple fields in one plot, or tweaking things and want a faster iterate cycle. But I wasn't sure what would be the best way to expose creating the mapping to the user.

Also added an example and a few other docs tweaks.

Expected Usage

import cartopy.crs as ccrs
import matplotlib.pyplot as plt
import uxarray as ux

grid_path = "/path/to/grid.nc"
data_path = "/path/to/data.nc"

uxds = ux.open_dataset(grid_path, data_path)

fig, ax = plt.subplots(
    subplot_kw={"projection": ccrs.Robinson()}, figsize=(8, 4), constrained_layout=True,
)

ax.set_extent([-125, -67, 24.5, 50], crs=ccrs.PlateCarree())
raster = uxds["dataVar"].to_raster(ax=ax, pixel_ratio=2.0)

ax.imshow(raster, origin="lower", extent=ax.get_xlim() + ax.get_ylim())

PR Checklist

General

  • An issue is linked created and linked
  • Add appropriate labels
  • Filled out Overview and Expected Usage (if applicable) sections

Testing

  • Adequate tests are created if there is new functionality
  • Tests cover all possible logical paths in your function
  • Tests are not too basic (such as simply calling a function and nothing else)

Documentation

  • Docstrings have been added to all new functions
  • Docstrings have updated with any function changes
  • Internal functions have a preceding underscore (_)
  • User functions have been added to docs/user_api/index.rst

Examples

  • Any new notebook examples added to docs/examples/ folder
  • Clear the output of all cells before committing
  • New notebook files added to docs/examples.rst toctree
  • New notebook files added to new entry in docs/gallery.yml with appropriate thumbnail photo in docs/_static/thumbnails/

@review-notebook-app
Copy link

Check out this pull request on  ReviewNB

See visual diffs & provide feedback on Jupyter Notebooks.


Powered by ReviewNB

@zmoon
Copy link
Contributor Author

zmoon commented Sep 2, 2025

One issue is that the get-faces-containing-points gets pretty slow as you increase pixel ratio.

bench

A little non-rigorous benchmark with the global QU 480 example to demonstrate.

Details
import time

import cartopy.crs as ccrs
import matplotlib.pyplot as plt
import pandas as pd

import uxarray as ux
from uxarray.plot.matplotlib import _get_raster_pixel_to_face_mapping as get_pixel_mapping

base_path = "test/meshfiles/mpas/QU/480/"
grid_path = base_path + "grid.nc"
data_path = base_path + "data.nc"

uxds = ux.open_dataset(grid_path, data_path)

fig, ax = plt.subplots(
    subplot_kw={"projection": ccrs.Robinson()}, figsize=(8, 4), constrained_layout=True,
)

ax.set_global()

results = []
for pixel_ratio in [0.01, 0.05, 0.1, 0.25, 0.5, 0.75, 1, 2, 3, 4, 6, 8]:
    for _ in range(5):
        tic = time.perf_counter_ns()
        _ = get_pixel_mapping(uxds, ax=ax, pixel_ratio=pixel_ratio)
        toc = time.perf_counter_ns()
        results.append((pixel_ratio, toc - tic))

df = pd.DataFrame(results, columns=["pixel_ratio", "time_ns"])
df.to_csv("bench.csv", index=False)

@zmoon zmoon marked this pull request as ready for review September 2, 2025 04:30
@philipc2
Copy link
Member

philipc2 commented Sep 4, 2025

One issue is that the get-faces-containing-points gets pretty slow as you increase pixel ratio.

bench A little non-rigorous benchmark with the global QU 480 example to demonstrate.

Do you have the system specs for the benchmark run here?

@zmoon
Copy link
Contributor Author

zmoon commented Sep 10, 2025

Yeah, I think I'd slightly prefer the kwarg, keep to_raster() just returning raster by default. I will give it a go in this PR then unless you object.

@philipc2
Copy link
Member

I like the idea of returning the pixel_mapping through a kwarg.

@erogluorhan
Copy link
Member

Sounds like we have a plan; looking forward to your edits, @zmoon !

Copy link
Member

@erogluorhan erogluorhan left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This looks great! Docs looks really good! I only had a few inline comments.

what the majority of users (and devs, I would think), would want

the redirects are not followed, for example:

intersphinx inventory 'https://numba.readthedocs.io/objects.inv' not fetchable due to <class 'requests.exceptions.HTTPError'>: 404 Client Error: Not Found for url: https://numba.readthedocs.io/objects.inv
and encapsulate

note that `ccrs.CRS(str(ax.projection))` can recover the proj
in many cases, but not all
@erogluorhan
Copy link
Member

@zmoon could you please update this from UXarray's main branch. Once we see all test pass after that, I'll approve it

Copy link
Member

@philipc2 philipc2 left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Looks great! Thank you for this contribution.

Copy link
Member

@erogluorhan erogluorhan left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This looks great; thanks a lot for the contribution!

@erogluorhan erogluorhan merged commit 612c926 into UXARRAY:main Sep 11, 2025
15 checks passed
@zmoon
Copy link
Contributor Author

zmoon commented Sep 11, 2025

Thanks @philipc2 and @erogluorhan , sorry that this ballooned a bit from the initial simple pixel_ratio idea.

@zmoon zmoon deleted the pixel-ratio branch September 11, 2025 19:22
@erogluorhan
Copy link
Member

No worries at all! I really like how it evolved!

@zmoon zmoon mentioned this pull request Sep 11, 2025
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Add options to .to_raster() Matplotlib PolyCollection example failing for main branch

3 participants