-
-
Notifications
You must be signed in to change notification settings - Fork 18.5k
ENH: Allow column grouping in DataFrame.plot #29944
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
Changes from 5 commits
469eff8
b96a659
c5b187b
99cc049
06da910
49c728a
b370ba5
d1a2ae0
10ac363
9774d42
572de08
4519f22
c6edb9f
73dd7eb
b804e57
d7ee47c
8fb298d
d84f356
ba0f982
fe98b86
f81d295
8255405
f54459e
f962425
dda80b3
a457b38
8d85ba9
bbaeffa
81f2a7f
fdd7610
fe965b0
4478597
ac51202
722c83b
c601c2d
c99abba
ea6c73d
9184e64
34515a8
ae90509
827c5b5
5aace24
b28d3b3
587cbc1
1517ae3
8c61b83
b75d86c
55928ff
b5f47f2
43070d3
e3c0146
a4c2676
71b7b39
4157618
9b44546
2d89f73
8cd6342
ffd4b18
66342bc
48c9f32
aa128dc
69efd18
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,3 +1,4 @@ | ||
from collections import Iterable | ||
import re | ||
from typing import Optional | ||
import warnings | ||
|
@@ -115,6 +116,31 @@ def __init__( | |
self.sort_columns = sort_columns | ||
|
||
self.subplots = subplots | ||
if isinstance(self.subplots, Iterable): | ||
NicolasHug marked this conversation as resolved.
Show resolved
Hide resolved
|
||
# subplots is a list of tuples where each tuple is a group of | ||
# columns to be grouped together (one ax per group). | ||
# we consolidate the subplots list such that: | ||
# - the tuples contain indexes instead of column names | ||
# - the columns that aren't yet in the list are added in a group | ||
# of their own. | ||
# For example with columns from a to g, and | ||
# subplots = [(a, c), (b, f, e)], | ||
# we end up with [(ai, ci), (bi, fi, ei), (di,), (gi,)] | ||
# This way, we can handle self.subplots in a homogeneous manner | ||
# later. | ||
# TODO: also accept indexes instead of just names? | ||
# TODO: we're potentially messing with the order of the axes here | ||
cols_in_groups = {col for group in self.subplots for col in group} | ||
NicolasHug marked this conversation as resolved.
Show resolved
Hide resolved
|
||
cols_remaining = set(data.columns) - cols_in_groups | ||
|
||
subplots = [] | ||
index = list(data.columns).index | ||
for group in self.subplots: | ||
subplots.append(tuple(index(col) for col in group)) | ||
NicolasHug marked this conversation as resolved.
Show resolved
Hide resolved
|
||
for col in cols_remaining: | ||
subplots.append((index(col),)) | ||
|
||
self.subplots = subplots | ||
|
||
if sharex is None: | ||
if ax is None: | ||
|
@@ -306,8 +332,11 @@ def _maybe_right_yaxis(self, ax, axes_num): | |
|
||
def _setup_subplots(self): | ||
if self.subplots: | ||
naxes = ( | ||
self.nseries if isinstance(self.subplots, bool) else len(self.subplots) | ||
) | ||
fig, axes = _subplots( | ||
naxes=self.nseries, | ||
naxes=naxes, | ||
sharex=self.sharex, | ||
sharey=self.sharey, | ||
figsize=self.figsize, | ||
|
@@ -677,9 +706,20 @@ def _get_ax_layer(cls, ax, primary=True): | |
else: | ||
return getattr(ax, "right_ax", ax) | ||
|
||
def _col_idx_to_axis_idx(self, i): | ||
if isinstance(self.subplots, list): | ||
# Some columns are be grouped together in the same ax | ||
for group_idx, group in enumerate(self.subplots): | ||
if i in group: | ||
return group_idx | ||
else: | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Is this There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. it's a matter of style. I personally think that this way is less ambiguous when the first return statement is deeply nested with 4 indentation levels: it's easy to miss and to think that the function only returns There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I suppose, that once you added return type,
Or something like this. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I think mypy is wrong here. Because of the validation done earlier, there must be a valid column. Raising an exception might make mypy happy but it would never be hit (because of the validation), and we wouldn't be able to test against it so this would reduce test coverage. I changed the for loop into a |
||
# One ax per column | ||
return i | ||
|
||
def _get_ax(self, i): | ||
# get the twinx ax if appropriate | ||
if self.subplots: | ||
i = self._col_idx_to_axis_idx(i) | ||
ax = self.axes[i] | ||
ax = self._maybe_right_yaxis(ax, i) | ||
self.axes[i] = ax | ||
|
Uh oh!
There was an error while loading. Please reload this page.