Skip to content
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

Refactor to plotting API following pandas/matplotlib implementation #473

Merged
merged 15 commits into from
Jan 4, 2021
Merged
Show file tree
Hide file tree
Changes from 14 commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
14 changes: 9 additions & 5 deletions RELEASE_NOTES.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,17 +2,21 @@

## API changes

Several PRs in this release changed the name of plotting functions
for consistency with matplotlib and seaborn.
Several PRs in this release changed the implementation of the plotting library
for better UX and consistency with **pandas**, **matplotlib** and **seaborn**.

- `stackplot()` for `stack_plot()`
- `barplot()` for `bar_plot()`
Replace the calls to plotting features by the following:
- `plot(...)` (or `plot(kind='line', ...)`) for `line_plot()`
- `plot.stack(...)` for `stack_plot()`
- `plot.bar()` for `bar_plot()`
- ...

These PR also adds an `order` arg to the plotting functions, and the levels
These PRs also add an `order` arg to the plotting functions, and the levels
are ordered based on the `run_control()['order']` dictionary by default.

## Individual updates

- [#473](https://github.com/IAMconsortium/pyam/pull/473) Refactor to plotting API following pandas/matplotlib implementation
- [#472](https://github.com/IAMconsortium/pyam/pull/472) Add a ´sankey()` example to the plotting gallery
- [#470](https://github.com/IAMconsortium/pyam/pull/470) Add two types of `order` arg to `barplot()`
- [#467](https://github.com/IAMconsortium/pyam/pull/467) Refactor the GAMS-pyam tutorial to use the gamstransfer module
Expand Down
3 changes: 2 additions & 1 deletion doc/source/.gitignore
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
examples
# exclude built gallery folder (built by sphinx-gallery module)
gallery
modules
#*
.#*
2 changes: 1 addition & 1 deletion doc/source/api.rst
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
.. currentmodule:: pyam

API reference
API Reference
=============

This page gives an overview of the public |pyam| features, objects, functions
Expand Down
47 changes: 45 additions & 2 deletions doc/source/api/plotting.rst
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,39 @@
Plotting library
================

The plotting API(s)
-------------------

There are three ways to use the |pyam| plotting library.

1. Using the plot feature as an attribute of the :class:`IamDataFrame`:

.. code-block:: python

IamDataFrame.plot.<kind>(**kwargs)

2. Using the plot feature as a function with a `kind` keyword argument:

.. code-block:: python

IamDataFrame.plot(kind='<kind>', **kwargs)

This function defaults to the :meth:`pyam.plotting.line` type.

3. Calling any function of either the :mod:`plotting`
or the :mod:`figures` module directly via

.. code-block:: python

pyam.<module>.<kind>(df, **kwargs)

where `df` is either an :class:`IamDataFrame`
or a suitable :class:`pandas.DataFrame`.

Check out the `Plotting Gallery`_ for examples!

.. _`Plotting Gallery` : ../examples/index.html

The RunControl configuration
----------------------------

Expand All @@ -27,7 +60,7 @@ or as the path to a yaml file with a similar structure:

pyam.run_control().update(<file.yaml>)

See `this example`_ from the AR6 WG1 work using |pyam| plotting.
See `this example`_ from the AR6 WG1 using |pyam| plotting via a `yaml` file.

.. _`this example`: https://github.com/gidden/ar6-wg1-ch6-emissions/blob/master/plotting.yaml

Expand All @@ -37,6 +70,16 @@ to the RunControl.
Plotting functions
------------------

.. autofunction:: pyam.plotting.stackplot
.. autofunction:: pyam.plotting.line

.. autofunction:: pyam.plotting.stack

.. autofunction:: pyam.plotting.bar

.. autofunction:: pyam.plotting.box

.. autofunction:: pyam.plotting.scatter

.. autofunction:: pyam.plotting.pie

.. autofunction:: pyam.figures.sankey
18 changes: 6 additions & 12 deletions doc/source/conf.py
Original file line number Diff line number Diff line change
Expand Up @@ -320,6 +320,7 @@
'pint': ('https://pint.readthedocs.io/en/stable', None),
'ixmp': ('https://docs.messageix.org/projects/ixmp/en/stable/', None),
'matplotlib': ('https://matplotlib.org', None),
'plotly': ('https://plotly.com/python-api-reference/', None),
'pandas_datareader':
('https://pandas-datareader.readthedocs.io/en/stable', None)
}
Expand All @@ -329,19 +330,12 @@

sphinx_gallery_conf = {
'doc_module': ('plotly',),
# path to your examples scripts
'examples_dirs': 'examples_source',
# path to your example scripts
'examples_dirs': 'examples',
# path where to save gallery generated examples
'gallery_dirs': 'examples',
'subsection_order':
ExplicitOrder(['../examples/plot_timeseries',
'../examples/plot_ranges',
'../examples/plot_stack',
'../examples/plot_bar',
'../examples/plot_boxplot',
'../examples/plot_pie',
'../examples/plot_sankey']),
'reference_url': {'plotly': None,},
'gallery_dirs': 'gallery',
# 'subsection_order': ExplicitOrder(examples_folders),
'reference_url': {'plotly': None, 'matplotlib': None, 'pyam': None},
'image_scrapers': image_scrapers,
}

Expand Down
File renamed without changes.
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,7 @@
args = dict(model='WITCH-GLOBIOM 4.4', scenario='CD-LINKS_NPi2020_1000')
data = df.filter(**args, variable='Primary Energy|*', region='World')

data.barplot(stacked=True, title='Primary energy mix')
data.plot.bar(stacked=True, title='Primary energy mix')
plt.legend(loc=1)
plt.tight_layout()
plt.show()
Expand All @@ -46,7 +46,7 @@
#
# We can flip that round for a horizontal chart.

data.barplot(stacked=True, orient='h', title='Primary energy mix')
data.plot.bar(stacked=True, orient='h', title='Primary energy mix')
plt.legend(loc=1)
plt.tight_layout()
plt.show()
Expand All @@ -64,8 +64,8 @@
.filter(region='World', keep=False)
)

data.barplot(bars='region', stacked=True,
title='CO2 emissions by region', cmap='tab20')
data.plot.bar(bars='region', stacked=True,
title='CO2 emissions by region', cmap='tab20')
plt.legend(loc=1)
plt.tight_layout()
plt.show()
Expand All @@ -80,8 +80,8 @@
from pyam.plotting import add_net_values_to_barplot

fig, ax = plt.subplots()
data.barplot(ax=ax, bars='region', stacked=True,
title='CO2 emissions by region', cmap='tab20')
data.plot.bar(ax=ax, bars='region', stacked=True,
title='CO2 emissions by region', cmap='tab20')
add_net_values_to_barplot(ax)
plt.legend(loc=1)
plt.tight_layout()
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,7 @@
data = df.filter(scenario='CD-LINKS_NPi2020_1000',
variable='Emissions|CO2', region='World')

data.boxplot(x='year')
data.plot.box(x='year')
plt.tight_layout()
plt.show()

Expand All @@ -49,7 +49,7 @@
.filter(region='World', keep=False)
)

data.boxplot(x='year', by='region', legend=True)
data.plot.box(x='year', by='region', legend=True)

# We can use matplotlib arguments to make the figure more appealing.
plt.legend(loc=1)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,7 @@
variable='Primary Energy|*', year=2050,
region='World')

data.pie_plot()
data.plot.pie()
plt.tight_layout()
plt.show()

Expand All @@ -44,7 +44,7 @@
#
# Sometimes a legend is preferable to labels, so we can use that instead.

data.pie_plot(labels=None, legend=True)
data.plot.pie(labels=None, legend=True)
plt.tight_layout()
plt.show()

Expand All @@ -61,6 +61,6 @@
variable='Emissions|CO2', year=2050)
.filter(region='World', keep=False)
)
data.pie_plot(category='region', cmap='tab20')
data.plot.pie(category='region', cmap='tab20')
plt.tight_layout()
plt.show()
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,7 @@
data = df.filter(scenario='CD-LINKS*',
variable='Emissions|CO2', region='World')

data.line_plot(color='scenario', fill_between=True)
data.plot(color='scenario', fill_between=True)
plt.tight_layout()
plt.show()

Expand All @@ -45,7 +45,7 @@
# or it can be provided specific arguments as a dictionary:
# in this illustration, we choose a very low transparency value.

data.line_plot(color='scenario', fill_between=dict(alpha=0.15))
data.plot(color='scenario', fill_between=dict(alpha=0.15))
plt.tight_layout()
plt.show()

Expand All @@ -57,7 +57,6 @@
# range of data in the final time period using `final_ranges`. Similar to
# `fill_between` it can either be true or have specific arguments.

data.line_plot(color='scenario', fill_between=True,
final_ranges=dict(linewidth=5))
data.plot(color='scenario', fill_between=True, final_ranges=dict(linewidth=5))
plt.tight_layout()
plt.show()
Original file line number Diff line number Diff line change
Expand Up @@ -70,6 +70,6 @@
('Gas Network & Power Generation', 'Gas Demand'),
}

fig = df.filter(year=2050).sankey(mapping=sankey_mapping)
fig = df.filter(year=2050).plot.sankey(mapping=sankey_mapping)
# calling `show()` is necessary to have the thumbnail in the gallery overview
plotly.io.show(fig)
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,7 @@
data = df.filter(model=model, scenario=scenario,
variable='Primary Energy|*', region='World')

data.stackplot(title=scenario)
data.plot.stack(title=scenario)
plt.legend(loc=1)
plt.tight_layout()
plt.show()
Expand All @@ -47,8 +47,8 @@
.filter(region='World', keep=False)
)

