Skip to content

Commit

Permalink
Moved visualization to its own module; automated generation of some m…
Browse files Browse the repository at this point in the history
…ain.ipynb markdown cells.
  • Loading branch information
milos-simic committed Jun 17, 2019
1 parent f0c3cee commit 880b06d
Show file tree
Hide file tree
Showing 4 changed files with 487 additions and 231 deletions.
107 changes: 27 additions & 80 deletions download_and_process.ipynb
Expand Up @@ -113,7 +113,8 @@
"source_list_filepath = os.path.join('input', 'sources.csv')\n",
"\n",
"# Import the utility functions and classes from the util package\n",
"import util.helper"
"import util.helper\n",
"from util.visualizer import visualize_points"
]
},
{
Expand Down Expand Up @@ -240,80 +241,6 @@
"valuenames.head(2)"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"## Visualizer\n",
"\n",
"Since many sources in the dataset come with the data on their geographical locations, having a way to visualize them on a map can be very useful. The next function serves exactly that purpose."
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"def visualize(latitudes, longitudes, country, categories=None, eps=0.03):\n",
" # Remove the locations not in Europe\n",
" european_latitude_mask = np.logical_and(latitudes >= 34, latitudes <= 81)\n",
" european_longitude_mask= np.logical_and(longitudes >= -31, longitudes <= 69)\n",
" european_mask = np.logical_and(european_latitude_mask, european_longitude_mask)\n",
" latitudes = latitudes[european_mask]\n",
" longitudes = longitudes[european_mask]\n",
" if categories is not None:\n",
" categories = categories[european_mask]\n",
" \n",
" # Determine the coordinates of boundary locations\n",
" max_lat = latitudes.max()\n",
" min_lat = latitudes.min()\n",
"\n",
" max_lon = longitudes.max()\n",
" min_lon = longitudes.min()\n",
" \n",
" # Make the area to show a bit larger\n",
" max_lat = max_lat + (max_lat - min_lat) * eps\n",
" min_lat = min_lat - (max_lat - min_lat) * eps\n",
" \n",
" max_lon = max_lon + (max_lon - min_lon) * eps\n",
" min_lon = min_lon - (max_lon - min_lon) * eps\n",
" \n",
" # Get the shape file for visualizing countries\n",
" shp_filename = shapereader.natural_earth('10m', 'cultural', 'admin_0_countries')\n",
" \n",
" df_geo = geopandas.read_file(shp_filename)\n",
" \n",
" polygon = df_geo.loc[df_geo['ADMIN'] == country]['geometry'].values[0]\n",
" # Make sure that polygon is technically multi-part\n",
" # (see https://github.com/SciTools/cartopy/issues/948)\n",
" if type(polygon) == shapely.geometry.polygon.Polygon:\n",
" polygon=[polygon]\n",
" # Make the figure\n",
" figure(num=None, figsize=(8, 6), dpi=100, facecolor='white', edgecolor='k')\n",
" ax = plt.axes(projection=ccrs.PlateCarree())\n",
" ax.add_geometries(polygon, crs=ccrs.PlateCarree(), facecolor='white', edgecolor='0.5', zorder=1)\n",
" ax.set_extent([min_lon, max_lon, min_lat, max_lat], crs=ccrs.PlateCarree())\n",
" ax.coastlines(resolution='10m', color='black')\n",
"\n",
" \n",
" # Plot the locations\n",
" if categories is None:\n",
" ax.scatter(longitudes, latitudes, s=1.5, zorder=2, c='#123456')\n",
" else:\n",
" labels = categories.unique()\n",
" for label in labels:\n",
" category_mask = (categories == label)\n",
" latitude_subset = latitudes[category_mask]\n",
" longitude_subset = longitudes[category_mask]\n",
" ax.scatter(longitude_subset, latitude_subset, s=1.5, zorder=2, label=label)\n",
" ax.legend()\n",
" \n",
" \n",
" # Show the figure\n",
" plt.show()"
]
},
{
"cell_type": "markdown",
"metadata": {},
Expand Down Expand Up @@ -1123,7 +1050,11 @@
"metadata": {},
"outputs": [],
"source": [
"visualize(DE_renewables['lat'], DE_renewables['lon'], 'Germany', categories=DE_renewables['energy_source_level_2'])"
"visualize_points(DE_renewables['lat'],\n",
" DE_renewables['lon'],\n",
" 'Germany',\n",
" categories=DE_renewables['energy_source_level_2']\n",
")"
]
},
{
Expand Down Expand Up @@ -1623,7 +1554,11 @@
},
"outputs": [],
"source": [
"visualize(DK_renewables['lat'], DK_renewables['lon'], 'Denmark', categories=DK_renewables['energy_source_level_2'])"
"visualize_points(DK_renewables['lat'],\n",
" DK_renewables['lon'],\n",
" 'Denmark',\n",
" categories=DK_renewables['energy_source_level_2']\n",
")"
]
},
{
Expand Down Expand Up @@ -1963,7 +1898,11 @@
"metadata": {},
"outputs": [],
"source": [
"visualize(FR_re_df['lat'], FR_re_df['lon'], 'France', categories=FR_re_df['energy_source_level_2'])"
"visualize_points(FR_re_df['lat'],\n",
" FR_re_df['lon'],\n",
" 'France',\n",
" categories=FR_re_df['energy_source_level_2']\n",
")"
]
},
{
Expand Down Expand Up @@ -2661,7 +2600,11 @@
"metadata": {},
"outputs": [],
"source": [
"visualize(CH_re_df['lat'], CH_re_df['lon'], 'Switzerland', categories=CH_re_df['energy_source_level_2'])"
"visualize_points(CH_re_df['lat'],\n",
" CH_re_df['lon'],\n",
" 'Switzerland',\n",
" categories=CH_re_df['energy_source_level_2']\n",
")"
]
},
{
Expand Down Expand Up @@ -3119,7 +3062,11 @@
"metadata": {},
"outputs": [],
"source": [
"visualize(UK_re_df['latitude'], UK_re_df['longitude'], 'United Kingdom', categories=UK_re_df['energy_source_level_2'])"
"visualize_points(UK_re_df['latitude'],\n",
" UK_re_df['longitude'],\n",
" 'United Kingdom',\n",
" categories=UK_re_df['energy_source_level_2']\n",
")"
]
},
{
Expand Down
13 changes: 13 additions & 0 deletions input/countries.csv
@@ -0,0 +1,13 @@
short_name,full_name,data_description,long_description
DE,Germany,"Individual power plants, all renewable energy plants supported by the German Renewable Energy Law (EEG).","In Germany, the four TSOs (50Hertz, Amprion, Tennet, TransnetBW) publish individual plant-level data on renewable power plants on their joint platform Netztransparenz.de. Since they are only updated once per year (usually in August) for the past year, their data is often a bit outdated. We therefore complement their data with data from BNetzA, which has more recent data.

Since August 2014 the BNetzA is responsible to publish the renewable power plants register. The legal framework for the register is specified in the EEG 2014 [(German)](http://www.gesetze-im-internet.de/eeg_2014/) [(English)](http://www.res-legal.eu/search-by-country/germany/single/s/res-e/t/promotion/aid/feed-in-tariff-eeg-feed-in-tariff/lastp/135/). All power plants are listed in a new format: two separate MS-Excel and CSV files for roof-mounted PV power plants ['PV-Datenmeldungen'](https://www.bundesnetzagentur.de/DE/Sachgebiete/ElektrizitaetundGas/Unternehmen_Institutionen/ErneuerbareEnergien/ZahlenDatenInformationen/EEG_Registerdaten/EEG_Registerdaten_node.html) and all other renewable power plants [' Anlagenregister'](https://www.bundesnetzagentur.de/DE/Sachgebiete/ElektrizitaetundGas/Unternehmen_Institutionen/ErneuerbareEnergien/ZahlenDatenInformationen/EEG_Registerdaten/EEG_Registerdaten_node.html).

From the beginning of 2019, BNetzA has switched to the Marktstammdatenregister (MaStR, central register for installation data). This is, however, not used yet for OPSD data. We will change to using the MaStR most likely for the 2020 version of the OPSD data package.
"
FR,France,"Summed capacity and number of installations per energy source per municipality (Commune).",""
DK,Denmark,"Wind and phovoltaic power plants with a high level of detail.",""
CH,Switzerland,"All renewable-energy power plants supported by the feed-in-tariff KEV.",""
PL,Poland,"Summed capacity and number of installations per energy source per municipality (Powiat).",""
UK,United Kingdom,"Renewable-energy power plants in the United Kingdom.",""

460 changes: 309 additions & 151 deletions main.ipynb

Large diffs are not rendered by default.

138 changes: 138 additions & 0 deletions util/visualizer.py
@@ -0,0 +1,138 @@
import cartopy.crs as ccrs
import cartopy.feature as cfeature
from cartopy.io import shapereader
import geopandas
import shapely
import numpy as np
import matplotlib.pyplot as plt
from matplotlib.pyplot import figure
#import matplotlib.pyplot as plt
import cartopy
#import cartopy.io.shapereader as shpreader
#import cartopy.crs as ccrs
#import pandas as pd

def visualize_points(latitudes, longitudes, country, categories=None, eps=0.03):
# Remove the locations not in Europe
european_latitude_mask = np.logical_and(latitudes >= 34, latitudes <= 81)
european_longitude_mask= np.logical_and(longitudes >= -31, longitudes <= 69)
european_mask = np.logical_and(european_latitude_mask, european_longitude_mask)
latitudes = latitudes[european_mask]
longitudes = longitudes[european_mask]
if categories is not None:
categories = categories[european_mask]

# Determine the coordinates of boundary locations
max_lat = latitudes.max()
min_lat = latitudes.min()

max_lon = longitudes.max()
min_lon = longitudes.min()

# Make the area to show a bit larger
max_lat = max_lat + (max_lat - min_lat) * eps
min_lat = min_lat - (max_lat - min_lat) * eps

max_lon = max_lon + (max_lon - min_lon) * eps
min_lon = min_lon - (max_lon - min_lon) * eps

# Get the shape file for visualizing countries
shp_filename = shapereader.natural_earth('10m', 'cultural', 'admin_0_countries')

df_geo = geopandas.read_file(shp_filename)

polygon = df_geo.loc[df_geo['ADMIN'] == country]['geometry'].values[0]
# Make sure that polygon is technically multi-part
# (see https://github.com/SciTools/cartopy/issues/948)
if type(polygon) == shapely.geometry.polygon.Polygon:
polygon=[polygon]
# Make the figure
figure(num=None, figsize=(8, 6), dpi=100, facecolor='white', edgecolor='k')
ax = plt.axes(projection=ccrs.PlateCarree())
ax.add_geometries(polygon, crs=ccrs.PlateCarree(), facecolor='white', edgecolor='0.5', zorder=1)
ax.set_extent([min_lon, max_lon, min_lat, max_lat], crs=ccrs.PlateCarree())
ax.coastlines(resolution='10m', color='black')


# Plot the locations
if categories is None:
ax.scatter(longitudes, latitudes, s=1.5, zorder=2, c='#123456')
else:
labels = categories.unique()
for label in labels:
category_mask = (categories == label)
latitude_subset = latitudes[category_mask]
longitude_subset = longitudes[category_mask]
ax.scatter(longitude_subset, latitude_subset, s=1.5, zorder=2, label=label)
ax.legend()


# Show the figure
plt.show()


def visualize_countries(countries):
""" Adapted from https://matthewkudija.com/blog/2018/05/25/country-maps/
"""
#projection = ccrs.Robinson()
print(countries)
title = "Countries currently covered by the OPSD renewable power plants package"

#ax = plt.axes(projection=projection)
#ax.add_feature(cartopy.feature.OCEAN, facecolor='white')
#ax.outline_patch.set_edgecolor("0.5")

figure(num=None, figsize=(8, 8), dpi=1000, facecolor='white', edgecolor='k')
ax = plt.axes(projection=ccrs.Orthographic())
# Get the shape file for visualizing countries
shp_filename = shapereader.natural_earth('10m', 'cultural', 'admin_0_countries')
df_geo = geopandas.read_file(shp_filename)
df_europe = df_geo.loc[df_geo["CONTINENT"] == "Europe", :]

for index, row in df_europe.iterrows():
polygon = row['geometry']
# Make sure that polygon is technically multi-part
# (see https://github.com/SciTools/cartopy/issues/948)
if type(polygon) == shapely.geometry.polygon.Polygon:
polygon=[polygon]
# Make the figure
if row["NAME"] in countries:
facecolor = "#000099"#"#71a2d6"
else:
facecolor = "#DDDDDD"
ax.add_geometries(polygon, crs=ccrs.PlateCarree(), facecolor=facecolor, edgecolor='#FFFFFF', zorder=1)
ax.set_extent([-31, 69, 34, 81], crs=ccrs.PlateCarree())
ax.coastlines(resolution='10m', color='grey')

plt.title(title, fontsize=8)

plt.show()


def mainam():
df = pd.read_csv('countries.csv', index_col='ISO_CODE')

projection = ccrs.Robinson()
title = 'Four Regions With The Same Population'
colors = ['#f4b042', '#92D050','#71a2d6','#b282ac','#DDDDDD']
#colors = ['#orange' ,'#green','#blue ','#purple','#grey ']
annotation = 'Four Regions With The Same Population: https://mapchart.net/showcase.html'
plot_countries(df,projection,colors,annotation,title,edgecolor='white')

projection = ccrs.Orthographic(-30,40)
colors = ['#71a2d6','#DDDDDD']
annotation = 'NATO Member Countries: https://en.wikipedia.org/wiki/Member_states_of_NATO'
title = 'NATO Members'
plot_countries(df,projection,colors,annotation,title,edgecolor='grey')

projection = ccrs.Orthographic(10,50)
colors = ['#000099','#DDDDDD']
annotation = 'EU Member Countries: https://en.wikipedia.org/wiki/Member_state_of_the_European_Union'
title = 'EU Members'
plot_countries(df,projection,colors,annotation,title,edgecolor='grey')

print('Done.\n')


if __name__ == '__main__':
main()

0 comments on commit 880b06d

Please sign in to comment.