From f70ffc0f2e7feeadbdfc0758b5ac2311c7d2ecd9 Mon Sep 17 00:00:00 2001 From: Matthew Turk Date: Thu, 14 Dec 2023 12:12:48 -0600 Subject: [PATCH 1/2] Add a TwoSlopeNorm to the norm_handler --- yt/visualization/_handlers.py | 28 +++++++++++++++++++++++++++- 1 file changed, 27 insertions(+), 1 deletion(-) diff --git a/yt/visualization/_handlers.py b/yt/visualization/_handlers.py index 659b1eb6d3f..419c92b05f7 100644 --- a/yt/visualization/_handlers.py +++ b/yt/visualization/_handlers.py @@ -6,7 +6,7 @@ import matplotlib as mpl import numpy as np import unyt as un -from matplotlib.colors import Colormap, LogNorm, Normalize, SymLogNorm +from matplotlib.colors import Colormap, LogNorm, Normalize, SymLogNorm, TwoSlopeNorm from unyt import unyt_quantity from yt._typing import Quantity, Unit @@ -61,6 +61,7 @@ class NormHandler: "_dynamic_range", "_norm_type", "_linthresh", + "_vcenter", "_norm_type", "_norm", "prefer_log", @@ -68,6 +69,7 @@ class NormHandler: _constraint_attrs: list[str] = [ "vmin", "vmax", + "vcenter", "dynamic_range", "norm_type", "linthresh", @@ -84,6 +86,7 @@ def __init__( norm_type: Optional[type[Normalize]] = None, norm: Optional[Normalize] = None, linthresh: Optional[float] = None, + vcenter: Optional[float] = None, ): self.data_source = weakref.proxy(data_source) self.ds = data_source.ds # should already be a weakref proxy @@ -95,6 +98,7 @@ def __init__( self._dynamic_range = dynamic_range self._norm_type = norm_type self._linthresh = linthresh + self._vcenter = vcenter self.prefer_log = True if self.norm is not None and self.has_constraints: @@ -196,6 +200,22 @@ def vmax(self, newval: Optional[Union[Quantity, float, Literal["max"]]]) -> None else: self._set_quan_attr("_vmax", newval) + @property + def vcenter(self) -> Optional[Union[un.unyt_quantity, Literal["zero"], float]]: + return self._vcenter + + @vcenter.setter + def vcenter( + self, newval: Optional[Union[un.unyt_quantity, Literal["zero"], float]] + ) -> None: + self._reset_norm() + if newval == "zero": + self._vcenter = 0.0 + else: + self._set_quan_attr("_vcenter", newval) + if newval is not None: + self.norm_type = TwoSlopeNorm + @property def dynamic_range(self) -> Optional[float]: return self._dynamic_range @@ -364,6 +384,12 @@ def get_norm(self, data: np.ndarray, *args, **kw) -> Normalize: kw.setdefault("linthresh", linthresh) kw.setdefault("base", 10) + elif norm_type is TwoSlopeNorm: + if self.vcenter is not None: + vcenter = self.to_float(self.vcenter) + else: + vcenter = 0.0 + kw.setdefault("vcenter", vcenter) return norm_type(*args, **kw) From 2defd2dcfcd11af0825b930e2f4de42161462034 Mon Sep 17 00:00:00 2001 From: Matthew Turk Date: Tue, 23 Jan 2024 10:59:42 -0600 Subject: [PATCH 2/2] Remove duplicate slot --- yt/visualization/_handlers.py | 1 - 1 file changed, 1 deletion(-) diff --git a/yt/visualization/_handlers.py b/yt/visualization/_handlers.py index 419c92b05f7..ec52acf6c05 100644 --- a/yt/visualization/_handlers.py +++ b/yt/visualization/_handlers.py @@ -62,7 +62,6 @@ class NormHandler: "_norm_type", "_linthresh", "_vcenter", - "_norm_type", "_norm", "prefer_log", )