Repository: Ultraplot/UltraPlot

Issue:
Scaling that are part of UltraPlot raise errors
# The problem

When setting a scale that is present in MPL but not in UltraPlot it will create an edge case where it attempts to load the scaler from Matplotlib which has a slightly different call signature

For example

```python
import ultraplot as uplt
fig, ax = uplt.subplots()
for scale in "linear symlog log logit asinh mercator".split():
    ax.set_yscale(scale) # will fail on asinh
uplt.show(block=1)
```

ASinh is not part of ultraplot but it is valid under (see https://matplotlib.org/stable/gallery/scales/asinh_demo.html).

Hints from issue comments:

Solution patch:
diff --git a/ultraplot/scale.py b/ultraplot/scale.py
index f2e96787..d83d8f44 100644
--- a/ultraplot/scale.py
+++ b/ultraplot/scale.py
@@ -956,7 +956,12 @@ def _scale_factory(scale, axis, *args, **kwargs):  # noqa: U100
                 + ", ".join(map(repr, mapping))
                 + "."
             )
-        return mapping[scale](*args, **kwargs)
+        # Ensure that if the scaler exists in mpl or otherwise it will attempt to return it, which has a different signature than the _Scale class above
+        scaler = mapping[scale]
+        # Assume it is a MPL class
+        if not issubclass(scaler, _Scale):
+            return scaler(axis, *args, **kwargs)
+        return scaler(*args, **kwargs)
 
 
 # Monkey patch matplotlib scale factory with version that accepts ScaleBase instances.


Test patch:
diff --git a/ultraplot/tests/test_format.py b/ultraplot/tests/test_format.py
index 4c9a763c..4e57f0d6 100644
--- a/ultraplot/tests/test_format.py
+++ b/ultraplot/tests/test_format.py
@@ -393,3 +393,11 @@ def test_input_parsing_cycle():
     last_color = uplt.colors.to_rgba(cycle.get_next()["color"])
     assert np.allclose(first_color, lower_half(0.0))
     assert np.allclose(last_color, upper_half(1.0))
+
+
+def test_scaler():
+    # Test a ultraplot scaler and a matplotlib native scaler; should not race errors
+    fig, ax = uplt.subplots(ncols=2, share=0)
+    ax[0].set_yscale("mercator")
+    ax[1].set_yscale("asinh")
+    return fig