Skip to content
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

pcolorfast misbehaves when changing axis limits #13576

Closed
psmaragdis opened this issue Mar 3, 2019 · 6 comments · Fixed by #14397
Closed

pcolorfast misbehaves when changing axis limits #13576

psmaragdis opened this issue Mar 3, 2019 · 6 comments · Fixed by #14397
Milestone

Comments

@psmaragdis
Copy link

Bug report

With a figure that contains a pcolorfast plot, when I limit the range of an axis (using axis, xlim or ylim), I get a significant amount of empty space in the figure. This makes manual zooming into a plot impractical (increased zoom creates more empty space and makes the resulting plot smaller).

Code for reproduction

%matplotlib inline
from matplotlib.pyplot import figure, gca, axis
from numpy import array

# Give the figure a background color to see the empty space on a white page
figure( facecolor='r')

# Make a pclorfast plot and zoom into the y axis
gca().pcolorfast( array( [[1,2],[3,4]]))
axis( [0,2,0,.5])

Actual outcome
Note the large amount of empty space above the figure. This is proportional to the amount of the zoom, i.e., had we drawn the whole plot without limiting the axis it would take that much space, but the aspect ratio is now different so that it's 1:1 based on the specified limits. In this case asking to zoom at 1/4 of the y axis, results in a figure that's 4 times taller. Had I zoomed into the x axis, the empty space would be on the right. Zooming on both axes will add empty space on top and right.

download

Expected outcome

A figure that did not have as much empty space on top (I did this one with pcolormesh instead).

download-1

Matplotlib version

  • Operating system: MacOS 10.14.3, and Ubuntu 16
  • Matplotlib version: 3.0.2
  • Matplotlib backend (print(matplotlib.get_backend())): module://ipykernel.pylab.backend_inline
  • Python version: 3.6.8
  • Jupyter version (if applicable): JupyterLab 0.35.3, also in nteract 0.12.3
  • Other libraries:
@ImportanceOfBeingErnest
Copy link
Member

Quick fix: Set the clip path manually.

ret = ax.pcolorfast( np.array( [[1,2],[3,4]]))
ret.set_clip_path(ax.patch)

Of course this should be done internally though I wonder why if the clip_path isn't set, the image would still be clipped visually.

@efiring
Copy link
Member

efiring commented Mar 18, 2019

I can't reproduce this on master using ipython with %matplotlib and the Qt5Agg backend. Is it perhaps specific to the inline backend?

@ImportanceOfBeingErnest
Copy link
Member

Yes this is specific to the inline backend, or more precisely to the bbox_inches="tight" option, which is used by the inline backend by default. Meaning, to reproduce either show the plot in a juypter notebook using %matplotlib inline, or save the figure in any environment using savefig("bla.png", bbox_inches="tight").

@ImportanceOfBeingErnest ImportanceOfBeingErnest added this to the v3.1.1 milestone Apr 25, 2019
@anntzer
Copy link
Contributor

anntzer commented Apr 30, 2019

why if the clip_path isn't set, the image would still be clipped visually.

Because for the better or (mostly) the worse this additional clipping is handled by _make_image.

Looks like

diff --git i/lib/matplotlib/image.py w/lib/matplotlib/image.py
index 656cc47b0..c95db0e46 100644
--- i/lib/matplotlib/image.py
+++ w/lib/matplotlib/image.py
@@ -855,8 +855,10 @@ class AxesImage(_ImageBase):
 
     def get_window_extent(self, renderer=None):
         x0, x1, y0, y1 = self._extent
-        bbox = Bbox.from_extents([x0, y0, x1, y1])
-        return bbox.transformed(self.axes.transData)
+        return Bbox.intersection(
+            Bbox.from_extents([x0, y0, x1, y1])
+            .transformed(self.axes.transData),
+            self.axes.bbox)
 
     def make_image(self, renderer, magnification=1.0, unsampled=False):
         # docstring inherited

(edit: well, really, should be intersecting with clip_path, but see #14396).
fixes the bug, just needs some tests now...

@efiring
Copy link
Member

efiring commented May 25, 2019

@anntzer will you be able to turn this into a PR in the next few days, so that it can get into the release that @tacaswell is planning?

@anntzer
Copy link
Contributor

anntzer commented May 25, 2019

I would like to first figure out why this only affects pcolorfast and not imshow, even though both should be equally affected.
I also don't think this is so urgent to fix that it needs to be milestoned for 3.1, given that this was reported against 3.0 (so not a regression in 3.1) and has likely been present for a while.

Edit: OK, that's because imshow() does set the clip_path, which is not actually used for drawing (#14396 -- explaing why pcolorfast can get away with not setting it...) but is used for tightbboxing...

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging a pull request may close this issue.

4 participants