Skip to content

Axes are drawn at wrong positions #12697

Closed

Description

@ImportanceOfBeingErnest

Bug report

Bug summary

The window extent of the axes does not coincide with their position in the figure. This issue occurs in Agg and Cairo backends.

Code for reproduction

The following code produces two axes. A green rectangle is drawn at the bounding box of the axes. A red rectangle is drawn in the space between the axes.

import matplotlib.pyplot as plt

fig, axs = plt.subplots(2, figsize=(4,2), dpi=100)
for ax in axs.flatten():
    ax.set(xticklabels = [], yticklabels=[])
    ax.tick_params(labelbottom=False, bottom=False)

fig.canvas.draw()

bb1 = axs[0].get_window_extent()
bb2 = axs[1].get_window_extent()

rect = plt.Rectangle((bb2.x0, bb2.y1), width=20, height=bb1.y0 - bb2.y1,
                     linewidth=72./fig.dpi, edgecolor="red", facecolor="none", 
                     transform=None)
rect2 = plt.Rectangle((bb2.x0, bb2.y0), width=bb2.width, height=bb2.height,
                     linewidth=72./fig.dpi, edgecolor="limegreen", facecolor="none", 
                     transform=None)
fig.add_artist(rect2)
fig.add_artist(rect)

fig.savefig("borders.png")
plt.show()

Actual outcome

Code run with 100 dpi
borders

Code run with 200 dpi
borders

The green rectangle does not overlay with the axes. The red rectangle does not sit tight on both axes.

Expected outcome

The green rectangle should appear exactly on top of the axes spines. The red rectangle should sit tight on both axes.

Matplotlib version

  • Operating system: Win8
  • Matplotlib version: master
  • Matplotlib backend: Qt5Agg, TkCairo
  • Python version: 3.6.6

Activity

  1. jklymak commented on Nov 1, 2018

    @jklymak
    Member

    _base.py extends the bbox by self.xaxis.get_tick_padding() and self.yaxis.get_tick_padding(), for, you know, whatever reason. Particularly annoying, as these boxes do not at all cover the ticks; they seem to be in the wrong units...

  2. self-assigned this
    on Nov 2, 2018
  3. jklymak commented on Nov 2, 2018

    @jklymak
    Member

    I'll self-assign and try to fix this....

  4. jklymak commented on Nov 2, 2018

    @jklymak
    Member

    OK, so the issue was dpi was not being taken into account. And that the algorithm assumed ticks around all the spines.

    Currently

    • ax.get_window_extent currently gives the extent of the axes plus a pad aroudn the outside that is supposed to be the size of the ticks. It applies this regardless of whether the ticks are shown on that axis or not, though it does account for ticks that point in or out.
    • ax.get_tightbbox currently also accounts for the axis objetcs and all artists in the axes.

    Proposal

    ax.get_window_extent properly account for tick visibility on each spine.

  5. djakubosky commented on Nov 2, 2018

    @djakubosky

    Don't know if this is the place to bring this up, but I have noticed that this also happens when calling gridspec tight_layout and attempting to set zero as padding. So if you want to introduce a pad in one dimension (eg. h_pad=0, w_pad = 0.5), you need to gs.update the wspace or hspace to achieve the expected.

    fig =plt.figure(figsize=(8,10), constrained_layout = False)
    gs = mpl.gridspec.GridSpec(2, 1, 
                               figure =fig,
                               width_ratios=[1], height_ratios = [1, 1], wspace = 0, hspace=0)
    
    
    tax1 = fig.add_subplot(gs[0])
    tax2 = fig.add_subplot(gs[1])
    
    
    for a in [tax1, tax2]:
        a.tick_params(axis = 'both', top=False, bottom=False, right=False, left = False)
        a.set_xticklabels([])
        a.set_yticklabels([])
    gs.tight_layout(fig, h_pad = 0, w_pad= 0, pad = 0)
    

    image

  6. jklymak commented on Nov 2, 2018

    @jklymak
    Member

    Thats the same bug. #12716 gives the correct layout.

  7. added this to the v3.1.0 milestone on Feb 25, 2019
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

Labels

No labels
No labels

Type

No type

Projects

No projects

    Milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions