import mikeio1d
xns = mikeio1d.open("../tests/testdata/mikep_cs_demo.xns11")
xns
<mikeio1d.Xns11 (103)>
# How many cross sections in the file?
len(xns)
103
# You can index specific cross sections using their location id, chainage, and topo id.
# For example, to access the cross section at location 'basin_left1', chainage '122.042', and topo id '1':
xns["basin_left1", "122.042", "1"]
<CrossSection: basin_left1, 122.042, 1>
# Alternatively, you can use 'sel()' method to be more explicit (however without autocompletion):
xns.sel(location_id="basin_left1", chainage="122.042", topo_id="1")
<CrossSection: basin_left1, 122.042, 1>
# Use ':' or '...' as a wildcard to get a list of CrossSection objects matching the specified criteria.
xns["basin_left1", :, "1"]
[<CrossSection: basin_left1, 2.004, 1>, <CrossSection: basin_left1, 33.774, 1>, <CrossSection: basin_left1, 80.945, 1>, <CrossSection: basin_left1, 122.042, 1>, <CrossSection: basin_left1, 166.107, 1>, <CrossSection: basin_left1, 184.886, 1>, <CrossSection: basin_left1, 210.212, 1>, <CrossSection: basin_left1, 264.614, 1>, <CrossSection: basin_left1, 284.638, 1>, <CrossSection: basin_left1, 341.152, 1>, <CrossSection: basin_left1, 413.617, 1>, <CrossSection: basin_left1, 481.451, 1>]
# You can also provide fewer arguments and the remaining ones will automatically use '...'.
# For example, xns['basin_left1', ..., ...] can be more concisely expressed as:
xns["basin_left1"]
[<CrossSection: basin_left1, 2.004, 1>, <CrossSection: basin_left1, 33.774, 1>, <CrossSection: basin_left1, 80.945, 1>, <CrossSection: basin_left1, 122.042, 1>, <CrossSection: basin_left1, 166.107, 1>, <CrossSection: basin_left1, 184.886, 1>, <CrossSection: basin_left1, 210.212, 1>, <CrossSection: basin_left1, 264.614, 1>, <CrossSection: basin_left1, 284.638, 1>, <CrossSection: basin_left1, 341.152, 1>, <CrossSection: basin_left1, 413.617, 1>, <CrossSection: basin_left1, 481.451, 1>]
# Or with the 'sel()' method:
xns.sel(location_id="basin_left1")
[<CrossSection: basin_left1, 2.004, 1>, <CrossSection: basin_left1, 33.774, 1>, <CrossSection: basin_left1, 80.945, 1>, <CrossSection: basin_left1, 122.042, 1>, <CrossSection: basin_left1, 166.107, 1>, <CrossSection: basin_left1, 184.886, 1>, <CrossSection: basin_left1, 210.212, 1>, <CrossSection: basin_left1, 264.614, 1>, <CrossSection: basin_left1, 284.638, 1>, <CrossSection: basin_left1, 341.152, 1>, <CrossSection: basin_left1, 413.617, 1>, <CrossSection: basin_left1, 481.451, 1>]
# Get a nice overview of the collection as a pandas DataFrame.
xns.to_dataframe()
cross_section | |||
---|---|---|---|
location_id | chainage | topo_id | |
basin_left1 | 2.004 | 1 | <CrossSection: basin_left1, 2.004, 1> |
33.774 | 1 | <CrossSection: basin_left1, 33.774, 1> | |
80.945 | 1 | <CrossSection: basin_left1, 80.945, 1> | |
122.042 | 1 | <CrossSection: basin_left1, 122.042, 1> | |
166.107 | 1 | <CrossSection: basin_left1, 166.107, 1> | |
... | ... | ... | ... |
tributary | 250.000 | tributary | <CrossSection: tributary, 250.000, tributary> |
300.000 | tributary | <CrossSection: tributary, 300.000, tributary> | |
400.000 | tributary | <CrossSection: tributary, 400.000, tributary> | |
450.000 | tributary | <CrossSection: tributary, 450.000, tributary> | |
500.000 | tributary | <CrossSection: tributary, 500.000, tributary> |
103 rows × 1 columns
# You can access some basic properties of the collection:
print(xns.location_ids)
print(xns.chainages)
print(xns.topo_ids)
{'basin_left1', 'link_basin_left', 'basin_left2', 'tributary', 'river', 'basin_right', 'link_basin_right'} {'400.000', '281.473', '520.410', '53200.000', '70.870', '53126.750', '53900.000', '29.194', '46.000', '563.294', '481.451', '53745.338', '436.489', '54350.000', '450.000', '54850.000', '54000.000', '54812.900', '403.762', '210.212', '130.000', '166.107', '54900.000', '64.000', '53150.000', '54100.000', '264.614', '182.271', '80.945', '300.000', '200.000', '53798.128', '54800.000', '238.800', '94.137', '53550.000', '54550.000', '53713.410', '30.000', '434.188', '53350.000', '54999.995', '50.000', '54500.000', '53840.195', '53876.974', '53589.588', '662.699', '0.000', '54750.000', '53950.000', '54950.000', '122.513', '33.774', '53450.000', '341.152', '712.468', '2.004', '341.557', '122.042', '159.062', '54400.000', '53763.578', '53128.000', '54150.000', '284.638', '53250.000', '100.000', '53300.001', '55050.000', '54715.000', '343.386', '53631.749', '54600.001', '54200.000', '53100.000', '54450.000', '54299.996', '41.930', '69.014', '250.000', '567.166', '54050.000', '90.000', '150.000', '80.400', '53400.000', '500.000', '53500.000', '54250.000', '18.000', '53693.640', '54650.000', '28.000', '413.617', '55100.000', '184.886', '636.389', '398.991', '214.431', '120.000'} {'1', 'tributary', 'river'}
# Access the raw data of a cross section using the 'raw' attribute, which returns a Pandas DataFrame.
df = xns["basin_left1", "481.451", "1"].raw
df.head()
markers | marker_labels | x | z | resistance | |
---|---|---|---|---|---|
0 | 1 | Left Levee Bank (1) | 0.000 | 60.049 | 25.0 |
1 | 0.999 | 59.997 | 25.0 | ||
2 | 1.998 | 59.957 | 25.0 | ||
3 | 2.997 | 59.918 | 25.0 | ||
4 | 3.996 | 59.862 | 25.0 |
# Plot the cross section.
ax = xns["basin_left1", "122.042", "1"].plot()
# Plot another cross section on the same axis.
ax = xns["basin_left1", "166.107", "1"].plot(ax=ax, linestyle="--")
ax.figure
# Turn off marker labels if it gets too crowded.
ax = xns["basin_left1", "166.107", "1"].plot(with_marker_labels=False)
# Or turn off markers completely.
ax = xns["basin_left1", "166.107", "1"].plot(with_markers=False)
# You can create a new Xns11 object from a subset of the original collection.
from mikeio1d import Xns11
new_xns11 = Xns11(xns.sel(location_id="basin_left1"))
new_xns11
<mikeio1d.Xns11 (12)>
# Plot all cross sections part of the new collection.
ax = new_xns11.plot(with_marker_labels=False)
# You can convert xsections into a GeoDataframe. Note that this requires installing GeoPandas seperately.
gdf = xns.to_geopandas()
gdf.plot()
<Axes: >
# You can use convert any subset to a GeoDataFrame.
subset = Xns11(xns.sel(location_id="basin_left1"))
subset.to_geopandas().plot()
<Axes: >
# This xns11 file has three topo ids, let's get an overview of where they are located.
gdf = xns.to_geopandas()
gdf.plot(column="topo_id", legend=True, legend_kwds={"title": "Topo"})
<Axes: >
# You can check for overlapping cross sections by seeing if there's duplicate geometries.
# Here there's no duplicates, however, we notice a number of cross sections have no coordinates.
# This can be the case where cross section coordinates are not defined in the xns11 file. For example,
# sometimes coordinates are excluded, then MIKE+ will estimate the coordinates based on the river geometry,
# cross section chainage, and the river's centerline.
gdf[gdf.geometry.duplicated()]
location_id | chainage | topo_id | geometry | |
---|---|---|---|---|
37 | link_basin_left | 64.000 | 1 | LINESTRING EMPTY |
38 | link_basin_right | 0.000 | 1 | LINESTRING EMPTY |
39 | link_basin_right | 18.000 | 1 | LINESTRING EMPTY |
43 | link_basin_right | 80.400 | 1 | LINESTRING EMPTY |
45 | river | 53126.750 | river | LINESTRING EMPTY |
46 | river | 53128.000 | river | LINESTRING EMPTY |
81 | river | 54715.000 | river | LINESTRING EMPTY |
83 | river | 54800.000 | river | LINESTRING EMPTY |
84 | river | 54812.900 | river | LINESTRING EMPTY |
91 | tributary | 50.000 | tributary | LINESTRING EMPTY |
92 | tributary | 90.000 | tributary | LINESTRING EMPTY |
93 | tributary | 100.000 | tributary | LINESTRING EMPTY |
94 | tributary | 120.000 | tributary | LINESTRING EMPTY |
95 | tributary | 130.000 | tributary | LINESTRING EMPTY |
96 | tributary | 150.000 | tributary | LINESTRING EMPTY |
97 | tributary | 200.000 | tributary | LINESTRING EMPTY |
98 | tributary | 250.000 | tributary | LINESTRING EMPTY |
99 | tributary | 300.000 | tributary | LINESTRING EMPTY |
100 | tributary | 400.000 | tributary | LINESTRING EMPTY |
101 | tributary | 450.000 | tributary | LINESTRING EMPTY |
102 | tributary | 500.000 | tributary | LINESTRING EMPTY |
# Plot all of the markers.
xns.to_geopandas(mode='markers').plot(legend=True)
<Axes: >
# Plot markers on top of cross sections.
gdf1 = xns.to_geopandas(mode='sections')
gdf2 = xns.to_geopandas(mode='markers')
ax = gdf1.plot(figsize=(15, 15))
gdf2.plot(ax=ax, column="marker_label", markersize=10, zorder=10, legend=True)
<Axes: >