Skip to content

Issues with autoscaling and transforms with 3.2+ #17016

Closed

Description

@mwaskom

Bug report

Bug summary

I am encountering a few seemingly related issues but can't exactly define what's happening. They broadly relate to unexpected changes in how plots are scaled and appear in the context of using the transform objects attached to the Axes. I assume they are caused by changes in autoscaling in 3.2, but don't know whether they are a bug or if previous code was relying on undefined behavior (the release notes are a little vague about what actually changed).

Code for reproduction

Here is a simple example derived from an issue in seaborn rugplot (mwaskom/seaborn#2015)

import numpy as np
import matplotlib as mpl
import matplotlib.transforms as tx
from matplotlib.collections import LineCollection
import matplotlib.pyplot as plt

a = [1, 2, 4]
height = .2

xy_pairs = np.column_stack([np.repeat(a, 2), np.tile([0, height], len(a))])
line_segs = xy_pairs.reshape([len(a), 2, 2])

f, ax = plt.subplots()
trans = tx.blended_transform_factory(ax.transData, ax.transAxes)
ax.add_collection(LineCollection(line_segs, transform=trans))
ax.autoscale_view(scalex=True, scaley=False)

Actual outcome

With matplotlib 3.2.1:

image

Expected outcome

With matplotlib 3.1.2:

image

Matplotlib version

  • Operating system: macos
  • Matplotlib version: 3.2.1
  • Matplotlib backend (print(matplotlib.get_backend())): ipython inline

Other information

Linking another seaborn issue (mwaskom/seaborn#2013) where there has been a similar change in behavior with matplotlib 3.2 but where it's harder to extract a standalone issue.

Activity

  1. anntzer commented on Apr 3, 2020

    @anntzer
    Contributor

    I think this is basically an instance of #13642 (comment), which I did not realize would affect many people, otherwise I'd have insisted more on it. (On the other hand, I did look a bit into it a while ago and IIRC fixing that was not so trivial :/)

    The basic idea of #13642 was that previously, when autoscaling a Collection (e.g., a PatchCollection as producted by scatter()), we would attempt to take the marker extents into account (i.e., we'd have 5% margins starting from the edges of the markers rather than their centers). Clearly there are some issues to make that work -- the most obvious one being what happens if the marker size is bigger than the axes size(!); see the discussion in that issue for more examples. Also it seems weird that e.g. plot([0, 1]) would autoscale to (-0.05, 1.05) whereas the same call to scatter would use slightly larger margins.

    So we decided that for collections whose size was in physical space (i.e. points), their extents would not be included in autoscaling (I still think that change is fundamentally for the better). Clearly, if a collection is in data space (i.e., x values), then they should still be taken into account, and they correctly are. What we did not handle was collections for which only x or only y was in data space -- as per my comment linked above, we handled them as fully in physical space. This is exactly the blended transform case you show here. Ideally, we'd want to handle the x and y axis separately (include them in autoscaling along the data-space direction, but not along the screen-space direction); if someone wants to look into this that would be great! However, in the mean time, I guess a partial solution would be to just handle them as if fully in physical space, which should approximately just be a matter of replacing transOffset.contains_branch(transData) by the correct call to contains_branch_separately.

  2. added this to the v3.2.2 milestone on Apr 3, 2020
  3. jklymak commented on Apr 3, 2020

    @jklymak
    Member

    Thanks a lot for the simple example. The fix in #17017 fixes this very naively. Not sure if its the "correct" fix.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

      Milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions