Thanks to visit codestin.com
Credit goes to github.com

Skip to content

Commit f8ceb85

Browse files
committed
Merge pull request #4829 from JanSchulz/unpack_labeled_data_alternative
ENH: plotting methods can unpack labeled data
2 parents 484c0f2 + 0b4fc7c commit f8ceb85

13 files changed

+1224
-86
lines changed

.gitignore

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@
1313
.project
1414
.pydevproject
1515
.swp
16+
.idea
1617

1718
# Compiled source #
1819
###################

.travis.yml

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,7 @@ env:
2626
- secure: "dfjNqGKzQG5bu3FnDNwLG8H/C4QoieFo4PfFmZPdM2RY7WIzukwKFNT6kiDfOrpwt+2bR7FhzjOGlDECGtlGOtYPN8XuXGjhcP4a4IfakdbDfF+D3NPIpf5VlE6776k0VpvcZBTMYJKNFIMc7QPkOwjvNJ2aXyfe3hBuGlKJzQU="
2727
- BUILD_DOCS=false
2828
- NUMPY=numpy
29+
- PANDAS=
2930
- NPROC=2
3031
- TEST_ARGS=--no-pep8
3132

@@ -36,7 +37,7 @@ matrix:
3637
- python: 2.6
3738
env: NUMPY=numpy==1.6 MOCK=mock==1.0.1
3839
- python: 2.7
39-
env: MOCK=mock
40+
env: MOCK=mock PANDAS=pandas
4041
- python: 3.3
4142
- python: 3.4
4243
- python: 2.7
@@ -60,7 +61,7 @@ install:
6061
pip install --upgrade setuptools
6162
# Install only from travis wheelhouse
6263
- if [ -z "$PRE" ]; then
63-
wheelhouse_pip_install python-dateutil $NUMPY pyparsing pillow sphinx!=1.3.0;
64+
wheelhouse_pip_install python-dateutil $NUMPY $PANDAS pyparsing pillow sphinx!=1.3.0;
6465
else
6566
pip install $PRE python-dateutil $NUMPY pyparsing pillow sphinx!=1.3.0;
6667
fi

boilerplate.py

Lines changed: 27 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@
88
itself, whereas the generatable content must be edited via templates in
99
this file.
1010
11+
This file is python 3 only due to the use of `inspect`
1112
"""
1213
# We did try to do the wrapping the smart way,
1314
# with callable functions and new.function, but could never get the
@@ -209,7 +210,12 @@ def format_value(value):
209210
mappable = ''
210211

211212
# Get argspec of wrapped function
212-
args, varargs, varkw, defaults = inspect.getargspec(getattr(Axes, func))
213+
base_func = getattr(Axes, func)
214+
has_data = 'data' in inspect.signature(base_func).parameters
215+
work_func = inspect.unwrap(base_func)
216+
217+
args, varargs, varkw, defaults = inspect.getargspec(work_func)
218+
213219
args.pop(0) # remove 'self' argument
214220
if defaults is None:
215221
defaults = ()
@@ -222,6 +228,15 @@ def format_value(value):
222228
def_edited.append(val)
223229
defaults = tuple(def_edited)
224230

231+
# Add a data keyword argument if needed (fmt is PLOT_TEMPLATE) and
232+
# possible (if *args is used, we can't just add a data
233+
# argument in front of it since it would gobble one of the
234+
# arguments the user means to pass via *args)
235+
# This needs to be done here so that it goes into call
236+
if not varargs and fmt is PLOT_TEMPLATE and has_data:
237+
args.append('data')
238+
defaults = defaults + (None,)
239+
225240
# How to call the wrapped function
226241
call = []
227242
for i, arg in enumerate(args):
@@ -230,6 +245,14 @@ def format_value(value):
230245
else:
231246
call.append('%s=%s' % (arg, arg))
232247

248+
# remove the data keyword as it was needed above to go into the
249+
# call but should go after `hold` in the signature.
250+
# This is janky as all get out, but hopefully boilerplate will
251+
# be retired soon.
252+
if not varargs and fmt is PLOT_TEMPLATE and has_data:
253+
args.pop()
254+
defaults = defaults[:-1]
255+
233256
if varargs is not None:
234257
call.append('*' + varargs)
235258
if varkw is not None:
@@ -249,6 +272,9 @@ def format_value(value):
249272
elif fmt is PLOT_TEMPLATE:
250273
args.append('hold')
251274
defaults = defaults + (None,)
275+
if has_data:
276+
args.append('data')
277+
defaults = defaults + (None,)
252278
sethold = ''
253279

254280
# Now we can build the argspec for defining the wrapper
Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,36 @@
1+
Working with labeled data like pandas DataFrames
2+
------------------------------------------------
3+
Plot methods which take arrays as inputs can now also work with labeled data
4+
and unpack such data.
5+
6+
This means that the following two examples produce the same plot:
7+
8+
Example ::
9+
10+
df = pandas.DataFrame({"var1":[1,2,3,4,5,6], "var2":[1,2,3,4,5,6]})
11+
plt.plot(df["var1"], df["var2"])
12+
13+
14+
Example ::
15+
16+
plt.plot("var1", "var2", data=df)
17+
18+
This works for most plotting methods, which expect arrays/sequences as
19+
inputs. ``data`` can be anything which supports ``__getitem__``
20+
(``dict``, ``pandas.DataFrame``, ``h5py``, ...) to access ``array`` like
21+
values with string keys.
22+
23+
In addition to this, some other changes were made, which makes working with
24+
labeled data (ex ``pandas.Series``) easier:
25+
26+
* For plotting methods with ``label`` keyword argument, one of the
27+
data inputs is designated as the label source. If the user does not
28+
supply a ``label`` that value object will be introspected for a
29+
label, currently by looking for a ``name`` attribute. If the value
30+
object does not have a ``name`` attribute but was specified by as a
31+
key into the ``data`` kwarg, then the key is used. In the above
32+
examples, this results in an implicit ``label="var2"`` for both
33+
cases.
34+
35+
* ``plot()`` now uses the index of a ``Series`` instead of
36+
``np.arange(len(y))``, if no ``x`` argument is supplied.

0 commit comments

Comments
 (0)