inbo / niche_vlaanderen

Python package to run the NICHE Vlaanderen model
https://inbo.github.io/niche_vlaanderen/
MIT License
5 stars 0 forks source link

Improve legend for management map (and others) #308

Open johanvdw opened 1 year ago

johanvdw commented 1 year ago

Rather than showing a scalebar, if the input data contains distinct classes with a lookup table (such as management), it would be better to show these values in the legend. image

stijnvanhoey commented 3 months ago

After a check, this requires a refactoring of the vegetation, nutrient_level and acidity modules. At the moment, a niche instance can not directly access the code-tables in these submodules, which is required to convert the scale (using the mapping of the code tables). The proposal is to refactor the logic of the code-tables getting it from inpu or from stroed code table (e.g. for vegetation module) to the niche module level and let the submodule classes always instantiated with required parameters (these modules should not bother where the tables are coming from). Hence, we will:

Note this will also solve the current duplicate loading of the system tables in the different submodules.

Once the system tables are accessible in the class to the plot method, the following snippet illustrates how the discrete colormap with labels can be created (code can be integrated in the .plot method):

import numpy as np
import pandas as pd
import matplotlib as mpl

key = "acidity"  # or management, seepage,...

# custom mapping table to extract codes/labels from the system tables
mapping = {"acidity": {"code": "acidity", "labels": "zuurgraadklasse_bodem"},
           "inundation": {"code": "inundation", "labels": "description"},
           "management": {"code": "code", "labels": "management"},
           "seepage": {"code": "seepage", "labels": "description"},
           "nutrient_level": {"code": "code", "labels": "nutrient_level"},
           "seepage": {"code": "seepage", "labels": "description"},
           "soil_code": {"code": "soil_code", "labels": "description"}, # ! not consistent soil_code versus soil_codes
          }

ct_table = pd.read_csv(f"../niche_vlaanderen/system_tables/{key}.csv")  # refactor so this is extracted from niche-class
ct_table = ct_table.sort_values(by=mapping[key]["code"])

# Define bounds/norm for cmap
cmap = mpl.cm.viridis
bounds = np.concatenate([ct_table[mapping[key]["code"]].values, 
                         np.array([ct_table[mapping[key]["code"]].values.max() + 1])]) - 0.5
norm = mpl.colors.BoundaryNorm(bounds, cmap.N, extend='neither')

# create plot
fig, ax  = plt.subplots()
full.plot(key, ax=ax)

# add custom colorbar
cbar = fig.colorbar(mpl.cm.ScalarMappable(norm=norm, cmap=cmap),
                    cax=fig.axes[1], ticks=ct_table[mapping[key]["code"]].values)
cbar.set_ticklabels(ticklabels=ct_table[mapping[key]["labels"]].values)

example output: image

stijnvanhoey commented 2 weeks ago

Note, the # custom mapping table to extract codes/labels from the system tables is no longer representative as the column naming of the code tables has been updated as part of https://github.com/inbo/niche_vlaanderen/pull/376