You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
When plotting with imshow using the PDF (or SVG) backend the right and top edges of the extent are not correct. The left and bottom edges seem to be correct.
The deviation is small but noticeable (I used a smaller figure size to make it more visible -- it seems not to scale with figure size). It also appears to be unaffected by the interpolation mode. I noticed while returning to an old set of scripts -- I think this wasn't an issue for MPL pre-2.0 but unfortunately I'm unable to be more specific than that.
A minimal code example is given below (I've tested it with a blank matplotlibrc as well and the issue persists).
On Wed, Aug 2, 2017 at 1:46 PM, radioactivist ***@***.***> wrote:
Bug report
*Bug summary*
When plotting with imshow using the PDF (or SVG) backend the right and
top edges of the extent are not correct. The left and bottom edges seem to
be correct.
The deviation is small but noticeable (I used a smaller figure size to
make it more visible -- it seems not to scale with figure size). It also
appears to be unaffected by the interpolation mode. I noticed while
returning to an old set of scripts -- I think this wasn't an issue for MPL
pre-2.0 but unfortunately I'm unable to be more specific than that.
A minimal code example is given below.
*Code for reproduction*
import numpy as npimport matplotlib.pyplot as plt
fig = plt.figure()
fig.set_size_inches([2,2])
ax = fig.add_subplot(111)
x0, x1 = 0.0, 1.0
ax.set_xlim(x0-0.1,x1+0.1)
ax.set_ylim(x0-0.1,x1+0.1)
ax.plot([x0,x0],[x0,x1],color='r',lw=0.1)
ax.plot([x1,x1],[x0,x1],color='r',lw=0.1)
ax.plot([x0,x1],[x0,x0],color='r',lw=0.1)
ax.plot([x0,x1],[x1,x1],color='r',lw=0.1)
ax.imshow(np.zeros((16,16))+0.5,
cmap='Blues',
origin='lower left',
extent=(x0,x1,x0,x1),
interpolation='none',
vmin=0,vmax=1)
fig.savefig("minimal.pdf")
fig.savefig("minimal.png",dpi=600)
*Actual outcome*
The red outlines (set to match the extent) are *not* at the edge of the
blue square. See the PDF examplee and the zoomed version (attached below).
minimal.pdf
<https://github.com/matplotlib/matplotlib/files/1194753/minimal.pdf>
[image: show-pdf-zoom]
<https://user-images.githubusercontent.com/30665222/28886470-a01ff74c-7787-11e7-92f6-00a695882a9f.png>
*Expected outcome*
The red outlines (set to match the extent) should be at the edge of the
blue square. See the PNG example and the zoomed version (attached below).
[image: minimal]
<https://user-images.githubusercontent.com/30665222/28886452-8fb5ec4a-7787-11e7-9e4f-fcb16046fbee.png>
[image: show-png-zoom]
<https://user-images.githubusercontent.com/30665222/28886474-a5312c60-7787-11e7-9598-3aa0041bdf8d.png>
*Matplotlib version*
- Operating System: Linux 4.12.3-1-ARCH
- Matplotlib Version: 2.0.2 (Both packaged from Arch and latest
version compiled myself)
- Python Version: 2.7.13 and 3.6.2
—
You are receiving this because you are subscribed to this thread.
Reply to this email directly, view it on GitHub
<#8981>, or mute the thread
<https://github.com/notifications/unsubscribe-auth/AARy-DN6ZU25bdWg9cmiD96OheXf-hZnks5sULXfgaJpZM4Orbod>
.
@WeatherGod The issue appears for me in evince and in the Chromium and Firefox PDF viewers. It also appears when rasterizing the PDF in gimp (as I did to generate the zoomed version).
@jkseppan before you dig too fare into the imshow code have a look at #8966 . I suspect that won't affect this, but is a big change that maybe on the code path.
A workaround is to set the imshow to be rasterized (even though that seems redundant) and then set a higher dpi (which is only used for rasterization on vector backends like PDF):
I've done a little digging into the source code to try and nail down what's causing this. By looking at the raw SVG output I was able to trace it to something in the transform being passed into the backend. This line in the _make_image function in the file image.py appears to be the issue; if I comment this line out then the error disappears in both the PDF and SVG output. Interestingly the PNG output also still looks correct (this is for the v2.0.2 code).
I have no real idea what this line is intended to fix, so I don't know what the appropriate change is. (I came to it since the references to sub pixels and such seemed odd for vector output).
Well, the last change was mine, to remove a +1 to the new width/height rounding. Now it is likely very close to matching in PNG output, but you can't say it will work without the adjustment before checking various sizes to try and trigger the round up.
I guess it makes sense that this is a problem with PDF and SVG since they use a relatively low dpi (because it's really points-per-inch, not pixels/dots). I'm not sure how _make_image is called, but if we can get round_to_pixel_border to be false when using the PDF/SVG backends, that might be enough.
This bug (or regression because this wasn't an issue in matplotlib 1.5.x) is still not fixed in matplotlib 2.2.3.
The misalignment is quite significant and it is an annoying bug. I get the misalignment with all output formats: pdf, png, svg, etc.
The misalignment seems to increase from bottom to top.
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!
#17182 doesn't fix this. The problem is the same as #17182 though.
interploation != 'none'
For the rasterized imshow, suppose the pdf dpi is 20 dpi, but the width of the image as specified by the axes size and "extent" must be 1.571", then the image would need to be 31.42 pixels wide to fit precisely. So we round up to 32 pixels, but then the image overflows its extent. For this case, what should happen is the image size gets rounded up (ceil(1.57*20)=32 pixels), and then the image dpi would be increased accordingly in the PDF to 32/1.571 = 20.3692 dpi.
Of course the problem is not usually as bad as this. For 200 dpi the image would need to be 314.2 pixels wide, and the adjusted dpi would be 200.51.
Activity
WeatherGod commentedon Aug 2, 2017
jkseppan commentedon Aug 2, 2017
Looks like a bug to me.
radioactivist commentedon Aug 2, 2017
@WeatherGod The issue appears for me in evince and in the Chromium and Firefox PDF viewers. It also appears when rasterizing the PDF in gimp (as I did to generate the zoomed version).
tacaswell commentedon Aug 2, 2017
@jkseppan before you dig too fare into the imshow code have a look at #8966 . I suspect that won't affect this, but is a big change that maybe on the code path.
QuLogic commentedon Aug 2, 2017
A workaround is to set the
imshowto be rasterized (even though that seems redundant) and then set a higher dpi (which is only used for rasterization on vector backends like PDF):radioactivist commentedon Aug 5, 2017
I've done a little digging into the source code to try and nail down what's causing this. By looking at the raw SVG output I was able to trace it to something in the
transformbeing passed into the backend. This line in the_make_imagefunction in the fileimage.pyappears to be the issue; if I comment this line out then the error disappears in both the PDF and SVG output. Interestingly the PNG output also still looks correct (this is for the v2.0.2 code).I have no real idea what this line is intended to fix, so I don't know what the appropriate change is. (I came to it since the references to sub pixels and such seemed odd for vector output).
tacaswell commentedon Aug 5, 2017
attn @QuLogic I think you were looking at this sort of thing during the 2.0 release?
QuLogic commentedon Aug 5, 2017
Well, the last change was mine, to remove a +1 to the new width/height rounding. Now it is likely very close to matching in PNG output, but you can't say it will work without the adjustment before checking various sizes to try and trigger the round up.
I guess it makes sense that this is a problem with PDF and SVG since they use a relatively low dpi (because it's really points-per-inch, not pixels/dots). I'm not sure how
_make_imageis called, but if we can getround_to_pixel_borderto be false when using the PDF/SVG backends, that might be enough.laborleben commentedon Nov 23, 2018
This bug (or regression because this wasn't an issue in matplotlib 1.5.x) is still not fixed in matplotlib 2.2.3.
The misalignment is quite significant and it is an annoying bug. I get the misalignment with all output formats: pdf, png, svg, etc.
The misalignment seems to increase from bottom to top.
Expected result (1.5.x):

Actual result (2.2.3):

Code to reproduce the bug
github-actions commentedon Apr 16, 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!
jklymak commentedon Apr 16, 2023
I think #17182 will fix this.
jklymak commentedon Apr 17, 2023
#17182 doesn't fix this. The problem is the same as #17182 though.
interploation != 'none'
For the rasterized imshow, suppose the pdf dpi is 20 dpi, but the width of the image as specified by the axes size and "extent" must be 1.571", then the image would need to be 31.42 pixels wide to fit precisely. So we round up to 32 pixels, but then the image overflows its extent. For this case, what should happen is the image size gets rounded up (ceil(1.57*20)=32 pixels), and then the image dpi would be increased accordingly in the PDF to 32/1.571 = 20.3692 dpi.
Of course the problem is not usually as bad as this. For 200 dpi the image would need to be 314.2 pixels wide, and the adjusted dpi would be 200.51.
interpolation == 'none'
See #25704 for what I think is a solution....