When z-values become small the z-axis gives wrong magnitude.
Example:
import numpy as np
import matplotlib.pyplot as plt
import matplotlib
print('matplotlib version : ', matplotlib.__version__)
X = np.arange(-5, 5, 0.25)
Y = np.arange(-5, 5, 0.25)
X, Y = np.meshgrid(X, Y)
R = np.sqrt(X**2 + Y**2)
Z = np.sin(R)
r = 0.0001 # scale z values
fig, ax = plt.subplots(subplot_kw={"projection": "3d"})
# Plot the surface.
surf = ax.plot_surface(X, Y, r*Z, cmap=matplotlib.cm.coolwarm,
linewidth=0, antialiased=False)
plt.show()
when taking e.g. r=0.0001
the z-axis should be labelled with 1e-5
or something like that to be correct, but it uses the same exact z-ticks as plotting with r=1
.
Edit: added plot. The ticks on the z-axis should be adjusted but aren't. (Just want a an overall 1e-5, for the axis not on each tick)
Expected image for ir = 0.000000000000000000000001 # scale z values ????
This is caused by a bug that is present in Matplotlib v3.7 (all minor versions). It was fixed in Matplotlib release 3.8. So, I recommend upgrading your Matplotlib version, e.g.,
pip install matplotlib==3.8
The problem also does not seem to occur in releases prior to 3.7, so you could also downgrade to version 3.6.3, e.g.,
pip install matplotlib==3.6.3
if upgrading is not possible.
If upgrading or downgrading are not possible, then you can manually apply the fix from the pull request, i.e.,
import numpy as np
import matplotlib.pyplot as plt
import matplotlib
X = np.arange(-5, 5, 0.25)
Y = np.arange(-5, 5, 0.25)
X, Y = np.meshgrid(X, Y)
R = np.sqrt(X**2 + Y**2)
Z = np.sin(R)
r = 0.0001 # scale z values
fig, ax = plt.subplots(subplot_kw={"projection": "3d"})
# Plot the surface.
surf = ax.plot_surface(X, Y, r*Z, cmap=matplotlib.cm.coolwarm,
linewidth=0, antialiased=False)
# fix the z-axis offset positioning
ax.zaxis.offsetText._transform = ax.zaxis.axes.transData
plt.show()
The above answer does not fix plots rendered in a Juptyer notebook as standard (i.e., with or without %matplotlib inline
magic), i.e., even with Matplotlib v3.8, the offset exponent value on the axis will not show up. Instead, to make things work as expected, you must use interactive plotting (via ipympl) by starting your notebook cell with %matplotlib widget
or %matplotlib ipympl
.