Skip to content

[Bug]: Incorrect offsets and scaling of EllipseCollection #30866

Closed

Description

@williamlus

Bug summary

This is a regression bug. The position and scaling of EllipseCollection do not follow the specification of offsets.

Code for reproduction

import matplotlib.pyplot as plt
import numpy as np
from matplotlib.collections import EllipseCollection

x = np.arange(2)
y = np.arange(2)
X, Y = np.meshgrid(x, y)

XY = np.column_stack((np.zeros_like(X.ravel()), Y.ravel()))

fig, ax = plt.subplots()

ec = EllipseCollection(X, Y, X, units='x', offsets=XY, offset_transform=ax.transData)  
ax.add_collection(ec)
plt.show()

Actual outcome

Image

Expected outcome

Image

Additional information

This works in v3.10.8.

Operating system

No response

Matplotlib Version

0.2.0.dev53474+unknown.g9e210e864

Matplotlib Backend

No response

Python version

No response

Jupyter version

No response

Installation

None

Activity

  1. rcomer commented on Dec 16, 2025

    @rcomer
    Member

    The change comes from #29958, but I would not say it is a regression as such. Autoscaling is now automatic when you add a collection, as implied by the default value of the autolim parameter. To preserve the old behaviour, you can do

    ax.add_collection(ec, autolim=False)

    If you call ax.autoscale_view() after adding the collection then you get the same behaviour in v3.10.8 and in main.

    The fact that the automatically determined limits seem to be wrong in this case probably should be investigated.

  2. timhoffm commented on Dec 16, 2025

    @timhoffm
    Member

    Indeed automatic scaling is an intended change.

    The fact that the automatically determined limits seem to be wrong in this case probably should be investigated.

    In fact, they are correct: Bbox(x0=0.0, y0=0.0, x1=0.0, y1=1.0). Note that data limits are calculated based on the offsets only.

    It's just that the data is chosen maximally confusing: There are 4 ellipses, two at (0, 0), two at (0, 1), which explains the data limits. Widths and heights are permutated between 0 and 1, so that only the 4th ellipse has non-zero width and height and is thus visible. 🤪 @williamlus please take a little more care when setting up an example that you don't use data leading to such degenerate cases.

  3. williamlus commented on Dec 17, 2025

    @williamlus
    Author

    @rcomer Yes, setting autolim=False can preserve the old behaviour. However, I found a new issue with autoscaling. After calling ax.autoscale_view(), the scaling is incorrect. Is this behavior intended or not? @timhoffm

    import matplotlib.pyplot as plt
    import numpy as np
    from matplotlib.collections import EllipseCollection
    
    x = np.arange(2)
    y = np.arange(2)
    X, Y = np.meshgrid(x, y)
    
    XY = np.column_stack((np.zeros_like(X.ravel()), Y.ravel()))
    
    fig, ax = plt.subplots()
    
    ec = EllipseCollection(X, Y, X, units='x', offsets=XY, offset_transform=ax.transData)  
    ax.add_collection(ec, autolim=False)
    ax.autoscale_view()
    plt.show()

    Actual: With ax.autoscale_view()

    Image

    Expected: Without ax.autoscale_view()

    Image
  4. timhoffm commented on Dec 17, 2025

    @timhoffm
    Member

    This is correct. autolim=False means the artist is not included in the limits calculation. Since no limit-setting data is contained in the Axes autoscale_view() falls back to a small margin around (0, 0).

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

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions