Thanks to visit codestin.com
Credit goes to github.com

Skip to content

NonUniformImage does not respond to ax.set_scale('log') #13442

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Closed
jacobsvensmark opened this issue Feb 15, 2019 · 9 comments
Closed

NonUniformImage does not respond to ax.set_scale('log') #13442

jacobsvensmark opened this issue Feb 15, 2019 · 9 comments
Labels
Difficulty: Hard https://matplotlib.org/devdocs/devel/contribute.html#good-first-issues status: closed as inactive Issues closed by the "Stale" Github Action. Please comment on any you think should still be open. status: inactive Marked by the “Stale” Github Action

Comments

@jacobsvensmark
Copy link

jacobsvensmark commented Feb 15, 2019

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

figure_1

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

@jklymak
Copy link
Member

jklymak commented Feb 15, 2019

What are you trying to do with NonUniformImage that can't be done with imshow or pcolormesh? So far as I can see NonUniformImage is almost completely un-documented.

@ImportanceOfBeingErnest ImportanceOfBeingErnest added the status: needs clarification Issues that need more information to resolve. label Feb 18, 2019
@jacobsvensmark
Copy link
Author

jacobsvensmark commented Feb 18, 2019

Thanks for your answer.

imshow assumes a uniform grid of constant spacing in the x and y directions, which I do not have. I have data analogous to the data in the bottom row, where you can see that the width of pixels along the x-axis varies i.e. the grid is non uniform.

I was not aware of pcolormesh, it does, essentially the thing I need, but I need to specify the corners of each pixel, rather than the midpoint of the pixel. So for an image of size Nx,Ny I would need an array of x-values of size Nx+1 and for y of size Ny+1. With NonUniformImage I don't need the extra grid value, I provide the points at which I have data and it assumes some way of finding pixel borders, which is a behaviour I would like.

Anyways, the point is that NonUniformImage could/should, as far as I can see, meaningfully adjust to the axes when they are set to logarithmic scaling, analogous to other image plotting routines. In the example above I show that it ignores the axes.

@ImportanceOfBeingErnest ImportanceOfBeingErnest removed the status: needs clarification Issues that need more information to resolve. label Feb 18, 2019
@jklymak
Copy link
Member

jklymak commented Feb 18, 2019

#9629 does what you want with pcolormesh; right now you can pass N, M vectors, but then the data gets trimmed, which is suboptimal in my opinion.

Skeptical that anyone will get NonUniformImage to work with log axes. Your better bet for now would be to provide pcolormesh with the appropriate x,y vectors that are N+1, M+1 long.

@jacobsvensmark
Copy link
Author

jacobsvensmark commented Feb 18, 2019

Alright, thanks for the reference and help.

@jklymak
Copy link
Member

jklymak commented Feb 18, 2019

You're welcome to keep this open - maybe someone else thinks NonUniformImage should be kept around and fixed.

@jacobsvensmark
Copy link
Author

Done! Thanks again.

@efiring
Copy link
Member

efiring commented Feb 18, 2019

This bug is shared by the PcolorImage used by pcolorfast under some circumstances. It would be nice to fix it for both of these, since they provide a substantial performance boost compared to pcolormesh. Or at a minimum, an exception should be raised when they are used with other than linear scales. Unfortunately, when I looked at this some time ago my impression was that the fix would be non-trivial, and I didn't pursue it.

@dstansby dstansby added the Difficulty: Hard https://matplotlib.org/devdocs/devel/contribute.html#good-first-issues label May 4, 2019
@anntzer
Copy link
Contributor

anntzer commented Feb 18, 2022

I think the patch to fix this is along the lines of

diff --git i/lib/matplotlib/image.py w/lib/matplotlib/image.py
index a7642a2cb2..ec585e329c 100644
--- i/lib/matplotlib/image.py
+++ w/lib/matplotlib/image.py
@@ -1066,8 +1066,10 @@ class NonUniformImage(AxesImage):
         l, b, r, t = self.axes.bbox.extents
         width = int(((round(r) + 0.5) - (round(l) - 0.5)) * magnification)
         height = int(((round(t) + 0.5) - (round(b) - 0.5)) * magnification)
-        x_pix = np.linspace(vl.x0, vl.x1, width)
-        y_pix = np.linspace(vl.y0, vl.y1, height)
+        x_pix, _ = self.axes.get_xaxis_transform().inverted().transform(
+            np.column_stack([np.linspace(l, r, width), np.zeros(width)])).T
+        _, y_pix = self.axes.get_yaxis_transform().inverted().transform(
+            np.column_stack([np.zeros(height), np.linspace(b, t, height)])).T
         if self._interpolation == "nearest":
             x_mid = (self._Ax[:-1] + self._Ax[1:]) / 2
             y_mid = (self._Ay[:-1] + self._Ay[1:]) / 2

(i.e. just get the data coordinates corresponding to pixel values). There may just be some off-by-1 or off-by-0.5 things...

@github-actions
Copy link

github-actions bot commented Jun 1, 2023

This issue has been marked "inactive" because it has been 365 days since the last comment. If this issue is still present in recent Matplotlib releases, or the feature request is still wanted, please leave a comment and this label will be removed. If there are no updates in another 30 days, this issue will be automatically closed, but you are free to re-open or create a new issue if needed. We value issue reports, and this procedure is meant to help us resurface and prioritize issues that have not been addressed yet, not make them disappear. Thanks for your help!

@github-actions github-actions bot added the status: inactive Marked by the “Stale” Github Action label Jun 1, 2023
@github-actions github-actions bot added the status: closed as inactive Issues closed by the "Stale" Github Action. Please comment on any you think should still be open. label Jul 3, 2023
@github-actions github-actions bot closed this as not planned Won't fix, can't repro, duplicate, stale Jul 3, 2023
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Difficulty: Hard https://matplotlib.org/devdocs/devel/contribute.html#good-first-issues status: closed as inactive Issues closed by the "Stale" Github Action. Please comment on any you think should still be open. status: inactive Marked by the “Stale” Github Action
Projects
None yet
Development

No branches or pull requests

6 participants