Description
Bug report
Bug summary
An image displayed with NonUniformImage does not respond to scaling the axis with ax.set_xscale('log')
, other than changing the axis, not the image itself.
Code for reproduction
import numpy as np
import matplotlib.pyplot as plt
from matplotlib.image import NonUniformImage
# Linear x array for cell centers:
x = np.linspace(1, 10, 10)
# Highly nonlinear x array:
x2 = x**3
# Linear y-array
y = np.linspace(1, 10, 10)
z = np.sqrt(x[np.newaxis, :]**2 + y[:, np.newaxis]**2)
fig, axs = plt.subplots(nrows=2, ncols=2)
fig.subplots_adjust(bottom=0.07, hspace=0.3)
# Uniform Grid, linear x-axis
ax = axs[0, 0]
im = ax.imshow(z, extent=(1, 10, 1, 10), aspect='auto',origin='lower')
ax.set_title("Uniform Grid, linear x-axis")
# Uniform Grid, log x-axis (image changes)
ax = axs[0, 1]
im = ax.imshow(z, extent=(1, 10, 1, 10),aspect='auto',origin='lower')
ax.set_xscale('log')
ax.set_title('Uniform Grid, log x-axis')
# Correct ticklabel formatting
from matplotlib.ticker import StrMethodFormatter, NullFormatter
ax.xaxis.set_major_formatter(StrMethodFormatter('{x:.0f}'))
ax.xaxis.set_minor_formatter(NullFormatter())
# NonUniform Grid, linear x-axis
ax = axs[1, 0]
im = NonUniformImage(ax, interpolation='nearest', extent=(1, 1000, 1, 10))
im.set_data(x2, y, z)
ax.images.append(im)
ax.set_xlim(1, 1000)
ax.set_ylim(1, 10)
ax.set_title('NonUniform Grid, lin x-axis')
# NonUniform Grid, logarithmic x-axis (this doesn't work as intended)
ax = axs[1, 1]
im = NonUniformImage(ax, interpolation='nearest', extent=(1, 1000, 1, 10))
im.set_data(x2, y, z)
ax.images.append(im)
ax.set_xlim(1, 1000)
ax.set_ylim(1, 10)
ax.set_xscale('log')
ax.set_title('NonUniform Grid, log x-axis')
plt.show()
Actual outcome
Expected outcome
The bottom panels are made using NonUniformImage. I expected a change similar to the top two panels (made with imshow) when setting ax.set_xscale('log')
, however as can be seen in the bottom two panels, the image does not change from the left to the right hand side, only the axis.
The issue is briefly discussed in this link, and suggested by stackoverflow user Aaron to originate from the following:
Basically the problem is that the image is rendered using square coords which are not transformed by the axis transformation, then the bounding box is linearly scaled to axes coords so the data lines up (if the axes coords are also linear). In this case the lack of a second transform misaligns the data. This could be considered a bug that mpl.image._ImageBase does not query the axes transforms for the purpose of aligning all the data, only the bounding box...
Matplotlib version
- Operating system: OS X 10.14
- Matplotlib version: 3.0.2
- Matplotlib backend (
print(matplotlib.get_backend())
): Qt5Agg - Python version: Python 3.7.1
Python installed via default conda channel