# Python – making square axes plot with log2 scales in matplotlib

matplotlibnumpypythonscipy

I'd like to make a square axis scatter plot with matplotlib. Normally using `set_scale("log")` works great, but it limits me to log10. I'd like to make the plot in log2. I saw the solution here: How to produce an exponentially scaled axis?

but it is quite complicated and does not work if you have 0 values in your arrays, which I do. I'd like to simply ignore those like other numpy functions do.

For example:

``````log2scatter(data1, data2)
``````

where data1 and data2 contain 0s should have a logarithmic scale on the x and y axis, with logarithmic spaced ticks. Just like log10, except log2…

Thanks.

#### Best Solution

Just specify `basex=2` or `basey=2`.

``````import matplotlib.pyplot as plt

fig, ax = plt.subplots()
ax.set_xscale('log', basex=2)
ax.set_yscale('log', basey=2)

ax.plot(range(1024))
plt.show()
`````` For the zero-crossing behavior, what you're referring to is a "Symmetric Log" plot (a.k.a. "symlog"). For whatever it's worth, data isn't filtered out, it's just a linear plot near 0 and a log plot everywhere else. It's the scale that changes, not the data.

Normally you'd just do `ax.set_xscale('symlog', basex=2)` but using a non-10 base appears to be buggy at the moment for symlog plots.

Edit: Heh! The bug appears to be due to a classic mistake: using a mutable default argument.
I've filed a bug report, but if you feel like fixing it, you'll need to make a minor edit to `lib/matplotlib/ticker.py`, around line 1376, in the `__init__` method of `SymmetricalLogLocator`.

``````def __init__(self, transform, subs=[1.0]):
self._transform = transform
self._subs = subs
...
``````

Change it to something similar to:

``````def __init__(self, transform, subs=None):
self._transform = transform
if subs is None:
self._subs = [1.0]
else:
self._subs = subs
....
``````

With that change made, it behaves as expected...

``````import matplotlib.pyplot as plt
import numpy as np

fig, ax = plt.subplots()
ax.set_xscale('symlog', basex=2)
ax.set_yscale('symlog', basey=2)

x = np.arange(-1024, 1024)
ax.plot(x, x)

plt.show()
`````` 