-
Notifications
You must be signed in to change notification settings - Fork 18
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
New MaskSet.get_cmap() implementation #1019
Conversation
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
We still have the same problem that the user will need to add vmin and vmax manually. I find this, as a user, more confusing then getting vmin and vmax from the get_cmap
method. See examples below:
land_cover_mask = MaskSet(land_cover_2019.lccs_class)
cmap = land_cover_mask.get_cmap()
land_cover_2019.lccs_class.plot(cmap=cmap)
land_cover_mask = MaskSet(land_cover_2019.lccs_class)
cmap = land_cover_mask.get_cmap()
land_cover_2019.lccs_class.plot(cmap=cmap, vmin=0, vmax=220)
plt.show()
The colormap is not really nice, but this method at least buts the values on the correct position. I did something like:
def get_cmap(maskset):
vals = maskset._flag_values
extent = vals.max() - vals.min()
vals_norm = (vals - vals.min()) / extent
colors = [(0, 0, 0, 0)] + maskset._flag_colors
color_mapping = [(v, c) for v, c in zip(vals_norm, colors)]
for v, c in zip(vals, colors):
print(v, c)
return matplotlib.colors.LinearSegmentedColormap.from_list(
str(maskset._flag_var.name), color_mapping, N=len(vals)
)
land_cover_mask = MaskSet(land_cover_2019.lccs_class)
cmap = get_cmap(land_cover_mask)
land_cover_2019.lccs_class.plot(cmap=cmap, vmin=0, vmax=220)
plt.show()
This gives an aesthetically nicer colormap but distorts the actual values of course. I am indecisive whats better.
Still we should do something about vmin and vmax, I think. Otherwise a lot of users will run into problems. Would it be possible to add a plotting routine to MaskSet
?
xcube/core/maskset.py
Outdated
def _sanitize_flag_values( | ||
flag_var: xr.DataArray, | ||
flag_values: np.ndarray, | ||
) -> Optional[np.ndarray]: |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Why Optional?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Forgot to remove.
Then, xarray is not calling the color map in the right way. The new color map is a This may be most useful when indexing directly into a colormap
That's right! |
The Land Cover color mapping is not about aesthetics. The ultimate goal is to have an exact match between flag values and assigned color. It is really a pity that the provided |
Co-authored-by: Konstantin Ntokas <38956538+konstntokas@users.noreply.github.com>
Yes, return a
Yes, but let's keep it simple for time being. I will change impl. to return the pair. |
Including matplotlib.colors.BoundaryNorm the colormap looks like this. The numbers are of course confusing. We would need to create the plot and assign the ticks to the center of each discrete color and assign the tick label to either the flag value or even flag name. Code snippet:
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
See suggestions
xcube/core/maskset.py
Outdated
An suitable instance of ```matplotlib.colors.Colormap``` and | ||
the corresponding ```matplotlib.colors.BoundaryNorm``` if applicable |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
An suitable instance of ```matplotlib.colors.Colormap``` and | |
the corresponding ```matplotlib.colors.BoundaryNorm``` if applicable | |
An suitable instance of ``matplotlib.colors.Colormap`` and | |
the corresponding ``matplotlib.colors.BoundaryNorm`` if applicable |
xcube/core/maskset.py
Outdated
|
||
if flag_value_min >= 0 and flag_value_max < _UINT16_MAX: | ||
flag_colors = self._flag_colors | ||
levels = np.append(flag_values - 0.5, flag_values[-1] + 0.5) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Why 0.5 shift?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
shift is removed, see plot below.
The plot now looks like this without the shift of 0.5 as suggested by @forman: Code snippet
|
I approve & merge, broken CI has other reasons. |
Closes #1011
@konstntokas please also test with original LC data in last webinar notebook.
Checklist:
docs/source/*
CHANGES.md