Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

ENH: Add a TwoSlopeNorm to the norm_handler #4761

Open
wants to merge 2 commits into
base: main
Choose a base branch
from
Open
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
29 changes: 27 additions & 2 deletions yt/visualization/_handlers.py
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down Expand Up @@ -61,13 +61,14 @@ class NormHandler:
"_dynamic_range",
"_norm_type",
"_linthresh",
"_norm_type",
"_vcenter",
"_norm",
"prefer_log",
)
_constraint_attrs: list[str] = [
"vmin",
"vmax",
"vcenter",
"dynamic_range",
"norm_type",
"linthresh",
Expand All @@ -84,6 +85,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
Expand All @@ -95,6 +97,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:
Expand Down Expand Up @@ -196,6 +199,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
Expand Down Expand Up @@ -364,6 +383,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)

Expand Down
Loading