FazBrowse GitHub Viewer | Trending |
URL:
| Home
Tools: [Download Repo ZIP]   [Original HTTPS Page]

[Bug]: Cannot share both axis when setting aspect ratio · Issue #30203 · matplotlib/matplotlib · GitHub

Repository navigation

[Bug]: Cannot share both axis when setting aspect ratio #30203

Open

Description

Bug summary

if shared_x and shared_y:
raise RuntimeError("set_aspect(..., adjustable='datalim') or "
"axis('equal') are not allowed when both axes "
"are shared. Try set_aspect(..., "
"adjustable='box').")

This part is a strong regulation.
People would like to share both x and y axes when setting the aspect ratio to a certain value.
Though there will be a conflict in datalim between subplots, it is a minor problem to me.

When I changed this part as below, it worked like a charm as I expected.

if shared_x and shared_y:
    return

Code for reproduction

#!/usr/bin/env python
from matplotlib import pyplot as plt

fig, ax = plt.subplots(2,1, sharex=True, sharey=True)

# Case 1
ax[0].plot(range(0,3), range(3,6))
ax[1].plot(range(10,13), range(0,3))

# Case 2
# ax[0].plot(range(3,6), range(0,3))
# ax[1].plot(range(0,3), range(10,13))

ax[0].set_box_aspect(1)
ax[1].set_box_aspect(1)
ax[1].set_aspect('equal', adjustable='datalim', share=True)

plt.show()

Actual outcome

File "/home/ssrokyz/app/miniforge3/lib/python3.12/site-packages/matplotlib/backends/backend_qt.py", line 508, in _draw_idle
self.draw()
File "/home/ssrokyz/app/miniforge3/lib/python3.12/site-packages/matplotlib/backends/backend_agg.py", line 382, in draw
self.figure.draw(self.renderer)
File "/home/ssrokyz/app/miniforge3/lib/python3.12/site-packages/matplotlib/artist.py", line 94, in draw_wrapper
result = draw(artist, renderer, *args, **kwargs)
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "/home/ssrokyz/app/miniforge3/lib/python3.12/site-packages/matplotlib/artist.py", line 71, in draw_wrapper
return draw(artist, renderer)
^^^^^^^^^^^^^^^^^^^^^^
File "/home/ssrokyz/app/miniforge3/lib/python3.12/site-packages/matplotlib/figure.py", line 3246, in draw
artists = self._get_draw_artists(renderer)
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "/home/ssrokyz/app/miniforge3/lib/python3.12/site-packages/matplotlib/figure.py", line 166, in _get_draw_artists
ax.apply_aspect(locator(ax, renderer) if locator else None)
File "/home/ssrokyz/app/miniforge3/lib/python3.12/site-packages/matplotlib/axes/_base.py", line 2061, in apply_aspect
raise RuntimeError("set_aspect(..., adjustable='datalim') or "
RuntimeError: set_aspect(..., adjustable='datalim') or axis('equal') are not allowed when both axes are shared. Try set_aspect(..., adjustable='box').

Expected outcome

Additional information

No response

Operating system

No response

Matplotlib Version

3.10.1

Matplotlib Backend

No response

Python version

No response

Jupyter version

No response

Installation

None

Activity

  1. oscargus commented on Jun 22, 2025

    Member

    Here is a bit of back story:

    #10033

    #11416 especially #11416 (comment)

  2. youngjae142 commented on Jun 23, 2025

    Author

    Thanks for pointing @oscargus
    Yes. I actually came from that thread.
    My opinion is that it seems like a strong regulation.
    Why don't we make it just a warning, but an error?
    Or why can't we enable it with an optional parameter?

  3. timhoffm commented on Jun 24, 2025

    Member

    IIRC there’s nothing against this from a conceptual point of view. It’s just not implemented. Note that adjustable datalims coordinate y and y limits on anAxes. Sharing coordinates x (or y) limits across multiple Axes. These are separate and simple code paths. For both to work simultaneously, one needs to implement a holistic coordination of all x and y axes.

  4. youngjae142 commented on Jun 25, 2025

    Author

    Thanks for the explanation @timhoffm
    I will be very happy if it is implemented someday, but I think disabling it until the actual implementation seems unnecessary.
    I mean, it has not been implemented for 7 years now.
    I think this feature is a really basic thing people would do, even though it doesn't work perfectly.

  5. timhoffm commented on Jun 25, 2025

    Member

    I do not follow. If the scenario is not implemented and we do not raise what do you expect to happen? - It's clearly not what the user has requested. Some of the requirements sharing and aspects with adjustable datalims will not be met. In that case it's better to deny the action and let the user choose what to give up.

  6. rcomer commented on Jun 26, 2025

    Member

    I cannot reproduce the error with the provided code example. I can if I remove (one of) the calls to set_box_aspect.

    Edit: the fixed box aspect seems to make the datalim adjustment redundant, so we return early here:

    y_expander = data_ratio * xsize / ysize - 1
    # If y_expander > 0, the dy/dx viewLim ratio needs to increase
    if abs(y_expander) < 0.005:
    return

  7. youngjae142 commented on Jun 26, 2025

    Author

    @rcomer Thanks for pointing that out.
    I am not sure why I missed that.
    I changed the code
    from

    ax[0].plot(range(0,3), range(0,3))
    ax[1].plot(range(3,7), range(3,7))
    

    to

    ax[0].plot(range(3,6), range(0,3))
    ax[1].plot(range(0,3), range(10,13))
    

    to raise the error.

  8. youngjae142 commented on Jun 26, 2025

    Author

    @timhoffm What I expect to happen is exactly what I plotted in "Expected outcome."
    I can get the figure only when I rule out this code block.

    if shared_x and shared_y:
    raise RuntimeError("set_aspect(..., adjustable='datalim') or "
    "axis('equal') are not allowed when both axes "
    "are shared. Try set_aspect(..., "
    "adjustable='box').")

    In other words, I cannot get that figure unless I change the code.

    When I giveup the set_aspect(..., adjustable='datalim') and set it as set_aspect(..., adjustable='box'), what I get is below.

    which is not what I want to get.

  9. rcomer commented on Jun 26, 2025

    Member

    Removing the error block does allow the specific updated example to work, but if we swap the x- and y-values, we get empty axes:

    #!/usr/bin/env python
    from matplotlib import pyplot as plt
    
    fig, ax = plt.subplots(2,1, sharex=True, sharey=True)
    
    ax[0].plot(range(0, 3), range(3, 6))
    ax[1].plot(range(10, 13), range(0, 3))
    
    ax[0].set_box_aspect(1)
    ax[1].set_box_aspect(1)
    ax[1].set_aspect('equal', adjustable='datalim', share=True)
    
    plt.show()

  10. youngjae142 commented on Jun 27, 2025

    Author

    @rcomer
    I see. Now I see the problem a bit. Thanks.
    In that case,

    Changing this code

    if shared_x and shared_y:
    raise RuntimeError("set_aspect(..., adjustable='datalim') or "
    "axis('equal') are not allowed when both axes "
    "are shared. Try set_aspect(..., "
    "adjustable='box').")

    to this

    if shared_x and shared_y:
        return

    works.

  11. oscargus commented on Jun 27, 2025

    Member

    But in the last example, the aspect is not 1?

  12. youngjae142 commented on Jun 30, 2025

    Author

    I see.
    So now I get it that some parts need to be implemented to make it work.

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

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions


      Back | FazBrowse Home | New Git URL