Skip to content

Commit fe4b19e

Browse files
Marc Garciadatapythonista
Marc Garcia
authored andcommitted
Adding documentation and improving comments, based on Jeff review
1 parent 1464a83 commit fe4b19e

File tree

3 files changed

+96
-18
lines changed

3 files changed

+96
-18
lines changed

doc/source/development/extending.rst

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -416,3 +416,30 @@ Below is an example to define two original properties, "internal_cache" as a tem
416416
# properties defined in _metadata are retained
417417
>>> df[['A', 'B']].added_property
418418
property
419+
420+
.. _extending.plotting-backends:
421+
422+
Plotting backends
423+
-----------------
424+
425+
Starting in 0.25 pandas can be extended with third-party plotting backends. The
426+
main idea is letting users select a plotting backend different than the provided
427+
one based on Matplotlib. For example:
428+
429+
.. code-block:: python
430+
431+
>>> pd.set_option('plotting.backend', 'backend.module')
432+
>>> pd.Series([1, 2, 3]).plot()
433+
434+
This would be more or less equivalent to:
435+
436+
.. code-block:: python
437+
438+
>>> import backend.module
439+
>>> backend.module.plot(pd.Series([1, 2, 3]))
440+
441+
The backend module can then use other visualization tools (Bokeh, Altair,...)
442+
to generate the plots.
443+
444+
More information on how to implement a third-party plotting backend can be found at
445+
https://github.com/pandas-dev/pandas/blob/master/pandas/plotting/__init__.py#L1.

pandas/plotting/__init__.py

Lines changed: 61 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,60 @@
11
"""
2-
Plotting public API
2+
Plotting public API.
3+
4+
Authors of third-party plotting backends should implement a module with a
5+
public ``plot(data, kind, **kwargs)``. The parameter `data` will contain
6+
the data structure and can be a `Series` or a `DataFrame`. For example,
7+
for ``df.plot()`` the parameter `data` will contain the DataFrame `df`.
8+
In some cases, the data structure is transformed before being sent to
9+
the backend (see PlotAccessor.__call__ in pandas/plotting/_core.py for
10+
the exact transformations).
11+
12+
The parameter `kind` will be one of:
13+
14+
- line
15+
- bar
16+
- barh
17+
- box
18+
- hist
19+
- kde
20+
- area
21+
- pie
22+
- scatter
23+
- hexbin
24+
25+
See the pandas API reference for documentation on each kind of plot.
26+
27+
Any other keyword argument is currently assumed to be backend specific,
28+
but some parameters may be unified and added to the signature in the
29+
future (e.g. `title` which should be useful for any backend).
30+
31+
Currently, all the Matplotlib functions in pandas are accessed through
32+
the selected backend. For example, `pandas.plotting.boxplot` (equivalent
33+
to `DataFrame.boxplot`) is also accessed in the selected backend. This
34+
is expected to change, and the exact API is under discussion. But with
35+
the current version, backends are expected to implement the next functions:
36+
37+
- plot (describe above, used for `Series.plot` and `DataFrame.plot`)
38+
- hist_series and hist_frame (for `Series.hist` and `DataFrame.hist`)
39+
- boxplot (`pandas.plotting.boxplot(df)` equivalent to `DataFrame.boxplot`)
40+
- boxplot_frame and boxplot_frame_groupby
41+
- tsplot (deprecated)
42+
- register and deregister (register converters for the tick formats)
43+
- Plots not called as `Series` and `DataFrame` methods:
44+
- table
45+
- andrews_curves
46+
- autocorrelation_plot
47+
- bootstrap_plot
48+
- lag_plot
49+
- parallel_coordinates
50+
- radviz
51+
- scatter_matrix
52+
53+
Use the code in pandas/plotting/_matplotib.py and
54+
https://github.com/pyviz/hvplot as a reference on how to write a backend.
55+
56+
For the discussion about the API see
57+
https://github.com/pandas-dev/pandas/issues/26747.
358
"""
459
from pandas.plotting._core import (
560
PlotAccessor, boxplot, boxplot_frame, boxplot_frame_groupby, hist_frame,
@@ -10,9 +65,9 @@
1065
parallel_coordinates, plot_params, radviz,
1166
register as register_matplotlib_converters, scatter_matrix, table)
1267

13-
__all__ = ['boxplot', 'boxplot_frame', 'boxplot_frame_groupby', 'hist_frame',
14-
'hist_series', 'PlotAccessor',
15-
'scatter_matrix', 'radviz', 'andrews_curves', 'bootstrap_plot',
16-
'parallel_coordinates', 'lag_plot', 'autocorrelation_plot',
17-
'table', 'plot_params', 'register_matplotlib_converters',
68+
__all__ = ['PlotAccessor', 'boxplot', 'boxplot_frame', 'boxplot_frame_groupby',
69+
'hist_frame', 'hist_series', 'scatter_matrix', 'radviz',
70+
'andrews_curves', 'bootstrap_plot', 'parallel_coordinates',
71+
'lag_plot', 'autocorrelation_plot', 'table', 'plot_params',
72+
'register_matplotlib_converters',
1873
'deregister_matplotlib_converters']

pandas/plotting/_core.py

Lines changed: 8 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -402,11 +402,6 @@ class PlotAccessor(PandasObject):
402402
Make plots of Series or DataFrame using the backend specified by the
403403
option ``plotting.backend``. By default, matplotlib is used.
404404
405-
*New in version 0.17.0:* Each plot kind has a corresponding method on
406-
the Series or DataFrame accessor, for example:
407-
``Series.plot(kind='line')`` is equivalent to
408-
``Series.plot.line()``.
409-
410405
Parameters
411406
----------
412407
data : Series or DataFrame
@@ -517,13 +512,11 @@ def __init__(self, data):
517512
@staticmethod
518513
def _get_call_args(data, args, kwargs):
519514
"""
520-
We used to have different accessors for Series and DataFrame. Their
521-
signatures were different:
522-
523-
- SeriesPlotMethods.__call__(kind, ..., **kwargs)
524-
- DataFramePlotMethods.__call__(x, y, kind, ..., **kwargs)
525-
526-
This function makes this unified `__call__` method compatible with both
515+
This function makes calls to this accessor `__call__` method compatible
516+
with the previous `SeriesPlotMethods.__call__` and
517+
`DataFramePlotMethods.__call__`. Those had slightly different
518+
signatures, since `DataFramePlotMethods` accepted `x` and `y`
519+
parameters.
527520
"""
528521
if args and isinstance(data, ABCSeries):
529522
# TODO raise warning here, positional arguments shouldn't be
@@ -573,6 +566,9 @@ def __call__(self, *args, **kwargs):
573566
raise ValueError('{} is not a valid plot kind'.format(kind))
574567

575568
plot_backend = _get_plot_backend()
569+
# The original data structured can be transformed before passed to the
570+
# backend. For example, for DataFrame is common to set the index as the
571+
# `x` parameter, and return a Series with the parameter `y` as values.
576572
data = self._parent.copy()
577573

578574
if isinstance(data, pandas.core.dtypes.generic.ABCSeries):

0 commit comments

Comments
 (0)