Example of DOV search methods for groundwater samples (grondwatermonsters)¶
Use cases:¶
Get groundwater samples in a bounding box
Get groundwater samples with specific properties
Get the coordinates of all groundwater samples in Ghent
Get groundwater samples based on a combination of specific properties
Get groundwater samples based on a selection of screens (filters)
[1]:
%matplotlib inline
import inspect, sys
[2]:
# check pydov path
import pydov
Get information about the datatype ‘GrondwaterMonster’¶
[3]:
from pydov.search.grondwatermonster import GrondwaterMonsterSearch
gwmonster = GrondwaterMonsterSearch()
A description is provided for the ‘GrondwaterMonster’ datatype:
[4]:
print(gwmonster.get_description())
In de Databank Ondergrond Vlaanderen zijn verschillende grondwatermeetnetten opgenomen. Deze meetnetten staan in functie van uitgebreide monitoringprogramma’s met de bedoeling een goed beeld te krijgen van de beschikbare grondwaterkwantiteit en grondwaterkwaliteit van de watervoerende lagen in Vlaanderen.
Deze kaartlaag toont alle watermonsters die in de meetnetten opgenomen zijn.
The different fields that are available for objects of the ‘GrondwaterMonster’ datatype can be requested with the get_fields() method:
[5]:
fields = gwmonster.get_fields()
# print available fields
for f in fields.values():
print(f['name'])
gw_id
filternummer
pkey_filter
grondwatermonsternummer
pkey_grondwatermonster
pkey_grondwaterlocatie
x
y
start_grondwaterlocatie_mtaw
gemeente
datum_monstername
kationen
anionen
zware_metalen
pesticiden_actieve_stoffen
pesticiden_relevante_metabolieten
niet_relevante_metabolieten_van_pesticiden
fysico_chemische_parameters
organische_verbindingen
chemisch_PFAS
andere_parameters
opdrachten
eerste_invoer
geom
parametergroep
parameter
detectie
waarde
eenheid
veld_labo
You can get more information of a field by requesting it from the fields dictionary:
name: name of the field
definition: definition of this field
cost: currently this is either 1 or 10, depending on the datasource of the field. It is an indication of the expected time it will take to retrieve this field in the output dataframe.
notnull: whether the field is mandatory or not
type: datatype of the values of this field
[6]:
# print information for a certain field
fields['waarde']
[6]:
{'name': 'waarde',
'type': 'float',
'definition': 'waarde (numeriek) van de parameter',
'notnull': False,
'query': False,
'cost': 10}
Optionally, if the values of the field have a specific domain the possible values are listed as values:
[7]:
# if an attribute can have several values, these are listed under 'values', e.g. for 'parameter':
list(fields['parameter']['values'].items())[0:10]
[7]:
[('1112TCA', 'parameter 1,1,1,2-Tetrachloorethaan'),
('111TCA', 'parameter 1,1,1-trichloorethaan'),
('1122TCA', 'parameter 1,1,2,2-Tetrachloorethaan'),
('112TCA', 'parameter 1,1,2-trichloorethaan'),
('11DCA', 'parameter 1,1-Dichloorethaan'),
('11DCE', 'parameter 1,1-Dichlooretheen'),
('11DCPE', 'parameter 1,1-Dichloorpropeen'),
('123TCB', 'parameter 1,2,3-Trichloorbenzeen '),
('123TCPA', 'parameter 1,2,3-Trichloropropaan'),
('123TMB', 'parameter 1,2,3-Trimethylbenzeen')]
[8]:
fields['parameter']['values']['NH4']
[8]:
'parameter Ammonium'
Example use cases¶
Get groundwater samples in a bounding box¶
Get data for all the groundwater samples that are geographically located within the bounds of the specified box.
The coordinates are in the Belgian Lambert72 (EPSG:31370) coordinate system and are given in the order of lower left x, lower left y, upper right x, upper right y.
[9]:
from pydov.util.location import Within, Box
df = gwmonster.search(location=Within(Box(93378, 168009, 94246, 169873)))
df.head()
[000/001] .
[000/051] ..................................................
[050/051] .
[9]:
pkey_grondwatermonster | grondwatermonsternummer | pkey_grondwaterlocatie | gw_id | pkey_filter | filternummer | x | y | start_grondwaterlocatie_mtaw | gemeente | datum_monstername | parametergroep | parameter | detectie | waarde | eenheid | veld_labo | |
---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
0 | https://www.dov.vlaanderen.be/data/watermonste... | SWPP023-38534 | https://www.dov.vlaanderen.be/data/put/2018-00... | SWPP023 | https://www.dov.vlaanderen.be/data/filter/2007... | 1 | 94053.0 | 169638.0 | 10.09 | Wortegem-Petegem | 2014-02-19 | Kationen | K | NaN | 2.99 | mg/l | LABO |
1 | https://www.dov.vlaanderen.be/data/watermonste... | SWPP023-38534 | https://www.dov.vlaanderen.be/data/put/2018-00... | SWPP023 | https://www.dov.vlaanderen.be/data/filter/2007... | 1 | 94053.0 | 169638.0 | 10.09 | Wortegem-Petegem | 2014-02-19 | Onbekend | %AfwijkBalans | NaN | 6.20 | % | LABO |
2 | https://www.dov.vlaanderen.be/data/watermonste... | SWPP023-38534 | https://www.dov.vlaanderen.be/data/put/2018-00... | SWPP023 | https://www.dov.vlaanderen.be/data/filter/2007... | 1 | 94053.0 | 169638.0 | 10.09 | Wortegem-Petegem | 2014-02-19 | Anionen | NO2 | < | 0.05 | mg/l | LABO |
3 | https://www.dov.vlaanderen.be/data/watermonste... | SWPP023-38534 | https://www.dov.vlaanderen.be/data/put/2018-00... | SWPP023 | https://www.dov.vlaanderen.be/data/filter/2007... | 1 | 94053.0 | 169638.0 | 10.09 | Wortegem-Petegem | 2014-02-19 | Kationen | Na | NaN | 16.98 | mg/l | LABO |
4 | https://www.dov.vlaanderen.be/data/watermonste... | SWPP023-38534 | https://www.dov.vlaanderen.be/data/put/2018-00... | SWPP023 | https://www.dov.vlaanderen.be/data/filter/2007... | 1 | 94053.0 | 169638.0 | 10.09 | Wortegem-Petegem | 2014-02-19 | Fysico-chemische parameters | pH | NaN | 7.45 | Sörensen | LABO |
Using the pkey attributes one can request the details of the corresponding grondwatermonster in a webbrowser (only showing the first unique records):
[10]:
for pkey_grondwatermonster in df.pkey_grondwatermonster.unique()[0:5]:
print(pkey_grondwatermonster)
https://www.dov.vlaanderen.be/data/watermonster/2014-246678
https://www.dov.vlaanderen.be/data/watermonster/1999-246645
https://www.dov.vlaanderen.be/data/watermonster/2014-246647
https://www.dov.vlaanderen.be/data/watermonster/2011-246677
https://www.dov.vlaanderen.be/data/watermonster/2000-246650
Get groundwater samples with specific properties¶
Next to querying groundwater samples based on their geographic location within a bounding box, we can also search for groundwater samples matching a specific set of properties. For this we can build a query using a combination of the ‘GrondwaterMonster’ fields and operators provided by the WFS protocol.
A list of possible operators can be found below:
[11]:
[i for i,j in inspect.getmembers(sys.modules['owslib.fes2'], inspect.isclass) if 'Property' in i]
[11]:
['PropertyIsBetween',
'PropertyIsEqualTo',
'PropertyIsGreaterThan',
'PropertyIsGreaterThanOrEqualTo',
'PropertyIsLessThan',
'PropertyIsLessThanOrEqualTo',
'PropertyIsLike',
'PropertyIsNotEqualTo',
'PropertyIsNull',
'SortProperty']
In this example we build a query using the PropertyIsEqualTo operator to find all groundwater samples that are within the community (gemeente) of ‘Leuven’:
[12]:
from owslib.fes2 import PropertyIsEqualTo
query = PropertyIsEqualTo(
propertyname='gemeente',
literal='Leuven')
df = gwmonster.search(query=query)
df.head()
[000/001] .
[000/208] ..................................................
[050/208] ..................................................
[100/208] ..................................................
[150/208] ..................................................
[200/208] ........
[12]:
pkey_grondwatermonster | grondwatermonsternummer | pkey_grondwaterlocatie | gw_id | pkey_filter | filternummer | x | y | start_grondwaterlocatie_mtaw | gemeente | datum_monstername | parametergroep | parameter | detectie | waarde | eenheid | veld_labo | |
---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
0 | https://www.dov.vlaanderen.be/data/watermonste... | 2-0005/M2009 | https://www.dov.vlaanderen.be/data/put/2017-00... | 2-0005 | https://www.dov.vlaanderen.be/data/filter/1974... | 1 | 171548.64 | 172680.85 | 26.21 | Leuven | 2009-12-14 | Fysico-chemische parameters | TOC | NaN | 37.29 | mg/l | LABO |
1 | https://www.dov.vlaanderen.be/data/watermonste... | 2-0005/M2009 | https://www.dov.vlaanderen.be/data/put/2017-00... | 2-0005 | https://www.dov.vlaanderen.be/data/filter/1974... | 1 | 171548.64 | 172680.85 | 26.21 | Leuven | 2009-12-14 | Zware metalen | Al | < | 0.02 | mg/l | LABO |
2 | https://www.dov.vlaanderen.be/data/watermonste... | 2-0005/M2009 | https://www.dov.vlaanderen.be/data/put/2017-00... | 2-0005 | https://www.dov.vlaanderen.be/data/filter/1974... | 1 | 171548.64 | 172680.85 | 26.21 | Leuven | 2009-12-14 | Zware metalen | Ni | < | 5.00 | µg/l | LABO |
3 | https://www.dov.vlaanderen.be/data/watermonste... | 2-0005/M2009 | https://www.dov.vlaanderen.be/data/put/2017-00... | 2-0005 | https://www.dov.vlaanderen.be/data/filter/1974... | 1 | 171548.64 | 172680.85 | 26.21 | Leuven | 2009-12-14 | Fysico-chemische parameters | EC(Lab.) | NaN | 650.00 | µS/cm(20°C) | LABO |
4 | https://www.dov.vlaanderen.be/data/watermonste... | 2-0005/M2009 | https://www.dov.vlaanderen.be/data/put/2017-00... | 2-0005 | https://www.dov.vlaanderen.be/data/filter/1974... | 1 | 171548.64 | 172680.85 | 26.21 | Leuven | 2009-12-14 | Kationen | NH4 | NaN | 0.29 | mg/l | LABO |
Once again we can use the pkey_grondwatermonster as a permanent link to the information of the groundwater samples:
[13]:
for pkey_grondwatermonster in df.pkey_grondwatermonster.unique()[0:5]:
print(pkey_grondwatermonster)
https://www.dov.vlaanderen.be/data/watermonster/2009-001087
https://www.dov.vlaanderen.be/data/watermonster/2009-001091
https://www.dov.vlaanderen.be/data/watermonster/2006-060958
https://www.dov.vlaanderen.be/data/watermonster/2009-060960
https://www.dov.vlaanderen.be/data/watermonster/2006-060964
We can add the descriptions of the parameter values as an extra column ‘parameter_label’:
[14]:
df['parameter_label'] = df['parameter'].map(fields['parameter']['values'])
df[['pkey_grondwatermonster', 'datum_monstername', 'parameter', 'parameter_label', 'waarde', 'eenheid']].head()
[14]:
pkey_grondwatermonster | datum_monstername | parameter | parameter_label | waarde | eenheid | |
---|---|---|---|---|---|---|
0 | https://www.dov.vlaanderen.be/data/watermonste... | 2009-12-14 | TOC | parameter Totaal organische koolstof | 37.29 | mg/l |
1 | https://www.dov.vlaanderen.be/data/watermonste... | 2009-12-14 | Al | parameter Aluminium | 0.02 | mg/l |
2 | https://www.dov.vlaanderen.be/data/watermonste... | 2009-12-14 | Ni | parameter Nikkel | 5.00 | µg/l |
3 | https://www.dov.vlaanderen.be/data/watermonste... | 2009-12-14 | EC(Lab.) | parameter Geleidbaarheid in het labo | 650.00 | µS/cm(20°C) |
4 | https://www.dov.vlaanderen.be/data/watermonste... | 2009-12-14 | NH4 | parameter Ammonium | 0.29 | mg/l |
Get groundwater screens based on a combination of specific properties¶
Get all groundwater screens in Hamme that have measurements for cations (kationen). And filter to get only Sodium values after fetching all records.
[15]:
from owslib.fes2 import Or, Not, PropertyIsNull, PropertyIsLessThanOrEqualTo, And, PropertyIsLike
query = And([PropertyIsEqualTo(propertyname='gemeente',
literal='Hamme'),
PropertyIsEqualTo(propertyname='kationen',
literal='true')
])
df_hamme = gwmonster.search(query=query,
return_fields=('pkey_grondwatermonster', 'parameter', 'parametergroep', 'waarde', 'eenheid','datum_monstername'))
df_hamme.head()
[000/001] .
[000/318] ..................................................
[050/318] ..................................................
[100/318] ..................................................
[150/318] ..................................................
[200/318] ..................................................
[250/318] ..................................................
[300/318] ..................
[15]:
pkey_grondwatermonster | parameter | parametergroep | waarde | eenheid | datum_monstername | |
---|---|---|---|---|---|---|
0 | https://www.dov.vlaanderen.be/data/watermonste... | HCO3 | Anionen | 854.00 | mg/l | 2014-02-25 |
1 | https://www.dov.vlaanderen.be/data/watermonste... | SO4 | Anionen | 18.00 | mg/l | 2014-02-25 |
2 | https://www.dov.vlaanderen.be/data/watermonste... | O2 | Fysico-chemische parameters | 0.13 | mg/l | 2014-02-25 |
3 | https://www.dov.vlaanderen.be/data/watermonste... | Mn | Kationen | 0.04 | mg/l | 2014-02-25 |
4 | https://www.dov.vlaanderen.be/data/watermonste... | K | Kationen | 12.00 | mg/l | 2014-02-25 |
You should note that this initial dataframe contains all parameters (not just the cations). The filter will only make sure that only samples where any cation was analysed are in the list. If we want to filter more, we should do so in the resulting dataframe.
[16]:
df_hamme = df_hamme[df_hamme.parameter=='Na']
df_hamme.head()
[16]:
pkey_grondwatermonster | parameter | parametergroep | waarde | eenheid | datum_monstername | |
---|---|---|---|---|---|---|
26 | https://www.dov.vlaanderen.be/data/watermonste... | Na | Kationen | 350.00 | mg/l | 2014-02-25 |
39 | https://www.dov.vlaanderen.be/data/watermonste... | Na | Kationen | 61.20 | mg/l | 2009-12-23 |
98 | https://www.dov.vlaanderen.be/data/watermonste... | Na | Kationen | 364.64 | mg/l | 2011-11-04 |
102 | https://www.dov.vlaanderen.be/data/watermonste... | Na | Kationen | 364.40 | mg/l | 2009-03-13 |
144 | https://www.dov.vlaanderen.be/data/watermonste... | Na | Kationen | 27.50 | mg/l | 2006-02-20 |
Working with water samples¶
For further analysis and visualisation of the time series data, we can use the data analysis library pandas and visualisation library matplotlib.
[17]:
import pandas as pd
import matplotlib.pyplot as plt
Query the data of a specific filter using its pkey
:
[18]:
query = PropertyIsEqualTo(
propertyname='pkey_filter',
literal='https://www.dov.vlaanderen.be/data/filter/1991-001040')
df = gwmonster.search(query=query)
df.head()
[000/001] .
[000/014] cccccccccccccc
[18]:
pkey_grondwatermonster | grondwatermonsternummer | pkey_grondwaterlocatie | gw_id | pkey_filter | filternummer | x | y | start_grondwaterlocatie_mtaw | gemeente | datum_monstername | parametergroep | parameter | detectie | waarde | eenheid | veld_labo | |
---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
0 | https://www.dov.vlaanderen.be/data/watermonste... | 4-0076/M2006 | https://www.dov.vlaanderen.be/data/put/2017-00... | 4-0076 | https://www.dov.vlaanderen.be/data/filter/1991... | 1 | 133981.28 | 199152.75 | 4.3 | Hamme | 2006-05-24 | Fysico-chemische parameters | Eh° | NaN | 120.00 | mV | LABO |
1 | https://www.dov.vlaanderen.be/data/watermonste... | 4-0076/M2006 | https://www.dov.vlaanderen.be/data/put/2017-00... | 4-0076 | https://www.dov.vlaanderen.be/data/filter/1991... | 1 | 133981.28 | 199152.75 | 4.3 | Hamme | 2006-05-24 | Kationen | Fe | NaN | 9.45 | mg/l | LABO |
2 | https://www.dov.vlaanderen.be/data/watermonste... | 4-0076/M2006 | https://www.dov.vlaanderen.be/data/put/2017-00... | 4-0076 | https://www.dov.vlaanderen.be/data/filter/1991... | 1 | 133981.28 | 199152.75 | 4.3 | Hamme | 2006-05-24 | Anionen | Cl | NaN | 108.00 | mg/l | LABO |
3 | https://www.dov.vlaanderen.be/data/watermonste... | 4-0076/M2006 | https://www.dov.vlaanderen.be/data/put/2017-00... | 4-0076 | https://www.dov.vlaanderen.be/data/filter/1991... | 1 | 133981.28 | 199152.75 | 4.3 | Hamme | 2006-05-24 | Kationen | Mg | NaN | 39.20 | mg/l | LABO |
4 | https://www.dov.vlaanderen.be/data/watermonste... | 4-0076/M2006 | https://www.dov.vlaanderen.be/data/put/2017-00... | 4-0076 | https://www.dov.vlaanderen.be/data/filter/1991... | 1 | 133981.28 | 199152.75 | 4.3 | Hamme | 2006-05-24 | Anionen | HCO3 | NaN | 863.40 | mg/l | LABO |
The date is still stored as a string type. Transforming to a data type using the available pandas function `to_datetime
<https://pandas.pydata.org/pandas-docs/stable/generated/pandas.to_datetime.html>`__ and using these dates as row index:
[19]:
df['datum_monstername'] = pd.to_datetime(df['datum_monstername'])
For many usecases, it is useful to create a pivoted table, showing the value per parameter
[20]:
pivot = df.pivot_table(columns=df.parameter, values='waarde', index='datum_monstername')
pivot
[20]:
parameter | %AfwijkBalans | Al | As | B | Br | CO3 | Ca | Cd | Cl | Co | ... | PO4(Tot.) | Pb | SO4 | SomAN | SomKAT | T | TOC | Zn | pH | pH(Lab.) |
---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
datum_monstername | |||||||||||||||||||||
2006-05-24 | NaN | 0.05 | 5.00 | NaN | NaN | NaN | 399.00 | 0.50 | 108.00 | NaN | ... | 0.1 | 5.0 | 488.00 | NaN | NaN | 13.90 | 58.00 | 16.00 | 6.70 | NaN |
2009-03-13 | NaN | NaN | 5.00 | NaN | NaN | 1.0 | 394.70 | 0.50 | 96.00 | NaN | ... | NaN | 10.0 | 431.00 | NaN | NaN | 12.70 | 8.59 | 10.00 | 6.76 | 6.80 |
2009-12-23 | NaN | NaN | 12.47 | NaN | NaN | 1.0 | 447.20 | 0.50 | 105.00 | NaN | ... | NaN | 5.0 | 433.60 | NaN | NaN | 10.80 | 8.90 | 24.94 | 7.04 | 6.90 |
2011-03-28 | NaN | NaN | 13.00 | NaN | NaN | 1.0 | 331.10 | 0.52 | 107.00 | NaN | ... | NaN | 5.0 | 290.10 | NaN | NaN | 12.00 | 9.98 | 12.98 | 6.70 | 6.90 |
2011-11-04 | NaN | NaN | 8.40 | 112.0 | NaN | 1.0 | 345.00 | 0.50 | 99.00 | 5.00 | ... | NaN | 5.0 | 385.49 | NaN | NaN | 12.10 | 8.34 | 10.90 | 6.73 | 7.40 |
2012-11-26 | NaN | NaN | NaN | NaN | NaN | 1.0 | 360.00 | NaN | 95.00 | NaN | ... | NaN | NaN | 313.00 | NaN | NaN | 12.70 | 7.78 | NaN | 6.61 | 7.18 |
2014-02-25 | NaN | NaN | 2.00 | 100.0 | NaN | 1.0 | 330.00 | 0.03 | 91.00 | 0.57 | ... | NaN | 2.0 | 190.00 | NaN | NaN | 12.40 | 7.50 | 5.00 | 6.82 | 7.10 |
2014-09-30 | NaN | 0.02 | 2.30 | 100.0 | NaN | 1.0 | 280.00 | 0.03 | 87.75 | 0.65 | ... | NaN | 2.0 | 143.20 | NaN | NaN | 12.40 | 5.80 | 5.00 | 6.82 | 6.90 |
2015-09-30 | -6.05 | 0.05 | 5.00 | 115.5 | NaN | 1.0 | 299.41 | 0.50 | 88.88 | 5.00 | ... | NaN | 5.0 | 171.15 | 22.35 | 19.80 | 11.99 | 9.19 | 47.29 | 6.68 | 6.80 |
2016-07-12 | NaN | 0.02 | 5.00 | 138.7 | NaN | 1.0 | 335.52 | 0.40 | 91.58 | 3.00 | ... | NaN | 5.0 | 224.02 | 22.53 | 22.43 | 12.20 | 8.75 | 16.47 | 7.41 | 6.79 |
2017-03-27 | -7.31 | 0.10 | 5.00 | 97.3 | NaN | 1.0 | 289.16 | 0.40 | 76.48 | 3.00 | ... | NaN | 5.0 | 218.41 | 23.02 | 19.89 | 12.30 | 8.00 | 10.00 | 6.76 | 6.77 |
2018-09-03 | 0.83 | 0.02 | 5.00 | 134.9 | NaN | 1.0 | 354.30 | 0.40 | 88.60 | 3.00 | ... | NaN | 5.0 | 222.84 | 23.20 | 23.59 | 12.30 | 9.14 | 10.00 | 6.87 | 6.88 |
2019-06-13 | 2.06 | 0.03 | 5.00 | 133.2 | 0.62 | 1.0 | 333.99 | 0.40 | 78.67 | 3.00 | ... | NaN | 5.0 | 187.69 | 21.97 | 22.90 | 14.20 | 9.54 | 10.00 | 6.93 | 6.75 |
2020-06-09 | 0.23 | 0.02 | 5.00 | 179.7 | 0.58 | 1.0 | 291.60 | 0.40 | 64.94 | 3.00 | ... | NaN | 5.0 | 134.33 | 20.46 | 20.55 | 13.60 | 11.25 | 10.00 | 6.63 | 6.79 |
14 rows × 40 columns
Plotting¶
The default plotting functionality of Pandas can be used:
[21]:
parameters = ['NO3', 'NO2', 'NH4']
ax = pivot[parameters].plot.line(style='.-', figsize=(12, 5))
ax.set_xlabel('');
ax.set_ylabel('concentration (mg/l)');
ax.set_title('Concentration nitrite, nitrate and ammonium for filter id 1991-001040');

