Skip to content

add new minmax function#526

Merged
leouieda merged 24 commits intofatiando:mainfrom
mdtanker:minmax
Mar 17, 2026
Merged

add new minmax function#526
leouieda merged 24 commits intofatiando:mainfrom
mdtanker:minmax

Conversation

@mdtanker
Copy link
Member

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

Copy link
Member

@santisoler santisoler left a comment

Choose a reason for hiding this comment

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

Thanks @mdtanker for pushing this forward! I just left a few minor suggestions. Let me know what do you think!

It might be also nice to check if min_percentile <= max_percentile so we are ensure that min <= max regardless of the choices of percentile values.

mdtanker and others added 6 commits November 21, 2025 09:39
Co-authored-by: Santiago Soler <santisoler@fastmail.com>
Co-authored-by: Santiago Soler <santisoler@fastmail.com>
Co-authored-by: Santiago Soler <santisoler@fastmail.com>
Co-authored-by: Santiago Soler <santisoler@fastmail.com>
Since percentile calculations are slower than min/max, I only do them if non-default values (0,100) are provided. If only 1 non-default percentile provided, only calculate that percentile and use min/max for other value.
@mdtanker
Copy link
Member Author

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 mdtanker requested a review from santisoler November 21, 2025 11:16
Copy link
Member

@santisoler santisoler left a comment

Choose a reason for hiding this comment

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

Looking good, @mdtanker. Just left a few comments. Let me know what do you think!

mdtanker and others added 4 commits December 4, 2025 15:18
Co-authored-by: Santiago Soler <santisoler@fastmail.com>
Co-authored-by: Santiago Soler <santisoler@fastmail.com>
Co-authored-by: Santiago Soler <santisoler@fastmail.com>
Co-authored-by: Santiago Soler <santisoler@fastmail.com>
@leouieda leouieda added this to the v1.9.0 milestone Mar 16, 2026
@leouieda
Copy link
Member

@mdtanker I want to get this released with v1.9 (#537) and was wondering what the status is. Is there anything blocking this that I could help with?

@leouieda
Copy link
Member

By the way, I merged the recent changes from main here which should fix some of the unrelated failures.

@mdtanker
Copy link
Member Author

Nothing stopping it just haven't had time, can get it done tomorrow though!

@leouieda
Copy link
Member

Ah awesome! Thanks! Don't forget to add yourself to the AUTHORS file as well.

mdtanker and others added 2 commits March 17, 2026 13:15
Co-authored-by: Santiago Soler <santisoler@fastmail.com>
@mdtanker
Copy link
Member Author

Ok this should be ready to go! I think I resolved all the review comments from @santisoler, but it seems the review is still blocking the merge? Is there something I should do on my end?

@leouieda
Copy link
Member

Hi @mdtanker sorry, was having a look and had a couple more comments.

mdtanker and others added 4 commits March 17, 2026 14:48
Co-authored-by: Leonardo Uieda <leo@uieda.com>
Co-authored-by: Leonardo Uieda <leo@uieda.com>
Co-authored-by: Leonardo Uieda <leo@uieda.com>
@leouieda leouieda dismissed santisoler’s stale review March 17, 2026 18:13

Reviewed changes and approved.

@leouieda leouieda merged commit 0a4b943 into fatiando:main Mar 17, 2026
27 of 28 checks passed
@leouieda
Copy link
Member

Merged! Thanks for this @mdtanker!

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.

3 participants