| FazBrowse GitHub Viewer | Trending | | Home |
| Tools: [Download Repo ZIP] [Original HTTPS Page] |
Looks like a bug to me.
@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).
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):
import numpy as np
import 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, rasterized=True)
fig.savefig("minimal.pdf", dpi=300)
fig.savefig("minimal.png", dpi=600)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).
attn @QuLogic I think you were looking at this sort of thing during the 2.0 release?
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.
import matplotlib.pyplot as plt
import matplotlib.patches
import numpy as np
arr = np.zeros((5000, 5000), dtype=np.uint8)
arr[4000:4010, :] = 200
arr[2990:3000, :] = 200
arr[:, 4000:4010] = 200
arr[:, 2990:3000] = 200
arr[3990:4000, 3990:4000] = 100
arr[3000:3010, 3990:4000] = 100
arr[3990:4000, 3000:3010] = 100
arr[3000:3010, 3000:3010] = 100
extent = [0.0, 5000.0, 0.0, 5000.0]
plt.imshow(arr, aspect="auto", origin="lower", interpolation='none', extent=extent)
rect = matplotlib.patches.Rectangle(xy=(3000.0, 3000.0), width=1000.0, height=1000.0, linewidth=0.5, facecolor='none', edgecolor='m')
ax = plt.gca()
ax.add_patch(rect)
plt.xlim(2900, 4100)
plt.ylim(2900, 4100)
plt.savefig("test_extent_1_1.pdf")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!
I think #17182 will fix this.
#17182 doesn't fix this. The problem is the same as #17182 though.
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.
See #25704 for what I think is a solution....
| Back | FazBrowse Home | New Git URL |
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 (I've tested it with a blank matplotlibrc as well and the issue persists).
Code for reproduction
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

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).
Matplotlib version