Combine search in filters and groundwater samples¶
For this example, we will first search filters, and later search all samples for this selection. We will select filters in the primary network located in Kalmthout.
[22]:
from pydov.search.grondwaterfilter import GrondwaterFilterSearch
from pydov.util.query import Join
gfs = GrondwaterFilterSearch()
gemeente = 'Kalmthout'
filter_query = And([PropertyIsLike(propertyname='meetnet',
literal='meetnet 1 %'),
PropertyIsEqualTo(propertyname='gemeente',
literal=gemeente)])
filters = gfs.search(query=filter_query, return_fields=['pkey_filter'])
monsters = gwmonster.search(query=Join(filters, 'pkey_filter'))
monsters.head()
[000/001] .
[000/001] .
[000/212] ..................................................
[050/212] ..................................................
[100/212] ..................................................
[150/212] ..................................................
[200/212] ............
[22]:
pkey_grondwatermonster | grondwatermonsternummer | pkey_grondwaterlocatie | gw_id | pkey_filter | filternummer | x | y | start_grondwaterlocatie_mtaw | gemeente | datum_monstername | parametergroep | parameter | detectie | waarde | eenheid | veld_labo | |
---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
0 | https://www.dov.vlaanderen.be/data/watermonste... | 1-0171/M2009 | https://www.dov.vlaanderen.be/data/put/2017-00... | 1-0171 | https://www.dov.vlaanderen.be/data/filter/1975... | 1 | 159591.0 | 229510.0 | 23.0 | Kalmthout | 2009-11-24 | Fysico-chemische parameters | O2 | NaN | 1.34 | mg/l | VELD |
1 | https://www.dov.vlaanderen.be/data/watermonste... | 1-0171/M2009 | https://www.dov.vlaanderen.be/data/put/2017-00... | 1-0171 | https://www.dov.vlaanderen.be/data/filter/1975... | 1 | 159591.0 | 229510.0 | 23.0 | Kalmthout | 2009-11-24 | Kationen | NH4 | NaN | 0.09 | mg/l | LABO |
2 | https://www.dov.vlaanderen.be/data/watermonste... | 1-0171/M2009 | https://www.dov.vlaanderen.be/data/put/2017-00... | 1-0171 | https://www.dov.vlaanderen.be/data/filter/1975... | 1 | 159591.0 | 229510.0 | 23.0 | Kalmthout | 2009-11-24 | Zware metalen | Cu | < | 5.00 | µg/l | LABO |
3 | https://www.dov.vlaanderen.be/data/watermonste... | 1-0171/M2009 | https://www.dov.vlaanderen.be/data/put/2017-00... | 1-0171 | https://www.dov.vlaanderen.be/data/filter/1975... | 1 | 159591.0 | 229510.0 | 23.0 | Kalmthout | 2009-11-24 | Anionen | HCO3 | NaN | 18.29 | mg/l | LABO |
4 | https://www.dov.vlaanderen.be/data/watermonste... | 1-0171/M2009 | https://www.dov.vlaanderen.be/data/put/2017-00... | 1-0171 | https://www.dov.vlaanderen.be/data/filter/1975... | 1 | 159591.0 | 229510.0 | 23.0 | Kalmthout | 2009-11-24 | Anionen | CO3 | < | 1.00 | mg/l | LABO |
We will filter out some parameters, and show trends per location.
[23]:
parameter = 'NH4'
trends_sel = monsters[(monsters.parameter==parameter) & (monsters.veld_labo=='LABO')]
trends_sel = trends_sel.set_index('datum_monstername')
trends_sel['label'] = trends_sel['gw_id'] + ' F' + trends_sel['filternummer']
# By pivoting, we get each location in a different column
trends_sel_pivot = trends_sel.pivot_table(columns='label', values='waarde', index='datum_monstername')
trends_sel_pivot.index = pd.to_datetime(trends_sel_pivot.index)
# resample to yearly values and plot data
ax = trends_sel_pivot.resample('A').median().plot.line(style='.-', figsize=(12, 5))
ax.legend(loc='center left', bbox_to_anchor=(1, 0.5))
ax.set_title(f'Long term evolution of {parameter} in {gemeente}');
ax.set_xlabel('year');
ax.set_ylabel('concentration (mg/l)');
