Reading Bronhouderportaal BRO data
This notebook introduces how to use the hydropandas package to read, visualise and analyse meta data of newly installed groundwater wells. These meta data is to be submitted to Bronhouderportaal BRO afterwards.
Notebook contents
[1]:
import pandas as pd
import hydropandas as hpd
[2]:
hpd.util.get_color_logger("INFO")
[2]:
<RootLogger root (INFO)>
Read ObsCollection
An ObsCollection is created for multiple monitoring wells.
[3]:
dirname = "data/bronhouderportaal-bro"
oc = hpd.read_bronhouderportaal_bro(dirname, full_meta=True, add_to_df=True)
oc
[3]:
| screen_top | unit | tube_top | location | y | source | x | filename | tube_nr | screen_bottom | ground_level | obs | |
|---|---|---|---|---|---|---|---|---|---|---|---|---|
| name | ||||||||||||
| GROND5_B1-2#000-1 | -9.33 | m NAP | 2.16 | GROND5_B1-2#000 | 386967.299 | bronhouderportaal-bro | 56336.522 | GROND5_B1-2.xml | 1 | -10.33 | 1.67 | GroundwaterObs GROND5_B1-2#000-1 -----metadata... |
| GROND5_B1-2#000-2 | 0.17 | m NAP | 2.34 | GROND5_B1-2#000 | 386967.299 | bronhouderportaal-bro | 56336.522 | GROND5_B1-2.xml | 2 | -0.83 | 1.67 | GroundwaterObs GROND5_B1-2#000-2 -----metadata... |
| GROND5_B1-3#000-1 | -9.70 | m NAP | 1.74 | GROND5_B1-3#000 | 387156.262 | bronhouderportaal-bro | 56349.209 | GROND5_B1-3.xml | 1 | -10.70 | 1.30 | GroundwaterObs GROND5_B1-3#000-1 -----metadata... |
| GROND5_B1-3#000-2 | -0.20 | m NAP | 2.00 | GROND5_B1-3#000 | 387156.262 | bronhouderportaal-bro | 56349.209 | GROND5_B1-3.xml | 2 | -1.20 | 1.30 | GroundwaterObs GROND5_B1-3#000-2 -----metadata... |
| GROND5_B1-1#000-1 | -10.64 | m NAP | 0.86 | GROND5_B1-1#000 | 386749.698 | bronhouderportaal-bro | 56525.207 | GROND5_B1-1.xml | 1 | -11.64 | 0.36 | GroundwaterObs GROND5_B1-1#000-1 -----metadata... |
| GROND5_B1-1#000-2 | -1.14 | m NAP | 1.07 | GROND5_B1-1#000 | 386749.698 | bronhouderportaal-bro | 56525.207 | GROND5_B1-1.xml | 2 | -2.14 | 0.36 | GroundwaterObs GROND5_B1-1#000-2 -----metadata... |
Visualize
Visualize the ObsCollection.
[4]:
oc.crs = 28992
oc.plots.interactive_map(popup_width=350)
WARNING:hydropandas.extensions.plots.interactive_map:all observations in the collection are empty
INFO:hydropandas.extensions.plots.interactive_map:no iplot available for GROND5_B1-1#000-2
INFO:hydropandas.extensions.plots.interactive_map:no iplot available for GROND5_B1-2#000-2
INFO:hydropandas.extensions.plots.interactive_map:no iplot available for GROND5_B1-3#000-2
[4]:
Make this Notebook Trusted to load map: File -> Trust Notebook
[5]:
oc.plots.section_plot(plot_obs=False)
INFO:hydropandas.extensions.plots.section_plot:created sectionplot -> GROND5_B1-2#000-1
INFO:hydropandas.extensions.plots.section_plot:created sectionplot -> GROND5_B1-2#000-2
INFO:hydropandas.extensions.plots.section_plot:created sectionplot -> GROND5_B1-3#000-1
INFO:hydropandas.extensions.plots.section_plot:created sectionplot -> GROND5_B1-3#000-2
INFO:hydropandas.extensions.plots.section_plot:created sectionplot -> GROND5_B1-1#000-1
INFO:hydropandas.extensions.plots.section_plot:created sectionplot -> GROND5_B1-1#000-2
[5]:
(<Figure size 1500x500 with 1 Axes>, [<Axes: ylabel='m NAP'>])
Analyse
Analyse the ObsCollection.
First step is to check which columns have unique values for all wells. E.g. the owner should be the same for all wells. That requires that we drop the obs column, beceause pd.nunique cannot deal with that specific HydroPandas column-type.
[6]:
oc_temp = oc.copy().drop(["obs"], axis=1)
oc_unique = oc_temp.iloc[0][oc_temp.columns[oc_temp.nunique() <= 1]]
oc_unique
[6]:
unit m NAP
source bronhouderportaal-bro
iplot_fname None
Name: GROND5_B1-2#000-1, dtype: object
[7]:
oc_non_unique = oc[oc.columns.drop(oc_temp.columns[oc_temp.nunique() <= 1])]
oc_non_unique
[7]:
| screen_top | tube_top | location | y | x | filename | tube_nr | screen_bottom | ground_level | obs | |
|---|---|---|---|---|---|---|---|---|---|---|
| name | ||||||||||
| GROND5_B1-2#000-1 | -9.33 | 2.16 | GROND5_B1-2#000 | 386967.299 | 56336.522 | GROND5_B1-2.xml | 1 | -10.33 | 1.67 | GroundwaterObs GROND5_B1-2#000-1 -----metadata... |
| GROND5_B1-2#000-2 | 0.17 | 2.34 | GROND5_B1-2#000 | 386967.299 | 56336.522 | GROND5_B1-2.xml | 2 | -0.83 | 1.67 | GroundwaterObs GROND5_B1-2#000-2 -----metadata... |
| GROND5_B1-3#000-1 | -9.70 | 1.74 | GROND5_B1-3#000 | 387156.262 | 56349.209 | GROND5_B1-3.xml | 1 | -10.70 | 1.30 | GroundwaterObs GROND5_B1-3#000-1 -----metadata... |
| GROND5_B1-3#000-2 | -0.20 | 2.00 | GROND5_B1-3#000 | 387156.262 | 56349.209 | GROND5_B1-3.xml | 2 | -1.20 | 1.30 | GroundwaterObs GROND5_B1-3#000-2 -----metadata... |
| GROND5_B1-1#000-1 | -10.64 | 0.86 | GROND5_B1-1#000 | 386749.698 | 56525.207 | GROND5_B1-1.xml | 1 | -11.64 | 0.36 | GroundwaterObs GROND5_B1-1#000-1 -----metadata... |
| GROND5_B1-1#000-2 | -1.14 | 1.07 | GROND5_B1-1#000 | 386749.698 | 56525.207 | GROND5_B1-1.xml | 2 | -2.14 | 0.36 | GroundwaterObs GROND5_B1-1#000-2 -----metadata... |
[8]:
# get statistics
oc_non_unique.describe()
[8]:
| screen_top | tube_top | y | x | tube_nr | screen_bottom | ground_level | |
|---|---|---|---|---|---|---|---|
| count | 6.000000 | 6.00000 | 6.000000 | 6.000000 | 6.000000 | 6.000000 | 6.000000 |
| mean | -5.140000 | 1.69500 | 386957.753000 | 56403.646000 | 1.500000 | -6.140000 | 1.110000 |
| std | 5.238309 | 0.60252 | 181.971242 | 94.331533 | 0.547723 | 5.238309 | 0.604053 |
| min | -10.640000 | 0.86000 | 386749.698000 | 56336.522000 | 1.000000 | -11.640000 | 0.360000 |
| 25% | -9.607500 | 1.23750 | 386804.098250 | 56339.693750 | 1.000000 | -10.607500 | 0.595000 |
| 50% | -5.235000 | 1.87000 | 386967.299000 | 56349.209000 | 1.500000 | -6.235000 | 1.300000 |
| 75% | -0.435000 | 2.12000 | 387109.021250 | 56481.207500 | 2.000000 | -1.435000 | 1.577500 |
| max | 0.170000 | 2.34000 | 387156.262000 | 56525.207000 | 2.000000 | -0.830000 | 1.670000 |
Check the usage of tube_nr. Has tube number one the lowest screen_bottom and lowest screen_top?
[9]:
lst_lowest_tube = []
for location in oc.location.unique():
oc_mw = oc.loc[oc.location == location]
lowest_screen_bottom_tube_nr = oc_mw.loc[
oc_mw.screen_bottom == oc_mw.screen_bottom.min(), "tube_nr"
].values[0]
lowest_screen_top_tube_nr = oc_mw.loc[
oc_mw.screen_top == oc_mw.screen_top.min(), "tube_nr"
].values[0]
lst_lowest_tube.append(
[location, lowest_screen_bottom_tube_nr, lowest_screen_top_tube_nr]
)
df_lowest_tube = pd.DataFrame(
lst_lowest_tube,
columns=[
"location",
"lowest_screen_bottom_tube_nr",
"lowest_screen_top_tube_nr",
],
).set_index("location")
df_lowest_tube
[9]:
| lowest_screen_bottom_tube_nr | lowest_screen_top_tube_nr | |
|---|---|---|
| location | ||
| GROND5_B1-2#000 | 1 | 1 |
| GROND5_B1-3#000 | 1 | 1 |
| GROND5_B1-1#000 | 1 | 1 |
Upload to Bronhouderportaal BRO
Upload the XML-files to Bronhouderportaal BRO via the website.