{ "cells": [ { "cell_type": "markdown", "metadata": {}, "source": [ "# Importing results from a GAMS model to an IamDataFrame\n", "\n", "This tutorial illustrates how to extract results from any GAMS model (via the gdx file)\n", "and cast them to an **IamDataFrame** for further processing.\n", "\n", "\n", "\n", "The workflow presented here uses the **GAMS Python API**\n", "([read the docs](https://www.gams.com/latest/docs/API_PY_TUTORIAL.html))\n", "and the **gamstransfer** module.\n", "\n", "Follow these steps to install the requirements:\n", "\n", "1. Manually install the GAMS API,\n", " follow one of the options in [this description](https://www.gams.com/latest/docs/API_PY_TUTORIAL.html).\n", " \n", " > **TL;DR**: search for the folder \"api_38\" in the GAMS installation folder on your machine\n", " > and run\n", " > ```\n", " > python setup.py install\n", " > ```\n", "\n", "2. Install the **schema** package via\n", " ```\n", " pip install schema\n", " ```\n", " This is a dependency of the **gamstransfer** module.\n", "\n", "This notebook was run with Python 3.8 and GAMS 33.2 on Mac OS.\n", "\n", "****\n", "\n", "**Developers note:**\n", "Running this notebook on CI and RTD is a challenge\n", "due to the need to download and install the GAMS API. \n", "For the time being, this notebook is not executed by **nbsphinx**\n", "and has to be saved with output." ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "## The transport model\n", "\n", "The model used for this illustration is the transport model by Rosenthal,\n", "frequently used for tutorials and examples.\n", "\n", "The complete model is repeated here for clarity - note the last line\n", "which exports the results to a file in the GAMS Data Exchange (gdx) format.\n", "\n", " *Basic example of transport model from GAMS model library\n", "\n", " $Title A Transportation Problem (TRNSPORT,SEQ=1)\n", " $Ontext\n", "\n", " This problem finds a least cost shipping schedule that meets\n", " requirements at markets and supplies at factories.\n", "\n", " Dantzig, G B, Chapter 3.3. In Linear Programming and Extensions.\n", " Princeton University Press, Princeton, New Jersey, 1963.\n", "\n", " This formulation is described in detail in:\n", " Rosenthal, R E, Chapter 2: A GAMS Tutorial. In GAMS: A User's Guide.\n", " The Scientific Press, Redwood City, California, 1988.\n", "\n", " $Offtext\n", "\n", " Sets\n", " i canning plants / seattle, san-diego /\n", " j markets / new-york, chicago, topeka / ;\n", " Parameters\n", " a(i) capacity of plant i in cases\n", " / seattle 350\n", " san-diego 600 /\n", " b(j) demand at market j in cases\n", " / new-york 325\n", " chicago 300\n", " topeka 275 / ;\n", " Table d(i,j) distance in thousands of miles\n", " new-york chicago topeka\n", " seattle 2.5 1.7 1.8\n", " san-diego 2.5 1.8 1.4 ;\n", " Scalar f freight in dollars per case per thousand miles /90/ ;\n", " Parameter c(i,j) transport cost in thousands of dollars per case ;\n", " c(i,j) = f * d(i,j) / 1000 ;\n", " Variables\n", " x(i,j) shipment quantities in cases\n", " z total transportation costs in thousands of dollars ;\n", "\n", " Positive Variable x ;\n", "\n", " Equations\n", " cost define objective function\n", " supply(i) observe supply limit at plant i\n", " demand(j) satisfy demand at market j ;\n", "\n", " cost .. z =e= sum((i,j), c(i,j)*x(i,j)) ;\n", "\n", " supply(i) .. sum(j, x(i,j)) =l= a(i) ;\n", "\n", " demand(j) .. sum(i, x(i,j)) =g= b(j) ;\n", "\n", " Model transport /all/ ;\n", "\n", " Solve transport using lp minimizing z ;\n", "\n", " Display x.l, x.m ;\n", "\n", " Execute_unload 'transport_tutorial.gdx';" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "## Import results from the gdx file\n", "\n", "The first cell imports **pyam** and the two GAMS packages used in this tutorial." ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "This cell loads the transport model results gdx file and reads all data into memory. \n", "In a larger application, one could load the data step by step (and only load the data that is actually needed)." ] }, { "cell_type": "code", "execution_count": 2, "metadata": {}, "outputs": [], "source": [ "from gams import GamsWorkspace\n", "from gamstransfer import GdxContainer\n", "\n", "gdx = GdxContainer(GamsWorkspace().system_directory, \"transport_tutorial.gdx\")\n", "gdx.rgdx()" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "## Cast results to an IamDataFrame\n", "\n", "The first cell in this section defines the model and scenario identifiers,\n", "which are identical for all results." ] }, { "cell_type": "code", "execution_count": 3, "metadata": {}, "outputs": [], "source": [ "args = dict(model=\"transport\", scenario=\"baseline\")" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "
\n", "\n", "The basic transport model does not have a temporal resolution,\n", "but an **IamDataFrame** requires some information on the time domain. \n", "We therefore assume that the year is 2020 and add it to the results.\n", "In a more elaborate model, \"time\" or \"year\" would be in the symbol domain.\n", "\n", "
" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "### The objective value\n", "\n", "The first cell in this section reads the value of the objective function, adds the year and displays the data.\n", "\n", "The next cell casts the data read from the gdx to an **IamDataFrame** using the variable name `cost`. \n", "In the following sections, we will add more results from the gdx.\n", "\n", "The last cell displays the data of the **IamDataFrame**." ] }, { "cell_type": "code", "execution_count": 4, "metadata": {}, "outputs": [ { "data": { "text/html": [ "
\n", "\n", "\n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", "
Lyear
0153.6752020
\n", "
" ], "text/plain": [ " L year\n", "0 153.675 2020" ] }, "execution_count": 4, "metadata": {}, "output_type": "execute_result" } ], "source": [ "z = gdx.to_dataframe(\"z\")[\"elements\"]\n", "z[\"year\"] = 2020\n", "z" ] }, { "cell_type": "code", "execution_count": 5, "metadata": {}, "outputs": [], "source": [ "from pyam import IamDataFrame\n", "\n", "df = IamDataFrame(z, variable=\"cost\", region=\"USA\", unit=\"$\", value=\"L\", **args)" ] }, { "cell_type": "code", "execution_count": 6, "metadata": {}, "outputs": [ { "data": { "text/html": [ "
\n", "\n", "\n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", "
2020
modelscenarioregionvariableunit
transportbaselineUSAcost$153.675
\n", "
" ], "text/plain": [ " 2020\n", "model scenario region variable unit \n", "transport baseline USA cost $ 153.675" ] }, "execution_count": 6, "metadata": {}, "output_type": "execute_result" } ], "source": [ "df.timeseries()" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "### Optimal shipment of quantities\n", "\n", "The shipments determined by the model can be read from the value of the decision variable `x`. \n", "The value (GAMS-speak: \"level\" or field `L`) is read by default by the **GdxContainer.to_dataframe()** function." ] }, { "cell_type": "code", "execution_count": 7, "metadata": {}, "outputs": [ { "data": { "text/html": [ "
\n", "\n", "\n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", "
ijLyear
0seattlenew-york50.02020
1seattlechicago300.02020
2seattletopeka0.02020
3san-diegonew-york275.02020
4san-diegochicago0.02020
5san-diegotopeka275.02020
\n", "
" ], "text/plain": [ " i j L year\n", "0 seattle new-york 50.0 2020\n", "1 seattle chicago 300.0 2020\n", "2 seattle topeka 0.0 2020\n", "3 san-diego new-york 275.0 2020\n", "4 san-diego chicago 0.0 2020\n", "5 san-diego topeka 275.0 2020" ] }, "execution_count": 7, "metadata": {}, "output_type": "execute_result" } ], "source": [ "x = gdx.to_dataframe(\"x\")[\"elements\"]\n", "x[\"year\"] = 2020\n", "x" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "There are several ways to coerce the \"from-to\" dimension of the mathematical formulation\n", "to the \"variable/region\" format used in the IAMC data standard.\n", "In this example, we define a variable `supply|*` where \\* is the supply location\n", "and we use the demand center as the region.\n", "\n", "This is implemented by adding a column 'type' to the shipment-dataframe\n", "and appending a new object to the results **IamDataFrame** concatening the 'type' column and the origin column 'i'." ] }, { "cell_type": "code", "execution_count": 8, "metadata": {}, "outputs": [], "source": [ "x[\"type\"] = \"supply\"" ] }, { "cell_type": "code", "execution_count": 9, "metadata": {}, "outputs": [], "source": [ "df.append(\n", " x, variable=[\"type\", \"i\"], value=\"L\", region=\"j\", unit=\"cases\", **args, inplace=True\n", ")" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "### Market prices at the demand centers\n", "\n", "The `market price` can be determined from the marginal value (field: `M`) of the demand-constraint equations." ] }, { "cell_type": "code", "execution_count": 10, "metadata": {}, "outputs": [ { "data": { "text/html": [ "
\n", "\n", "\n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", "
jMyear
0new-york0.2252020
1chicago0.1532020
2topeka0.1262020
\n", "
" ], "text/plain": [ " j M year\n", "0 new-york 0.225 2020\n", "1 chicago 0.153 2020\n", "2 topeka 0.126 2020" ] }, "execution_count": 10, "metadata": {}, "output_type": "execute_result" } ], "source": [ "demand = gdx.to_dataframe(\"demand\", fields=\"M\")[\"elements\"]\n", "demand[\"year\"] = 2020\n", "demand" ] }, { "cell_type": "code", "execution_count": 11, "metadata": {}, "outputs": [], "source": [ "df.append(\n", " demand,\n", " variable=\"market price\",\n", " value=\"M\",\n", " region=\"j\",\n", " unit=\"$/case\",\n", " **args,\n", " inplace=True,\n", ")" ] }, { "cell_type": "code", "execution_count": 12, "metadata": {}, "outputs": [ { "data": { "text/html": [ "
\n", "\n", "\n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", "
2020
modelscenarioregionvariableunit
transportbaselineUSAcost$153.675
chicagomarket price$/case0.153
supply|san-diegocases0.000
supply|seattlecases300.000
new-yorkmarket price$/case0.225
supply|san-diegocases275.000
supply|seattlecases50.000
topekamarket price$/case0.126
supply|san-diegocases275.000
supply|seattlecases0.000
\n", "
" ], "text/plain": [ " 2020\n", "model scenario region variable unit \n", "transport baseline USA cost $ 153.675\n", " chicago market price $/case 0.153\n", " supply|san-diego cases 0.000\n", " supply|seattle cases 300.000\n", " new-york market price $/case 0.225\n", " supply|san-diego cases 275.000\n", " supply|seattle cases 50.000\n", " topeka market price $/case 0.126\n", " supply|san-diego cases 275.000\n", " supply|seattle cases 0.000" ] }, "execution_count": 12, "metadata": {}, "output_type": "execute_result" } ], "source": [ "df.timeseries()" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "## Postprocessing to compute aggregate results\n", "\n", "It is often practical to not only have results at the most disaggregated level,\n", "but to also add aggregated results to the output.\n", "The **pyam** package offers several utilities to perform aggregation or validation;\n", "the following cell computes the total supply to each demand city\n", "and appends it to the **IamDataFrame**.\n", "\n", "The second cell again displays the complete data to illustrate the aggregation feature." ] }, { "cell_type": "code", "execution_count": 13, "metadata": {}, "outputs": [], "source": [ "df.aggregate(\"supply\", append=True)" ] }, { "cell_type": "code", "execution_count": 14, "metadata": {}, "outputs": [ { "data": { "text/html": [ "
\n", "\n", "\n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", "
2020
modelscenarioregionvariableunit
transportbaselineUSAcost$153.675
chicagomarket price$/case0.153
supplycases300.000
supply|san-diegocases0.000
supply|seattlecases300.000
new-yorkmarket price$/case0.225
supplycases325.000
supply|san-diegocases275.000
supply|seattlecases50.000
topekamarket price$/case0.126
supplycases275.000
supply|san-diegocases275.000
supply|seattlecases0.000
\n", "
" ], "text/plain": [ " 2020\n", "model scenario region variable unit \n", "transport baseline USA cost $ 153.675\n", " chicago market price $/case 0.153\n", " supply cases 300.000\n", " supply|san-diego cases 0.000\n", " supply|seattle cases 300.000\n", " new-york market price $/case 0.225\n", " supply cases 325.000\n", " supply|san-diego cases 275.000\n", " supply|seattle cases 50.000\n", " topeka market price $/case 0.126\n", " supply cases 275.000\n", " supply|san-diego cases 275.000\n", " supply|seattle cases 0.000" ] }, "execution_count": 14, "metadata": {}, "output_type": "execute_result" } ], "source": [ "df.timeseries()" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "## Visualization of results\n", "\n", "The **pyam** package includes a powerful plotting and visualization library.\n", "Most features are geared for timeseries data (for plotting development over time),\n", "but some are useful even for this small, stylized application:\n", "the next cell shows the regional share of supply from the two supply locations\n", "to the three demand centers." ] }, { "cell_type": "code", "execution_count": 15, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "" ] }, "execution_count": 15, "metadata": {}, "output_type": "execute_result" }, { "data": { "image/png": "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X1x01VVXddqyZYsq13z++ed3GjZs2KZly5YtOProo9evXr16u+/S++67r8WyZcsazZ07d9GiRYsWzp49u8ljjz3W7Nlnn23y0EMPtV64cOGCp59+euncuXObVkxz6qmn7nfZZZetXLJkycJ+/fp98LOf/axT5flWJ9cwsErSDcA44FFJDWswrZmZ2U4dcMABH0ybNq3FxIkTOz/++OPN2rZtW1bd+GPGjFnfrFmz6Nix47Zhw4ZtmDZtWlOAAQMGvF9SUrK1fv36nHDCCe9OmzatWfZ0vXv33tqqVattzz//fOP777+/Rb9+/TZ36NDhU8tq27ZtWcOGDcvHjRtXfPvtt7dq1qxZOcBrr72218iRI3v26tWr5He/+12HxYsXN66Y5mtf+9r6xo0bR8eOHbe1adPmo5UrV253Xt706dObn3baae8AnHjiiaUtWrTYbh0ff/zxFs8991yLkpKSkn79+pW88sorjRYvXtzo2WefbTZmzJj1TZo0idatW5ePHj16PcA777xTb+PGjfUOP/zwTQBnnHHGO9OnT29Web7VyfUL/QTgCeDQiFgPtAF+UpMFmZmZVWfgwIFbZs2atXDAgAEfXHjhhZ3PO++8jvXq1Yvy8nIAPvjgg099Z0mf/uFd0b+j9mzjx49/+6abbtr71ltv3Xv8+PHvVB7eoEEDZs+evei444577+GHH241atSongDf+973up599tlrlyxZsvD3v//961u2bPm4poYNG368z79evXps27ZNl19+ebs+ffqU9OnTp6Riz8XORATnnHPO6sWLFy9cvHjxwjfeeGP+j370o7dzmfazyikMRMRmYC0wImnaBizNV1FmZpY+y5cvb9C8efPys88++91zzz13zezZs5t06dJl6/PPP98EYMqUKZ/a3f/YY4+12rx5s9asWVNv+vTpzUeMGPE+ZA4TLF68eK+ysjLuvffeNiNHjtxYeVknn3zy+qlTp7acM2dO02OPPba08vDS0tKid999t964ceNKr7/++hWLFy9uArBx48Z6Xbt2/Qjgtttua7uzdbrgggvWVXypFxcXf/TFL35xY8V0U6ZMabFhw4btju2PGTNmw//93//tXVpaWgTw2muvNVi1alX9gw46aNMTTzzRcvPmzSotLS16+umnW0FmL0aLFi3KHn/88WYAN998c9thw4Zt2llt2XK6tFDSL4ChQG/gVqAB8AfgSzVZmJmZ7R4KcSngzJkzG19wwQVdioqKqF+/flx77bWvb968ueiss84qnjRpUtnw4cM/9aXet2/fzcOHD+/93nvv1T/vvPNWFxcXfzR//vxG/fv3f/+ss87qunz58kbDhw/fcPLJJ6+vvKxGjRrF8OHDN7Rq1aqsfv3tvwrXr19fb+zYsT0qjvtfcsklKwB+/vOfv3nSSSd1b9my5bYRI0ZsfOONNxrWZB2vuOKKN4899tjP9ejRo9/QoUM3dezYcWvlcY455pgNCxYsaPT5z3++D0CTJk3K77zzztcOOuigzYcddlhpSUlJv7Zt237Uu3fvD1q2bFkGcOutt742ceLEbj/4wQ+KunbtuuWuu+5aXpO6lH0m4w5HkmYDg4FZETE4aZsbEQNrsrBdbejQoTFjxoxClpBfF7es5eVtF473KMXnP1Kry1t+xeG1urw9md+7XUvSzIgYmt02Z86c5fvvv39ed0XvSueee26nZs2alU2aNOmt7PaHH364+dVXX91+6tSpy6qbvqysjH79+pXcc889rwwYMGBLRXtt32egpkpLS4tatmxZvnHjxqJhw4b1vv76618fMWLE5lymnTNnzt77779/cVXDcj1nYGtkUkMASGq6k/HNzMzqpJkzZzbq1q3bgJEjR27IDgK7g29/+9vd+vTpUzJw4MC+RxxxxHu5BoGdyfUOhFOSqwlaSToDOA24cVcUYGZmVlPXXHPNm1W1jx07duPYsWO3O0cg25AhQz5cuXJllb/+zzzzzLeqaq8rHnroodfyMd+cwkBEXCVpNLCBzHkDF0XEU/koyMzMrFAuuuiitYWuoRByPYGwKfBMRDwlqTfQW1KDiPgov+WZmZlZvuV6zsBzQENJnYHHgZOB2/JVlJmZmdWeXMOAknsNHANcFxHHA/2qnUC6RdJaSfOz2i6WtErS7OT19axhF0haJullSYd+lpUxMzOzmss5DEgaBnwLqLjGZ2cPQbgNOKyK9t9ExKDk9Wgy8xLgRDIB4zDgWkk1esiCmZmZfTa5Xk3wQ+AC4P6IWCDpc8DU6iaIiOckFec4/yOBuyNiC/CapGXAgcA/cpzezMx2pYtbDtm18yut9ZsYVda5c+cBM2bMWNSxY8dt1Y2zK+8z8MILLzResWLFXuPGjSuFzH0QGjZsWD569Oj3Ycf3S6htud6O+LmI+EZEXJn0vxoRP/iMy/yepLnJYYSKW0t2BlZkjbMyaduOpAmSZkiasW7dus9YgpmZWf7NmDGjySOPPPLxHeSeeeaZ5pUfnFQX5BQGJLWT9GtJj0p6puL1GZZ3HdAdGASsBq6u6QwiYnJEDI2Ioe3atfsMJZiZWV20YcOGolGjRvXo3bt3Sc+ePfvdeOONrTt37jxg9erV9QGee+65JgceeGBvyPyiPuqoo/YbNGhQn27duvW/+uqr94bML++hQ4f2HjVqVI/i4uL+3/zmN7uWlX36wYDnnHNOp0mTJu1T0f/973+/8yWXXLIPlZx99tmdu3fv3q9Xr14lEyZM6ALw5ptv1j/00EO79+/fv2///v37Pvnkk00Bpk6d2mTQoEF9+vbtWzJ48OA+c+bMafjhhx/q8ssv7/TQQw+17tOnT8nPf/7zDnfccUe766+/vn2fPn1KKp4lUGHBggUNR44c2bNfv359hwwZ0vull15qtIs38Q7lepjgTuBPwFjgLOAUoMY/yyPi490gkm4EHk56VwH7Zo3aJWkzM7OUuO+++1p06NDho7/97W/LIPNo3osvvniH4y9atKjxzJkzF23cuLHe4MGDSyoeODRv3rymL7300vxevXpt/fKXv9zzjjvuaD1+/Pj3KqabOHHi20cffXT3iy66aG1ZWRkPPPBA6xdffHFR9rzXrFlT79FHH2396quvzi8qKuLtt9+uB3DmmWfue+6557516KGHblq6dOlehx56aM9XX311wf777//hiy++uLhBgwY88MADzX/60592eeKJJ1654IIL3pwxY0bTO+644w3IPHkx+7DAk08+2aJimaeffnq3yZMnvz5gwIAtzzzzTNOJEyd2nT59+pJdt4V3LNcw0DYibpb0w4h4FnhW0os1XZikjhGxOuk9Gqi40uBB4I+SrgE6AT2Bf9V0/mZmtvs64IADPvj5z3++78SJEzsfeeSRpYcddli1T94bM2bM+mbNmkWzZs22DRs2bMO0adOatm7dumzAgAHvl5SUbAU44YQT3p02bVqz7DDQu3fvra1atdr2/PPPN169enWDfv36be7QocOndh+0bdu2rGHDhuXjxo0rHjt27PqKY/7PP/98i6VLlzauGG/Tpk31sp5wuN/y5csbSYqPPvpo++cmV6O0tLTopZdeanb88cd3r2jbunVrjebx78g1DFTcXGi1pMOBN4E21U0g6S5gFLC3pJXAL4BRkgaRecbBcuBMgOSkxCnAQjKPR/5uRJRVMVszM9tDDRw4cMusWbMW/vnPf2554YUXdn766ac31KtXL8rLy4HMr+rs8aVPf1dW9O+oPdv48ePfvummm/Zeu3Ztg/Hjx79TeXiDBg2YPXv2ogcffLDFvffe2/q6667bZ/r06UsiglmzZi1q0qTJp57yd9ppp3U96KCDNj711FOvvPzyy3sdfPDBvWuy7mVlZTRv3nzb4sWLF9Zkul0l10sLL5XUEvgxcB5wE3BOdRNExEkR0TEiGkREl4i4OSJOjogBETEwOSFxddb4v4qI7hHROyIe+6wrZGZmu6fly5c3aN68efnZZ5/97rnnnrtm9uzZTbp06bL1+eefbwIwZcqU1tnjP/bYY602b96sNWvW1Js+fXrzESNGvA+ZwwSLFy/eq6ysjHvvvbfNyJEjt3tWwcknn7x+6tSpLefMmdO04vBCtqxf+6XXX3/9isWLFzcBGDFixIbLL7/84/MLXnjhhcYAGzZsqNelS5etADfccMPeFcNbtGhRtmnTpo+/a5s3b162cePG7S6db9OmTXmXLl223nLLLa0BysvL+cc//tG48nj5kuuegeOBv0fEfOArktoAVwEP5a0yMzMrnAJcCjhz5szGF1xwQZeioiLq168f11577eubN28uOuuss4onTZpUNnz48E99qfft23fz8OHDe7/33nv1zzvvvNXFxcUfzZ8/v1H//v3fP+uss7ouX7680fDhwzecfPLJ6ysvq1GjRjF8+PANrVq1Kqtff/uvwvXr19cbO3Zsjy1btgjgkksuWQEwefLkFaeffnrXXr16lZSVlekLX/jCxuHDh7/xs5/9bM3pp5++35VXXtlp9OjRHy9vzJgxG6+66qqOffr0Kfnxj3+8+thjj11/3HHHdX/sscda/fa3v30je5l33XXXq2eccUa3K6+8suO2bdt09NFHvzts2LAPdsnG3Ylcw8DAiFhf0RMR70oanJ+SzMwsjY499tgNxx577Ha7yZcvXz6/qvEHDBjwwf3337+8cnvz5s3Lpk6duqxye/b9A8rKypg1a1aze+6555Wq5t2tW7eP5s2bt6hye8eOHbc98sgjr1Zu/+pXv/p+dp2/+93v3gRo37592fz58z81nyVLlny8jtnnRfTp02fr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", "text/plain": [ "
" ] }, "metadata": { "needs_background": "light" }, "output_type": "display_data" } ], "source": [ "df.filter(variable=\"supply|*\").plot.bar(x=\"region\")" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Visit the **pyam** [plotting gallery](https://pyam-iamc.readthedocs.io/en/stable/gallery/index.html)\n", "for more features and options!" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "## Exporting to different file formats\n", "\n", "You can use **pyam** to export the processed data in the IAMC format as an Excel table." ] }, { "cell_type": "code", "execution_count": 16, "metadata": {}, "outputs": [], "source": [ "df.to_excel(\"transport.xlsx\")" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "**pyam** also supports export to different file formats,\n", "for example the [frictionless data package](https://frictionlessdata.io)!" ] }, { "cell_type": "code", "execution_count": 17, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "" ] }, "execution_count": 17, "metadata": {}, "output_type": "execute_result" } ], "source": [ "df.to_datapackage(\"transport.zip\")" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "
\n", "\n", "**Questions?**\n", "Take a look at [this tutorial](https://pyam-iamc.readthedocs.io/en/stable/tutorials/pyam_first_steps.html) for *first steps with pyam* - then join our [mailing list](https://groups.io/g/pyam)!\n", "\n", "
" ] } ], "metadata": { "kernelspec": { "display_name": "Python 3", "language": "python", "name": "python3" }, "language_info": { "codemirror_mode": { "name": "ipython", "version": 3 }, "file_extension": ".py", "mimetype": "text/x-python", "name": "python", "nbconvert_exporter": "python", "pygments_lexer": "ipython3", "version": "3.8.3" }, "nbsphinx": { "execute": "never" } }, "nbformat": 4, "nbformat_minor": 4 }