data.stackplot(stack='region', cmap='tab20',
title=scenario, total=True)
data.plot.stack(stack='region', cmap='tab20',
title=scenario, total=True)
plt.legend(loc=1)
plt.tight_layout()
plt.show()
Original file line number Diff line number Diff line change
Expand Up @@ -36,5 +36,5 @@
.filter(region='World', keep=False)
)

data.line_plot(color='region', title='CO2 emissions by region')
data.plot(color='region', title='CO2 emissions by region')
data.timeseries()
4 changes: 2 additions & 2 deletions doc/source/index.rst
Original file line number Diff line number Diff line change
Expand Up @@ -65,7 +65,7 @@ The source code for |pyam| is available on `Github`_.
data.html

.. _`gallery`:
examples/index.html
gallery/index.html

.. _`Github`:
https://github.com/IAMconsortium/pyam
Expand All @@ -81,7 +81,7 @@ Table of Contents
contributing
data
tutorials
examples/index
gallery/index
api

Copyright & License
Expand Down
2 changes: 1 addition & 1 deletion doc/source/tutorials/GAMS_to_pyam.ipynb
Original file line number Diff line number Diff line change
Expand Up @@ -914,7 +914,7 @@
}
],
"source": [
"df.filter(variable='supply|*').bar_plot(x='region')"
"df.filter(variable='supply|*').plot.bar(x='region')"
]
},
{
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -64,7 +64,7 @@
"cell_type": "markdown",
"metadata": {},
"source": [
"Pyam's `stack_plot` method plots the stacks in the clearest way possible, even when some emissions are negative. The optional `total` keyword arguments also allows the user to include a total line on their plot."
"Pyam's `stackplot` method plots the stacks in the clearest way possible, even when some emissions are negative. The optional `total` keyword arguments also allows the user to include a total line on their plot."
]
},
{
Expand All @@ -73,7 +73,7 @@
"metadata": {},
"outputs": [],
"source": [
"df.stack_plot();"
"df.plot.stack();"
]
},
{
Expand All @@ -82,7 +82,7 @@
"metadata": {},
"outputs": [],
"source": [
"df.stack_plot(total=True);"
"df.plot.stack(total=True);"
]
},
{
Expand All @@ -98,7 +98,7 @@
"metadata": {},
"outputs": [],
"source": [
"df.stack_plot(alpha=0.5, total={\"color\": \"grey\", \"ls\": \"--\", \"lw\": 2.0});"
"df.plot.stack(alpha=0.5, total={\"color\": \"grey\", \"ls\": \"--\", \"lw\": 2.0});"
]
},
{
Expand All @@ -114,7 +114,7 @@
"metadata": {},
"outputs": [],
"source": [
"df.filter(variable=\"Emissions|CO2|Energy*\").stack_plot(total=True);"
"df.filter(variable=\"Emissions|CO2|Energy*\").plot.stack(total=True);"
]
},
{
Expand All @@ -132,7 +132,7 @@
"source": [
"pdf = df.copy()\n",
"afoluluc_vars = [\"Emissions|CO2|LUC\", \"Emissions|CO2|Agg\"]\n",
"fossil_vars = list(set(pdf.variables()) - set(afoluluc_vars))\n",
"fossil_vars = list(set(pdf.variable) - set(afoluluc_vars))\n",
"pdf.aggregate(\n",
" \"Emissions|CO2|AFOLULUC\", \n",
" components=afoluluc_vars, \n",
Expand All @@ -146,7 +146,7 @@
"pdf.filter(variable=[\n",
" \"Emissions|CO2|AFOLULUC\",\n",
" \"Emissions|CO2|Fossil\"\n",
"]).stack_plot(total=True);"
"]).plot.stack(total=True);"
]
},
{
Expand Down Expand Up @@ -227,8 +227,8 @@
" variable=\"Emissions|CO2|AFOLU\"\n",
").filter(\n",
" region=\"World\", keep=False\n",
").stack_plot(stack=\"region\", ax=ax)\n",
"df.filter(variable=\"Emissions|CO2|AFOLU\", region=\"World\").line_plot(ax=ax, color=\"black\");"
").plot.stack(stack=\"region\", ax=ax)\n",
"df.filter(variable=\"Emissions|CO2|AFOLU\", region=\"World\").plot(ax=ax, color=\"black\");"
]
},
{
Expand Down Expand Up @@ -274,8 +274,8 @@
" variable=\"Emissions|CO2|Fossil\"\n",
").filter(\n",
" region=\"World\", keep=False\n",
").stack_plot(stack=\"region\", ax=ax)\n",
"df.filter(variable=\"Emissions|CO2|Fossil\", region=\"World\").line_plot(ax=ax, color=\"black\");"
").plot.stack(stack=\"region\", ax=ax)\n",
"df.filter(variable=\"Emissions|CO2|Fossil\", region=\"World\").plot(ax=ax, color=\"black\");"
]
},
{
Expand Down
Loading