8000 constrained_layout and colorbar for a subset of axes · Issue #11641 · matplotlib/matplotlib · GitHub
[go: up one dir, main page]

Skip to content

constrained_layout and colorbar for a subset of axes #11641

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Closed
dcherian opened this issue Jul 12, 2018 · 8 comments · Fixed by #11648
Closed

constrained_layout and colorbar for a subset of axes #11641

dcherian opened this issue Jul 12, 2018 · 8 comments · Fixed by #11648
Assignees
Labels
topic: geometry manager LayoutEngine, Constrained layout, Tight layout
Milestone

Comments

@dcherian
Copy link

Bug report

Bug summary

constrained_layout seems to place colorbars at the "extreme right" of the image. (not sure how to phrase this; see below)

Code for reproduction

f, ax = plt.subplots(2,2, constrained_layout=True)

data = np.random.randn(10, 10)
    
for aa in ax.flat:
    mappable = aa.pcolormesh(data)
    
f.colorbar(mappable, ax=ax[:, 0])

Actual outcome

image

Expected outcome

I would like the constrained_layout version of this --- which results when setting constrained_layout=False in the plt.subplots call above

image

Matplotlib version

  • Operating system: Ubuntu 16.04
  • Matplotlib version: 2.2.2
  • Matplotlib backend (print(matplotlib.get_backend())): module://ipykernel.pylab.backend_inline
  • Python version: 3.6.5
  • Jupyter version (if applicable): 5.5.0
  • Other libraries:
@QuLogic
Copy link
Member
QuLogic commented Jul 12, 2018

Also interesting is if you pass ax[0, 0], space is stolen from the top-left, but if you pass [ax[0, 0]], space is stolen from the right. I know these are supposed to be different, but not that different.

[ax[0, 0], ax[1, 1]] steals from the right only, though I'd expect some kind of warning or even an error.

@dcherian
Copy link
Author

Thanks, @QuLogic I meant to report that too but forgot.

The behaviour for [ax[0, 0], ax[1, 1]] seems reasonable to me; "insert a colorbar with vertical extent bounded by the top and bottom of both axes; and to the right of the rightmost axes"

@jklymak
Copy link
Member
jklymak commented Jul 12, 2018

Colorbar either steals space from an axes or a GridSpec. If you specify multiple axes in the same GridSpec it steals from the whole GridSpec.

To get what you want, you need to make a nested GridSpec. See the docomplicated example in the tutorial.

@jklymak
Copy link
Member
jklymak commented Jul 12, 2018

I agree that its inconsistent between constrained_layout=True and constrained_layout=False. Its possible I can add this functionality to the constrained_layout algorithm, but I'm not sure.

In the meantime, the way to do what you want is indeed a bit longer. It also loses the idea that the subplots have the same size. OTOH, if you are adding a colorbar to one column, but not the second, my guess would be they contain different data types.

import numpy as np
import matplotlib.pyplot as plt
import matplotlib.gridspec as gridspec

fig = plt.figure(constrained_layout=True)
gs0 = gridspec.GridSpec(1, 2, figure=fig )

gsl = gridspec.GridSpecFromSubplotSpec(2, 1, gs0[0])
gsr = gridspec.GridSpecFromSubplotSpec(2, 1, gs0[1])

data = np.random.randn(10, 10)

axs = []
for i in range(2):
    ax = fig.add_subplot(gsl[i])
    mappable = ax.pcolormesh(data)
    axs += [ax]
fig.colorbar(mappable, ax=axs)

for i in range(2):
    ax = fig.add_subplot(gsr[i])
    mappable = ax.pcolormesh(data)

plt.show()

figure_1

@jklymak jklymak added the topic: geometry manager LayoutEngine, Constrained layout, Tight layout label Jul 12, 2018
@jklymak jklymak self-assigned this Jul 12, 2018
@jklymak jklymak added this to the v3.1 milestone Jul 12, 2018
@jklymak
Copy link
Member
jklymak commented Jul 12, 2018

I think I can make this consistent, but milestoning 3.1 because there is a workaround and its a bit of an obscure use case.

@dcherian
Copy link
Author

OTOH, if you are adding a colorbar to one column, but not the second, my guess would be they contain different data types.

Yes, different data types but on the same x,y grid. Practically, the two axes on the right could have a shared colorbar or one colorbar each and that would make the axes the same size which would be fine. My example was over-simplified. The below is what I'm aiming for with the big colorbar for the 2 panels on the left.

import matplotlib.pyplot as plt
import numpy as np

f, ax = plt.subplots(2,2, constrained_layout=True)

data = np.random.randn(10, 10)
    
for aa in ax.flat:
    mappable = aa.pcolormesh(data)
    
f.colorbar(mappable, ax=ax[:, 0])
f.colorbar(mappable, ax=ax[0, 1])
f.colorbar(mappable, ax=ax[1, 1])

image

@jklymak
Copy link
Member
jklymak commented Jul 12, 2018

figure_1

PR, coming, but I need to write some tests and update the guide.

BTW< thanks for giving constrained_layout a try! Please report any other issues so I can keep polishing it...

@dcherian
Copy link
Author

@jklymak This looks great! Thanks for all your hard work. It has certainly made life a whole lot easier.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
topic: geometry manager LayoutEngine, Constrained layout, Tight layout
Projects
None yet
Development

Successfully merging a pull request may close this issue.

3 participants
0