Pandas: plotting: subplots_adjust prevents use of constrained_layout=True

Created on 11 Feb 2019  Â·  14Comments  Â·  Source: pandas-dev/pandas

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

Visualization

Most helpful comment

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.

All 14 comments

What does a fix for this involve?

On Feb 10, 2019, at 18:15, K.-Michael Aye notifications@github.com wrote:

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()

—
You are receiving this because you are subscribed to this thread.
Reply to this email directly, view it on GitHub, or mute the thread.

How about a config flag that is being checked that tells if user wants to have subplots adjusted?

Sent from my iPhone

On Feb 11, 2019, at 05:48, Tom Augspurger notifications@github.com wrote:

What does a fix for this involve?

On Feb 10, 2019, at 18:15, K.-Michael Aye notifications@github.com wrote:

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()

—
You are receiving this because you are subscribed to this thread.
Reply to this email directly, view it on GitHub, or mute the thread.
—
You are receiving this because you authored the thread.
Reply to this email directly, view it on GitHub, or mute the thread.

That'd be somewhat unusual for pandas. I don't think we have any other
config options.

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

On Mon, Feb 11, 2019 at 8:24 AM K.-Michael Aye notifications@github.com
wrote:

How about a config flag that is being checked that tells if user wants to
have subplots adjusted?

Sent from my iPhone

On Feb 11, 2019, at 05:48, Tom Augspurger notifications@github.com
wrote:

What does a fix for this involve?

On Feb 10, 2019, at 18:15, K.-Michael Aye notifications@github.com
wrote:

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()

—
You are receiving this because you are subscribed to this thread.
Reply to this email directly, view it on GitHub, or mute the thread.
—
You are receiving this because you authored the thread.
Reply to this email directly, view it on GitHub, or mute the thread.

—
You are receiving this because you commented.
Reply to this email directly, view it on GitHub
https://github.com/pandas-dev/pandas/issues/25261#issuecomment-462344908,
or mute the thread
https://github.com/notifications/unsubscribe-auth/ABQHIqgcRXCfirtd5I8h6FlBO1IV0CTmks5vMX0BgaJpZM4azXjB
.

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

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.

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

On Tue, Jul 16, 2019 at 5:55 PM K.-Michael Aye notifications@github.com
wrote:

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".

—
You are receiving this because you commented.
Reply to this email directly, view it on GitHub
https://github.com/pandas-dev/pandas/issues/25261?email_source=notifications&email_token=AAKAOITSP6OOZUD3EKJHNHTP7ZGV3A5CNFSM4GWNPDA2YY3PNVWWK3TUL52HS4DFVREXG43VMVBW63LNMVXHJKTDN5WW2ZLOORPWSZGOD2CQA3I#issuecomment-512032877,
or mute the thread
https://github.com/notifications/unsubscribe-auth/AAKAOIQ3SVR5AEDSGIRZEXDP7ZGV3ANCNFSM4GWNPDAQ
.

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. ;)

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?

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?

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

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...

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

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...

... 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.

Was this page helpful?
0 / 5 - 0 ratings