Skip to content

[Bug]: twinx and twiny ignores previous set_position #21409

Description

@bfield1

Bug summary

If I manually set the position of an Axes, then call twinx or twiny, the new twinned Axes appears in the original position of the parent Axes, not in the new position.

Code for reproduction

import matplotlib.pyplot as plt
fig, ax = plt.subplots()
ax.set_position([0.2,0.2,0.5,0.5])
ax2 = ax.twinx()
plt.show()

Actual outcome

MPL_Bug_Image

I note that ax.get_position(original=True) and ax.get_position(original=False) both give the same answer.
I also note that the same issue occurs for ax.twiny().

Expected outcome

MPL_Bug_Expected
This expected outcome can be obtained by adding the line

ax2.set_position(ax.get_position())

after calling ax2=ax.twinx(). Alternatively, it can be obtained by calling ax.set_position after calling ax.twinx.
However, I would expect twinx to automatically inherit the position of the parent Axes, rather than draw the new Axes in an unrelated location.

Operating system

Windows 10

Matplotlib Version

3.4.2

Matplotlib Backend

TkAgg

Python version

3.9.4

Jupyter version

No response

Other libraries

No response

Installation

pip

Conda channel

No response

Activity

  1. jklymak commented on Oct 21, 2021

    @jklymak
    Member

    Agreed - the fix is relatively simple (I think)

  2. added this to the v3.5.1 milestone on Oct 21, 2021
  3. modified the milestones: v3.5.1, v3.5.2 on Dec 10, 2021
  4. modified the milestones: v3.5.2, v3.5.3 on Apr 30, 2022
  5. modified the milestones: v3.5.3, v3.5.4 on Jul 21, 2022
  6. modified the milestones: v3.5.4, v3.6.1 on Sep 25, 2022
  7. modified the milestones: v3.6.1, v3.6.2 on Oct 6, 2022
  8. modified the milestones: v3.6.2, v3.6.3 on Oct 27, 2022
  9. mahammadodj commented on Sep 12, 2023

    @mahammadodj

    This is not solved yet. When I turn off tick params of specific axis above in my code and twiny that axis below, tick params of the original axis are shown in my plot. That is why, I do set_xlabels([]) and turn off tick params later in my code as well like in the code below:

    for ax in [ax1,ax21,ax2,ax22,ax3,ax5,ax6,ax9,ax10,ax11,ax12,ax13,ax14,ax15,ax16,ax17,ax18]:
          new_ax = ax.twiny()
          new_ax.spines.top.set_position(('data', start_depth))
          new_ax.spines.bottom.set_position(('data', end_depth))
          new_ax.set_xticklabels([])
          new_ax.tick_params(axis='both', which='both', top=False, bottom=False, left=False, right=False)
          ax.set_xticklabels([])
          ax.tick_params(axis='both', which='both', top=False, bottom=False, left=False, right=False)
    

    Matplotlib version: 3.7.1
    Python version: 3.11.4

  10. maf2310 commented on Mar 13, 2026

    @maf2310
    Contributor

    Hi! I’ve been looking into this issue and the related PRs (#21413 and #22817) to understand why they stalled. (As it was told me on the Incubator chat)

    From what I understand, the original issue occurs when set_position() is called before twinx() / twiny(). In that case, the twin axes can end up using the original subplot position rather than the current position of the parent axes, so the two axes are no longer aligned.

    It seems that #21413 attempted to address this by always locating the twin from the parent axes, regardless of whether the parent came from a SubplotSpec or not. However, the discussion suggests that this approach ran into problems with tight_layout, since subplot twins currently rely on SubplotSpec-based layout behavior.

    Then #22817 took a more conservative approach and ensured that if the parent axes is moved after the twin is created, the twin follows. But as noted in the PR, the original case from the issue (moving the axes before creating the twin) would still not be resolved.

    I’m currently exploring whether it might be possible to keep the existing subplot-based layout behavior, but explicitly synchronize the positions between twinned axes (both at creation time and when set_position() is called). The idea would be to keep compatibility with layout engines while ensuring that twins always start from the current geometry of the parent.

    Does this sound like a reasonable direction to investigate?

  11. added a commit that references this issue on Mar 23, 2026
    d9ef7af
  12. added a commit that references this issue on Apr 10, 2026
    2923bfb
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Type

    No type

    Projects

    No projects

      Milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions