#+OPTIONS: H:3 num:nil toc:nil \n:nil @:t ::t |:t ^:nil -:t f:t *:t TeX:t LaTeX:t skip:t d:t tags:not-in-toc creator:t timestamp:nil author:nil title:nil #+HTML_HEAD: #+HTML_HEAD: #+HTML_HEAD: #+HTML_HEAD: #+HTML_HEAD: #+HTML_HEAD: #+LANGUAGE: en-GB #+STARTUP: latexpreview #+TITLE: Plotting a GDP time series #+DATE: September 2022 #+AUTHOR: Stéphane Adjemian #+EMAIL: stephane.adjemian@univ-lemans.fr #+PROPERTY: header-args:python :python /tmp/blog-plt-ts/bin/python To plot a GDP time series (as in the slides of the introductory chapter of the course, [[https://le-mans.adjemian.eu/croissance/cours/introduction.pdf][here]], in French) one first has to find and download some data. As in the course, I use the [[https://www.rug.nl/ggdc/historicaldevelopment/maddison/releases/maddison-project-database-2020][Maddison Project Database]], which provides (very) long run data on GDP and population for more than 160 countries[fn:1: Data over very long periods, more than a century, are only available for a limited number of countries]. To download the data, which come as an Excel file, I use a small Python script: #+BEGIN_SRC bash :results silent :exports none :async t python3 -m venv /tmp/blog-plt-ts source /tmp/blog-plt-ts/bin/activate pip install pandas openpyxl matplotlib #+END_SRC #+begin_src python :session plt-ts-en :exports code :tangle gdppc-en.py :results none import urllib.request as url MADDISON = 'mpd2020' MADDISON_PATH = 'https://www.rug.nl/ggdc/historicaldevelopment/maddison/data/'+MADDISON+'.xlsx' File = url.urlopen(MADDISON_PATH) data = File.read() with open('./'+MADDISON+'.xlsx', 'wb') as f: f.write(data) #+end_src This script downloads an Excel file from the [[https://www.rug.nl/ggdc/historicaldevelopment/maddison/releases/maddison-project-database-2020][Maddison Project Database]] website and saves it locally on my disk. Since I do not like Excel files, I convert the file =mpd2020.xlsx= into a =csv= (Comma Separated Values) text file: #+begin_src python :session plt-ts-en :exports code :tangle gdppc-en.py :results none import pandas as pd data = pd.read_excel(MADDISON+'.xlsx', 'Full data', dtype=str, index_col=None) data.to_csv(MADDISON+'.csv', encoding='utf-8', index=False) #+end_src The file =mpd2020.csv= is saved to disk. It is a text file (which you can therefore read with any text editor, or process programmatically, for instance to build charts). The file contains a table. The first column gives a three-letter country code, the second the name of the country, the third the year, the fourth GDP per capita (in 2011 dollars) and the fifth the population in thousands. For instance, rows 2 to 73 contain observations for Afghanistan from 1820 to 2018. Note that the years are not necessarily consecutive (it depends on the country and the period) and that more or less data are available depending on the country (it depends on the history and culture of the country, more or less inclined towards statistics). In the course, I produced the charts with [[https://www.mathworks.com/products/matlab.html][Matlab]], a scientific computing language (the codes used for the charts of the course are available [[https://github.com/stepan-a/growth/tree/master/routines/introduction][here]]). This software is proprietary and not free. Here I show how to use Python (and the matplotlib library) to produce these charts. As an example, I will plot the evolution of real GDP per capita in France. Let us start by extracting from =data= (this object is what is called a =dataframe= and holds all the data) the observations for France. You can display the observations for France by selecting the corresponding rows as follows: #+begin_src python :session plt-ts-en :exports code :tangle no data[data["countrycode"]=="FRA"] #+end_src #+RESULTS: #+begin_example countrycode country year gdppc pop 5788 FRA France 1 956 5000 5789 FRA France 1000 NaN 6500 5790 FRA France 1280 1321 NaN 5791 FRA France 1281 1288 NaN 5792 FRA France 1282 1253 NaN ... ... ... ... ... ... 6494 FRA France 2014 36527 66374.29027 6495 FRA France 2015 36827 66610.71741 6496 FRA France 2016 37124 66786.7139 6497 FRA France 2017 37895.0004 66927.12053 6498 FRA France 2018 38515.9193 67028.7493 [711 rows x 5 columns] #+end_example The extract contains src_python[:session plt-ts-en]{data[data["countrycode"]=="FRA"].shape[0]} {{{results(=711=)}}} observations, and GDP per capita is observed annually from 1280 (that is, from the time of Philip III the Bold, son of Saint Louis) to 1789, then again from 1820 onwards. The file contains no observation between these two dates, thirty years covering the Revolution, the Empire and the beginning of the Restoration, and since the corresponding rows are missing rather than filled with =NaN=, the chart below bridges the gap with a straight line segment. Population is only observed annually from 1820 onwards. To plot this time series, one uses the =matplotlib= library (there are other plotting libraries which might let you obtain charts more to your taste): #+begin_src python :session plt-ts-en :exports code :tangle gdppc-en.py :results none import matplotlib.pyplot as plt # Select the data for France from 1280 onwards DATA = data[(data["countrycode"]=="FRA") & (data["year"].astype(int)>=1280)][["year","gdppc"]] # Convert the data to numeric values (so far they are character strings) DATA["year"] = pd.to_numeric(DATA["year"]) DATA["gdppc"] = pd.to_numeric(DATA["gdppc"]) # Plot DATA.plot(x="year",y="gdppc") plt.savefig("gdppc-fr.svg", transparent=True) #+end_src #+CAPTION: *GDP per capita in France since 1280.* #+LABEL: fig:gdppcfr [[file:gdppc-fr.svg]] One observes that not much happens until the beginning of the 19th century. Here the chart shows the level of GDP per capita; it would be more appropriate to display the natural logarithm of GDP per capita (to smooth out the explosive behaviour of the variable from the middle of the 19th century onwards, and possibly to get a better view of the fluctuations of GDP before 1820).