Skip to content

Commit

Permalink
Allow pressure_level dependent colourbars
Browse files Browse the repository at this point in the history
Only includes the colourbar definitions for temperature. More will be
added later.

Fixes #1139
  • Loading branch information
Sylviabohnenstengel authored and jfrost-mo committed Feb 14, 2025
1 parent 2528b9a commit 60e4f97
Show file tree
Hide file tree
Showing 2 changed files with 79 additions and 6 deletions.
43 changes: 43 additions & 0 deletions src/CSET/operators/_colorbar_definition.json
Original file line number Diff line number Diff line change
Expand Up @@ -633,6 +633,49 @@
"max": 1e-06,
"min": -1e-06
},
"temperature_at_pressure_levels": {
"cmap": "RdYlBu_r",
"max": 330,
"min": 200,
"pressure_levels": {
"100": {
"max": 240,
"min": 200
},
"1000": {
"max": 320,
"min": 240
},
"200": {
"max": 240,
"min": 200
},
"250": {
"max": 240,
"min": 200
},
"300": {
"max": 250,
"min": 210
},
"500": {
"max": 280,
"min": 240
},
"700": {
"max": 300,
"min": 240
},
"850": {
"max": 310,
"min": 250
},
"950": {
"max": 310,
"min": 250
}
}
},
"temperature_at_screen_level": {
"cmap": "RdYlBu_r",
"max": 323,
Expand Down
42 changes: 36 additions & 6 deletions src/CSET/operators/plot.py
Original file line number Diff line number Diff line change
Expand Up @@ -190,28 +190,58 @@ def _colorbar_map_levels(cube: iris.cube.Cube):
user_colorbar_file = get_recipe_metadata().get("style_file_path", None)
colorbar = _load_colorbar_map(user_colorbar_file)

# First try standard name, then long name, then varname.
varnames = list(filter(None, [cube.standard_name, cube.long_name, cube.var_name]))
try:
# Ensure pressure_level is a string of an integer, as used in the
# _colorbar_definition.json. We assume that pressure is a scalar
# coordinate here.
pressure_level = str(int(cube.coord("pressure").points[0]))
except iris.exceptions.CoordinateNotFoundError:
pressure_level = None

# First try standard name, then long name, then var name.
varnames = filter(None, [cube.standard_name, cube.long_name, cube.var_name])
for varname in varnames:
# Get the colormap for this variable.
try:
cmap = mpl.colormaps[colorbar[varname]["cmap"]]
if pressure_level is None:
var_colorbar = colorbar[varname]
else:
# If pressure level is specified for cube use a pressure-level
# specific colourbar, if one exists.
try:
var_colorbar = colorbar[varname]["pressure_levels"][pressure_level]
except KeyError:
logging.warning(
"%s has no colorbar definition for pressure level %s.",
varname,
pressure_level,
)
# Fallback to variable default.
var_colorbar = colorbar[varname]

# Get the colorbar levels for this variable.
try:
levels = colorbar[varname]["levels"]
levels = var_colorbar["levels"]
# Use discrete bins when levels are specified, rather than a
# smooth range.
norm = mpl.colors.BoundaryNorm(levels, ncolors=cmap.N)
logging.debug("Using levels for %s colorbar.", varname)
except KeyError:
# Get the range for this variable.
vmin, vmax = colorbar[varname]["min"], colorbar[varname]["max"]
logging.debug("From colorbar dictionary: Using min and max")
vmin, vmax = var_colorbar["min"], var_colorbar["max"]
logging.debug("Using min and max for %s colorbar.", varname)
# Calculate levels from range.
levels = np.linspace(vmin, vmax, 20)
norm = None
return cmap, levels, norm
return cmap, levels, norm
except KeyError:
logging.debug("Cube name %s has no colorbar definition.", varname)
# Retry with next name.
continue

# Default if no varnames match.
logging.warning("No colorbar definition exists for %s.", cube.name())
cmap, levels, norm = mpl.colormaps["viridis"], None, None
return cmap, levels, norm

Expand Down

0 comments on commit 60e4f97

Please sign in to comment.