Plot Germany's electricity price

Power production from https://www.energy-charts.de/power/month_2015_04.json

Electricity price from http://www.pfbach.dk/

In [76]:
from __future__ import print_function, division

import pandas as pd, urllib, os, json

import matplotlib.pyplot as plt

import datetime as dt

data_folder = "data"

%matplotlib inline
In [77]:
def pad_number(number,digits):
    st = str(number)
    n_missing = digits - len(st)
    if n_missing > 0:
        return "0"*n_missing + st
    else:
        return st
In [78]:
pad_number(12,3)
Out[78]:
'012'
In [79]:
years = [2015]

datas = {}

for year in years:
    datas[year] = {}
    for month in range(1,13):
        file_name = "month_{}_{}.json".format(year,pad_number(month,2))
        path_name = os.path.join(data_folder,file_name)
        if not os.path.isfile(path_name):
            print("Downloading",file_name)
            url = "https://www.energy-charts.de/power/" + file_name
            urllib.urlretrieve (url, path_name)
        with open(path_name) as data_file:    
            datas[year][month] = json.load(data_file)
In [80]:
dt.datetime(1970,1,1) + dt.timedelta(seconds=datas[2015][1][0]["date"][0]/1000)
Out[80]:
datetime.datetime(2015, 6, 5, 9, 49, 38)
In [81]:
dt.datetime(1970,1,1) + dt.timedelta(seconds=(datas[2015][1][0]["values"][0][0]/1000+3600))
Out[81]:
datetime.datetime(2015, 1, 1, 0, 0)
In [82]:
year = 2015
month = 2

pd.date_range(dt.datetime(year,month,1),dt.datetime(year,month+1,1)-dt.timedelta(hours=1),freq="H")
Out[82]:
DatetimeIndex(['2015-02-01 00:00:00', '2015-02-01 01:00:00',
               '2015-02-01 02:00:00', '2015-02-01 03:00:00',
               '2015-02-01 04:00:00', '2015-02-01 05:00:00',
               '2015-02-01 06:00:00', '2015-02-01 07:00:00',
               '2015-02-01 08:00:00', '2015-02-01 09:00:00',
               ...
               '2015-02-28 14:00:00', '2015-02-28 15:00:00',
               '2015-02-28 16:00:00', '2015-02-28 17:00:00',
               '2015-02-28 18:00:00', '2015-02-28 19:00:00',
               '2015-02-28 20:00:00', '2015-02-28 21:00:00',
               '2015-02-28 22:00:00', '2015-02-28 23:00:00'],
              dtype='datetime64[ns]', length=672, freq='H')
In [95]:
columns = [d["key"][0]["en"] for d in datas[years[0]][1]]
data = []

for year in years:
    for month in range(1,13):
        for i in range(len(columns)):
            if datas[year][month][i]["key"][0]["en"] != columns[i]:
                print("Error")
        for j in range(len(datas[year][month][0]["values"])):
            data.append([d["values"][j][1] for d in datas[year][month]])
In [97]:
index = pd.date_range("2015-01-01 00:00","2015-12-31 23:00",freq="H")

df = pd.DataFrame(data=data,
                  columns=columns,
                  index=index)
In [104]:
df.rename(columns={"Import Balance" : "Imports",
           "Hydro Power" : "Hydro",
           "Uranium" : "Nuclear"},inplace=True)
df.describe()
Out[104]:
Imports Hydro Biomass Nuclear Brown Coal Hard Coal Gas Oil Others Pumped Storage Seasonal Storage Wind Solar
count 8760.000000 8760.000000 8760.000000 8760.000000 8760.000000 8760.000000 8760.000000 8760.000000 8760.000000 8760.000000 8760.000000 8760.000000 8760.000000
mean -5.348893 2.467432 5.346180 10.048257 15.992861 11.618610 3.763840 0.259309 0.090096 1.049443 0.181957 8.934102 3.820646
std 2.962256 0.624834 0.387098 1.387940 2.521052 5.728519 2.088773 0.150649 0.070991 0.933206 0.150769 7.139880 5.829201
min -15.862000 0.443000 4.786000 5.727000 6.845000 1.621000 0.789000 0.000000 0.006000 0.008000 0.000000 0.123000 0.000000
25% -7.308000 2.007000 4.853000 9.465000 14.503750 6.194250 2.199750 0.201000 0.055000 0.384000 0.059000 3.468000 0.000000
50% -5.412500 2.416000 5.303000 10.435000 16.368500 12.061000 3.239500 0.220000 0.066000 0.691500 0.140000 6.724000 0.126500
75% -3.488750 2.937000 5.599000 10.786000 17.979250 16.749250 4.548000 0.229000 0.096000 1.432000 0.274000 12.938750 6.103500
max 5.969000 4.091000 5.925000 12.077000 19.979000 22.190000 14.062000 1.408000 0.421000 5.909000 0.651000 32.609000 25.812000
In [103]:
df.drop(["Import Balance"],axis=1).plot(kind="area")
Out[103]:
<matplotlib.axes._subplots.AxesSubplot at 0x7f62996d59d0>
In [109]:
fig,ax = plt.subplots(1,1)

fig.set_size_inches(12,6)

start = "2015-01-01"

stop = "2015-01-31"


colors = {"Brown Coal" : "brown",
          "Hard Coal" : "k",
          "Nuclear" : "r",
          "Hydro" : "cyan",
          "Wind" : "blue",
          "Solar" : "yellow",
          "Biomass" : "green",
          "Waste" : "orange",
          "Gas" : "orange"}
#reorder
cols = ["Nuclear","Brown Coal","Hard Coal","Gas","Hydro","Biomass","Wind","Solar"]

df[cols][start:stop].plot(kind="area",
                         ax=ax,
                         colors=[colors[col] for col in cols],
                         linewidth=4)

ax.set_ylabel("Electricity generation in Germany [GW]")


ax.set_ylim([0,100])

(-df["Imports"][start:stop]).plot(ax=ax,color="magenta",label="Exports",linewidth=3)

ax.legend(loc="upper left",ncol=5)

ax.yaxis.grid(True)
In [64]:
fig.tight_layout()
#fig.savefig("germany_generation.pdf")

Get electricity price

In [12]:
price_df = pd.read_excel("data/2015_de_spot_price.xls",skiprows=3)
In [15]:
price = pd.Series(price_df[u"€/MWh"].values,pd.date_range("2015-01-01 00:00","2015-12-31 23:00",freq="H"))
In [17]:
price.plot(grid=True)
Out[17]:
<matplotlib.axes._subplots.AxesSubplot at 0x7f629c9ac090>

Plot both together

In [132]:
fig,axes = plt.subplots(2,1)

fig.set_size_inches(12,8)

ax = axes[0]

start = "2015-01-06"

stop = "2015-01-12"


colors = {"Brown Coal" : "brown",
          "Hard Coal" : "k",
          "Nuclear" : "r",
          "Hydro" : "cyan",
          "Wind" : "blue",
          "Solar" : "yellow",
          "Biomass" : "green",
          "Waste" : "orange",
          "Gas" : "orange"}
#reorder
cols = ["Nuclear","Brown Coal","Hard Coal","Gas","Hydro","Biomass","Wind","Solar"]

df[cols][start:stop].plot(kind="area",
                         ax=ax,
                         colors=[colors[col] for col in cols],
                         linewidth=1)

ax.set_ylabel("Electricity generation in Germany [GW]")


ax.set_ylim([0,110])

(-df["Imports"][start:stop]).plot(ax=ax,color="magenta",label="Exports",linewidth=1)

ax.legend(loc="upper left",ncol=5)

ax.grid(True)

ax = axes[1]

ax.set_ylabel(u"Spot price [€/MWh]")


price[start:stop].plot(ax=ax)


ax.grid(True)
In [133]:
fig.tight_layout()
fig.savefig("germany_generation-price-{}-{}.pdf".format(start,stop))
In [ ]: