Repository navigation
Closed
Labels
keepItems to be ignored by the “Stale” Github ActionItems to be ignored by the “Stale” Github Action
Description
Bug summary
When using Axes.imshow(), images are scaled to integer pixel size (_ImageBase._make_image). This makes images notably too large when using vector graphics output, misaligning them with tick marks and plotted lines.
Code for reproduction
import numpy as np
import matplotlib as mpl
import matplotlib.pyplot as plt
img = np.zeros((100, 400))
img[::5, ::5] = 1
idx = np.indices(img.shape)
idx = [idx[0][::5].flatten(), idx[1][:, ::5].flatten()]
fig, ax = plt.subplots(constrained_layout=True)
ax.imshow(img, interpolation="None", origin="lower")
ax.scatter(idx[1], idx[0], marker="x", lw=0.2, s=1)
fig.savefig("imshow.pdf")Actual outcome
The image does not align with plot markers, tick marks. Towards the top-right corner, they are even placed in adjacent pixels.

Full PDF output
Expected outcome
This can be worked around by calling _ImageBase._make_image with round_to_pixel_border=False:
class NotRoundedAxesImage(mpl.image.AxesImage):
"""AxesImage subclass which does not round image extents to fit frame
This rounding leads to improper alignment between data and image
"""
def make_image(self, renderer, magnification=1.0, unsampled=False):
# docstring inherited
trans = self.get_transform()
# image is created in the canvas coordinate.
x1, x2, y1, y2 = self.get_extent()
bbox = mpl.transforms.Bbox(np.array([[x1, y1], [x2, y2]]))
transformed_bbox = mpl.transforms.TransformedBbox(bbox, trans)
clip = ((self.get_clip_box() or self.axes.bbox) if self.get_clip_on()
else self.figure.bbox)
# Turn off round_to_pixel_border!
return self._make_image(self._A, bbox, transformed_bbox, clip,
magnification, unsampled=unsampled,
round_to_pixel_border=False)
fig, ax = plt.subplots(constrained_layout=True)
# Replicate Axes.imshow
ax.set_aspect(mpl.rcParams["image.aspect"])
ai = NotRoundedAxesImage(ax, interpolation="none")
ai.set_data(img)
ai.set_extent(ai.get_extent())
ax.add_image(ai)
ax.scatter(idx[1], idx[0], marker="x", lw=0.2, s=1)
fig.savefig("custom_image.pdf")Operating system
Ubuntu 20.04
Matplotlib Version
3.4.3
Matplotlib Backend
PDF, SVG, PGF, probably others
Python version
3.7
Jupyter version
No response
Other libraries
No response
Installation
conda
Conda channel
conda-forge
Metadata
Metadata
Assignees
Labels
keepItems to be ignored by the “Stale” Github ActionItems to be ignored by the “Stale” Github Action

Activity
lschr commentedon Sep 1, 2021
This may be related to #8981.
jklymak commentedon Sep 1, 2021
Currently away from my computer but there is more discussion of this and a fix (basically don't force vector backends to have integer dpi)
Spl1x commentedon Feb 23, 2022
This is the same issue, which also leads to a misalignment of axis ticks:
Full output: current.pdf
The problem is fixed, when implementing the solution suggested by @lschr:
Ticks now align perfectly:

Full output: custom_image.pdf
This issue may also be related to #17182.
Discussions about this issue seem to be going on for quite some time, cf.
#16378
#12934
#6827
#7341
After some closer investigation, it turns out that the misalignment issue is still present and 'only' significantly smaller.
github-actions commentedon Nov 28, 2025
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!
QuLogic commentedon Feb 5, 2026
I can't reproduce this with 3.10.6, but there have also been many fixes for image resampling for 3.11 that will be coming soon as well.