Skip to content

plotting: subplots_adjust prevents use of constrained_layout=True #25261

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
michaelaye opened this issue Feb 11, 2019 · 14 comments · Fixed by #39394
Closed

plotting: subplots_adjust prevents use of constrained_layout=True #25261

michaelaye opened this issue Feb 11, 2019 · 14 comments · Fixed by #39394
Labels
Milestone

Comments

@michaelaye
Copy link
Contributor

Code Sample, a copy-pastable example if possible

# Your code here
import matplotlib.pyplot as plt
import pandas as pd

fig, axes = plt.subplots(2, constrained_layout=True)
times = pd.date_range(start='now', periods=10)
pd.DataFrame({'a': np.arange(10)}, index=times).plot(style='x', ax=axes[0])

Problem description

Plotting time-series uses pandas-internally a subplots_adjust, but due to this I am unable to use the new matplotlib constrained_layout that would take care of these things automatically.

Expected Output

A good layout that respects my constrained_layout setting to plt.subplots()

Output of pd.show_versions()

[paste the output of pd.show_versions() here below this line]
INSTALLED VERSIONS

commit: None
python: 3.7.1.final.0
python-bits: 64
OS: Linux
OS-release: 3.10.0-862.el7.x86_64
machine: x86_64
processor: x86_64
byteorder: little
LC_ALL: None
LANG: en_US.UTF-8
LOCALE: en_US.UTF-8

pandas: 0.24.1
pytest: 4.2.0
pip: 19.0.2
setuptools: 40.7.3
Cython: 0.29.5
numpy: 1.16.1
scipy: 1.2.0
pyarrow: None
xarray: 0.11.3
IPython: 7.1.1
sphinx: 1.8.4
patsy: 0.5.1
dateutil: 2.8.0
pytz: 2018.9
blosc: None
bottleneck: None
tables: 3.4.4
numexpr: 2.6.9
feather: None
matplotlib: 3.0.2
openpyxl: None
xlrd: 1.2.0
xlwt: 1.3.0
xlsxwriter: 1.1.3
lxml.etree: 4.3.1
bs4: None
html5lib: None
sqlalchemy: 1.2.17
pymysql: None
psycopg2: 2.7.7 (dt dec pq3 ext lo64)
jinja2: 2.10
s3fs: None
fastparquet: None
pandas_gbq: None
pandas_datareader: None
gcsfs: None

@TomAugspurger
Copy link
Contributor

TomAugspurger commented Feb 11, 2019 via email

@michaelaye
Copy link
Contributor Author

michaelaye commented Feb 11, 2019 via email

@TomAugspurger
Copy link
Contributor

TomAugspurger commented Feb 11, 2019 via email

@mroeschke mroeschke added the Visualization plotting label May 27, 2019
@michaelaye
Copy link
Contributor Author

Well, when I want to combine several pandas timeseries plots into one figure, this mess happens. It wouldn't happen with constrained_layout, so I'd say, it is strictly better. ;)

Screen Shot 2019-07-16 at 15 52 00

@michaelaye
Copy link
Contributor Author

michaelaye commented Jul 16, 2019

The issue is, at the moment pandas uses subplot_adjust pandas is robbing the user of the opportunity of letting matplotlib take care of it, b/c matplotlib says, "oh, you adjust layout yourself, then i don't help you laying it out", and there's just no way to avoid it; I find that too imposing by pandas.

@TomAugspurger
Copy link
Contributor

TomAugspurger commented Jul 17, 2019 via email

@michaelaye
Copy link
Contributor Author

As always, the reason is that somebody else did some coding for you. ;) In this case, it's rather tedious to go through the detail of setting up matplotlib for dates. Or maybe it was, it still was tedious when I started using pandas being so happy that it did plots over time automatically. ;)

@michaelaye
Copy link
Contributor Author

Here is an easy to reproduce minimal example:

tseries = pd.date_range('now', freq='s', periods=100)
df = pd.DataFrame({'data': np.random.random(100)}, index=tseries)
df.plot()

Output:

Screenshot 2020-02-10 09 55 00

(Also here, for your convenience: https://gist.github.com/0b3c5f2ba247194fe84d8f620278dc7c )

I'm puzzled by the advise to plot using MPL instead of using df.plot(), isn't the functionality there to be used? It's a huge timesaver. Unless you claim I'm the only user that has constrained_layout as default MPL layouter. Do you officially not support plotting with the constraint_layout=True?

@jklymak
Copy link
Contributor

jklymak commented Feb 10, 2020

constrained_layout is typically set at figure creation, so pandas could check if its set and not do whatever it does to adjust things manually. Whether it should is a cost-benefit question for pandas. It will probably help some plots, but could break others?

@michaelaye
Copy link
Contributor Author

Could you give an example how existing plots could be broken if all pandas could do is to put an if in front of using subplots_adjust? I guess I'm underestimating some hidden complexity.
I'm open to other suggestion, like a wrapper on my side to switch off constrained_layout, although that would mean I either need to wrap all pandas plotters or all non-pandas plotters...

if not constrained_layout:
    do_subplots_adjust

@jklymak
Copy link
Contributor

jklymak commented Feb 10, 2020

Could you give an example how existing plots could be broken if all pandas could do is to put an if in front of using subplots_adjust?

I cannot - I am not familiar enough with panda's plotting. However, I'm sure if you made a PR that put this if in the appropriate place, pandas would consider adopting it...

@michaelaye
Copy link
Contributor Author

i certainly can try. although above comments don't make me hopeful that it would be considered.

@mdruiter
Copy link
Contributor

mdruiter commented Aug 17, 2020

Is matplotlib's constrained_layout strictly better than pandas current
stuff? I'd be happy to just let matplotlib take care of it.

Yes!

In that case, is there any reason to use DataFrame.plot rather than using Matplotlib directly?

Yes, because I am happy to let pandas take care of it...

I think the problem is that pandas used matplotlib subplots_adjust functionality, then matplotlib changed its details to add constrained_layout, disallowing subplots_adjust and tight_layout when it is enabled, but pandas didn't adapt to cope with those changes.

Pandas should just check fig.get_constrained_layout() before calling subplots_adjust or tight_layout...

@jklymak
Copy link
Contributor

jklymak commented Aug 17, 2020

... as a bit of a side issue, Matplotlib datetime handling has been improved (with some inspiration from pandas!), so I think directly plotting using matplotlib is not as painful as it might have been when pd.plot was originally written. Not to say that pd.plot probably doesn't have other specific niceties.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

Successfully merging a pull request may close this issue.

6 participants