Skip to content

Bug in circle patch plotting when using the same patch for two different figures #3776

Closed

Description

@astrofrog

The following code:

import numpy as np

import matplotlib.pyplot as plt
from matplotlib.patches import Circle

image = np.random.random((10,10))
c = Circle((5., 5.), 3.)

fig = plt.figure()
ax = fig.add_subplot(1,1,1)
ax.imshow(image, interpolation='nearest', vmin=-2., vmax=3.)
ax.add_patch(c)
fig.savefig('nearest.png')

fig = plt.figure()
ax = fig.add_subplot(1,1,1)
ax.imshow(image, vmin=-2., vmax=3.)
ax.add_patch(c)
fig.savefig('default.png')

produces the following two figures:

nearest.png [looks correct]

nearest

default.png [definitely doesn't look correct]

default

This is with the latest developer version of Matplotlib with Python 3.4.

[cc @cdeil @bsipocz @larrybradley - this is the issue that is causing https://github.com/astropy/photutils/pull/114#issuecomment-48383187]

Activity

  1. jenshnielsen commented on Nov 9, 2014

    @jenshnielsen
    Member

    I think the issue is the transform used to position the Circle. Explicitly setting the transform of the Circle to ax.TransData seems to work as expected in the second example i.e. I can reproduce your issue but it works correctly with the following code.

    import numpy as np
    import matplotlib.pyplot as plt
    from matplotlib.patches import Circle
    
    image = np.random.random((10,10))
    
    fig = plt.figure()
    ax = fig.add_subplot(1,1,1)
    ax.imshow(image, vmin=-2., vmax=3.)
    c = Circle((5., 5.), 3., transform=ax.transData)
    ax.add_patch(c,)
    ax.set_xlim(0,10)
    ax.set_ylim(0,10)
    fig.savefig('default.png')
  2. jenshnielsen commented on Nov 9, 2014

    @jenshnielsen
    Member

    Update.

    I think that the issue is that the first time C is used it does not have a transform set so according to the docs it is set to transData of the axis. However the second time round it has a transformation set so it doesn't get a new one set but the transformation is set to the DataTrans of the first axis which is wrong in this context.

    The docs of add_patch says the following:

    Add a :class:`~matplotlib.patches.Patch` *p* to the list of
    axes patches; the clipbox will be set to the Axes clipping
    box.  If the transform is not set, it will be set to
    :attr:`transData`.
    

    Can you reproduce the issue if you use a different circle patch for the second figure? If the above is a correct understanding that should change the behaviour.

  3. astrofrog commented on Nov 9, 2014

    @astrofrog
    ContributorAuthor

    Ah, this is not the bug I thought it was - this appears to be a bug related to re-using a patch in two different figures. If I use two different patches it all works fine. It has nothing to do with interpolation - I was trying to make a MWE for a different bug. But this still seems like something that should be fixed.

    EDIT: just saw your comment - we converged on the same answer!

  4. changed the title [-]Bug in circle patch plotting when not using nearest neighbor interpolation[/-] [+]Bug in circle patch plotting when using the same patch for two different figures[/+] on Nov 9, 2014
  5. jenshnielsen commented on Nov 9, 2014

    @jenshnielsen
    Member

    Yes I think it would be good if add_patch replaced the transformation if the transformation belonging to the patch was for a different axis or alternatively raised an error. I have a hart time seeing that the present behaviour where you can add a patch with a transform with respect to one axis to another axis is useful.

  6. tacaswell commented on Nov 9, 2014

    @tacaswell
    Member

    If add_patch replaced the transform you would end up in the alternate problem where the second figure would be correct, but the first would not.

    Artists have to associated with at most one axes. If we add any checks, it should probably be to raise an exception if ax.add_* is called on an artist which already has an axes. I think this should be on via turning Artist.axes into a property who's setter raises an exception if it the current value is not None or equal to the new value.

  7. added this to the milestone on Nov 9, 2014
  8. added
    API: changesChanges to the public API, typically requiring deprecation.
    on Nov 9, 2014
  9. jenshnielsen commented on Dec 21, 2014

    @jenshnielsen
    Member

    Closing since #3835 was merged.

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

    API: changesChanges to the public API, typically requiring deprecation.

    Type

    No type

    Projects

    No projects

      Milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions