verde icon indicating copy to clipboard operation
verde copied to clipboard

add new `minmax` function

Open mdtanker opened this issue 1 month ago • 1 comments

Adds an equivalanet function to maxabs but for calculating the min and max values of arrays, or optionally user-specified percentiles of the values.

This is useful for

  1. if you want to plot a series of datasets with the same colorscale so you need to calculate the overall min/max for all the datasets
  2. if you want to get robust colormap limits, excluding outliers by using percentiles, such as the 2nd and 98th percentiles.

Relevant issues/PRs:

Implements the function requested in #525 Follows the percentiles approach from #524 and #523

mdtanker avatar Nov 20 '25 09:11 mdtanker

Here are some timings for future reference:

import numpy as np
import verde as vd
a = np.random.uniform(size=(27, 100))

  • Using np.nanmin or np.nanmax is ~x2 slower than the non-nan functions

    %timeit vd.minmax(a, nan=True)
    %timeit vd.minmax(a, nan=False)
    
    >>>48.8 μs ± 1.94 μs per loop (mean ± std. dev. of 7 runs, 10,000 loops each)
    >>>20.2 μs ± 1.84 μs per loop (mean ± std. dev. of 7 runs, 10,000 loops each)
    
  • Using percentiles is ~4x slower than min/max

    • Only calculating 1 percentile, and using min/max for the other saves some time
    %timeit vd.minmax(a, min_percentile=0, max_percentile=100, nan=True)
    %timeit vd.minmax(a, min_percentile=1, max_percentile=99, nan=True)
    %timeit vd.minmax(a, min_percentile=0, max_percentile=99, nan=True)
    
    >>>50.5 μs ± 2.56 μs per loop (mean ± std. dev. of 7 runs, 10,000 loops each)
    >>>289 μs ± 26.5 μs per loop (mean ± std. dev. of 7 runs, 1,000 loops each)
    >>>179 μs ± 3.93 μs per loop (mean ± std. dev. of 7 runs, 10,000 loops each)
    
  • np.nanpercentile is ~5-10x slower than np.percentile

    %timeit vd.minmax(a, min_percentile=0, max_percentile=100, nan=False)
    %timeit vd.minmax(a, min_percentile=1, max_percentile=99, nan=False)
    %timeit vd.minmax(a, min_percentile=0, max_percentile=99, nan=False)
    
    >>>20.7 μs ± 843 ns per loop (mean ± std. dev. of 7 runs, 100,000 loops each)
    >>>232 μs ± 17.7 μs per loop (mean ± std. dev. of 7 runs, 1,000 loops each)
    >>>111 μs ± 5.5 μs per loop (mean ± std. dev. of 7 runs, 10,000 loops each)
    

mdtanker avatar Nov 21 '25 10:11 mdtanker