-
-
Notifications
You must be signed in to change notification settings - Fork 7.9k
[Bug]: Wrong scaling of NonUniformImage
with logarithmic axes
#29368
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
Comments
NonUniformImage
with logarithmic axesNonUniformImage
with logarithmic axes
I've not bisected, but the change is possibly related to #27964. I think the new behavior is actually correct. Pixel values are specified at their centers (y=[10^1, 10^3, 10^5]). The values in between are determined by the interpolation method (default: "nearest"). Therefore the pixel boundary between the pixels at 10^3 and 10^5 is at (10^5 - 10^3)/2 = 49500, which matches the image. This interpolation happens in data space and therefore is independent of the axis scaling. I believe the 3.10 behavior is correct and it's a topic on expectation/documentation of the interpolation behavior. |
For large pcolormesh in pdf use "rasterized=True". |
Confirmed that the behaviour changed at #27964, but before that commit and back to v3.6 I get |
I don't like this solution, because it is difficult to predict the right resolution. If the resolution is too coarse, details of the density will be lost. If the resolution is too fine, the file size is increased. In any case, the resolution would need to be much finer than the actual data to not move boundaries around. I think there should be a stable solution for adding images with rectangular, equal-sized pixels with logarithmic scaling! |
Your output device sets the resolution. Indeed it looks to me like NonUniformImage just makes a 72 dpi raster for a PDF, which is worse than what you will get from setting the dpi of the pcolormesh raster. The reason is that PDF and ps do not have any concept of a "NonUniformImage", and hence when we write the output we can either rasterize (at some dpi) or we can make polygons. We choose to rasterize the NonUniformImage, which is exactly what happens with The only reason I think |
Can you just use import numpy as np
import matplotlib.pyplot as plt
import matplotlib.ticker as mtick
from matplotlib.scale import InvertedLogTransform
x = np.linspace(0, 1, 2)
y = np.geomspace(1e1, 1e5, 3)
z = np.random.uniform(size=(len(x), len(y)))
fig, (ax1, ax2) = plt.subplots(ncols=2)
tr = InvertedLogTransform(10)
# create the image and add a secondary axis for log-scaled ticks
ax1.yaxis.set_visible(False)
im = ax1.imshow(z.T, extent=(0, 1, 0, 6), aspect="auto", origin="lower")
sec = ax1.secondary_yaxis("left", functions=tr)
sec.yaxis.set_major_locator(mtick.LogLocator())
sec.yaxis.set_minor_locator(mtick.LogLocator())
sec.yaxis.set_major_formatter(mtick.LogFormatterSciNotation())
sec.yaxis.set_tick_params(which="both", left=True)
ax1.set_title("imshow")
fig.colorbar(im, orientation="horizontal")
# use pcolormesh to get reference image
mesh = ax2.pcolormesh([0, 0.5, 1], [1e0, 1e2, 1e4, 1e6], z.T)
ax2.set_yscale("log")
ax2.set_title("pcolormesh")
fig.colorbar(mesh, orientation="horizontal")
plt.show() I'm afraid I haven't figured out how to make the minor ticks show up. Hopefully someone else can help with that. |
That's helpful! I understand now that However, I actually don't need a non-uniform image in my case – all I want is to display my uniform image with a log-scaled axis. This used to work several years ago, but now
This works in principle, but it becomes awkward when one adds a colorbar later, which might steal space from the original axis. |
I updated my comment to include colorbars. |
Thanks – this is certainly a work-around for specific situations, but I would like to provide a general function |
Perhaps you could provide an example where |
I played around with different options, and I'm pleasantly surprised by the rasterized pcolormesh. This seems to solve my original issue, so I will adopt it in the future. Thanks for the help! However, the original problem discussed in this issue still stands (even though I will now not be affected by it). |
What exactly do you as the "original problem"? Comparing |
Thank you for the detailed explanation! I agree that the current behavior is valid and nothing needs to be changed. |
Bug summary
I'm trying to produce a density plot of logarithmically spaced data. Using
NonUniformImage
used to work before matplotlib version3.10
, where I know exhibit a weirdly scaled axis.Code for reproduction
Actual outcome
The code above produces the following image
Expected outcome
I expect the left panel to look like the right panel, which was produced using
pcolormesh
. The reason I don't want to usepcolormesh
for these plots is that the quality in PDFs is often much worse (with lines showing up between patches) and the file size can easily be 10 times larger.Additional information
I recently asked a related question on Stackoverflow, which has some additional details.
Operating system
OS/X
Matplotlib Version
3.10.0
Matplotlib Backend
module://matplotlib_inline.backend_inline
Python version
3.12.8
Jupyter version
7.3.1
Installation
conda
The text was updated successfully, but these errors were encountered: