diff --git a/lib/matplotlib/scale.py b/lib/matplotlib/scale.py index 0793bb31e566..de4968dd1aeb 100644 --- a/lib/matplotlib/scale.py +++ b/lib/matplotlib/scale.py @@ -956,6 +956,21 @@ def register_scale(scale_class): ) +def deregister_scale(name): + """ + Remove a custom scale from the registry. + + Parameters + ---------- + name : str + The name of the scale to remove. + """ + if name not in _scale_mapping: + raise ValueError(f"Scale '{name}' is not registered.") + _scale_mapping.pop(name) + _scale_has_axis_parameter.pop(name, None) + + def _get_scale_docs(): """ Helper function for generating docstrings related to scales. diff --git a/lib/matplotlib/scale.pyi b/lib/matplotlib/scale.pyi index 866509ee020d..f553fb92fe81 100644 --- a/lib/matplotlib/scale.pyi +++ b/lib/matplotlib/scale.pyi @@ -182,4 +182,5 @@ class LogitScale(ScaleBase): def get_scale_names() -> list[str]: ... def scale_factory(scale: str, axis: Axis, **kwargs) -> ScaleBase: ... def register_scale(scale_class: type[ScaleBase]) -> None: ... +def deregister_scale(name: str) -> None: ... def _make_axis_parameter_optional(init_func: Callable[..., None]) -> Callable[..., None]: ... diff --git a/lib/matplotlib/tests/test_scale.py b/lib/matplotlib/tests/test_scale.py index 9f882103967e..78a7f3631a4b 100644 --- a/lib/matplotlib/tests/test_scale.py +++ b/lib/matplotlib/tests/test_scale.py @@ -330,7 +330,7 @@ def set_default_locators_and_formatters(self, axis): ax.set_xscale('custom') assert isinstance(ax.xaxis.get_transform(), CustomTransform) finally: - # cleanup - there's no public unregister_scale() + # cleanup - there's no public deregister_scale() del mscale._scale_mapping["custom"] del mscale._scale_has_axis_parameter["custom"] @@ -368,7 +368,7 @@ def set_default_locators_and_formatters(self, axis): ax.set_xscale('custom') assert isinstance(ax.xaxis.get_transform(), CustomTransform) finally: - # cleanup - there's no public unregister_scale() + # cleanup - there's no public deregister_scale() del mscale._scale_mapping["custom"] del mscale._scale_has_axis_parameter["custom"] @@ -433,3 +433,23 @@ def test_val_in_range_base_fallback(): assert s.val_in_range(np.nan) is False assert s.val_in_range(np.inf) is False assert s.val_in_range(-np.inf) is False + + +def test_deregister_scale(): + """Test that deregister_scale removes a scale correctly.""" + # Register a temporary custom scale + class TempScale(mscale.LinearScale): + name = 'temp_test_scale' + + mscale.register_scale(TempScale) + assert 'temp_test_scale' in mscale._scale_mapping + + # Now unregister it + mscale.deregister_scale('temp_test_scale') + assert 'temp_test_scale' not in mscale._scale_mapping + + +def test_deregister_scale_invalid(): + """Test that deregister_scale raises ValueError for unknown scale.""" + with pytest.raises(ValueError, match="not registered"): + mscale.deregister_scale('this_does_not_exist')