-
Notifications
You must be signed in to change notification settings - Fork 9
Timeseries plot style #465
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
base: main
Are you sure you want to change the base?
Changes from all commits
27ac391
c972683
3619190
72d3210
dfef139
a68fcfd
320563d
d55b4c7
d2d57e3
4446709
3a1fcba
0f57302
1a70efb
13a7163
3f941aa
f4d22ff
5cf2d03
9337b8e
fb44f8a
6b4476c
5c0a029
9b69219
33f631a
dc858ea
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -31,6 +31,17 @@ | |
| from ..settings import options | ||
|
|
||
|
|
||
| def _check_arg_length_match_nmodels(arg, n_mod): | ||
| if isinstance(arg, str): | ||
| # If arg is str, convert to list (for looping) | ||
| arg = [arg] | ||
| if arg is not None and len(arg) < n_mod: | ||
| raise ValueError( | ||
| f"Number of elements in {arg} does not match the number of models in the comparer." | ||
| ) | ||
| return arg | ||
|
|
||
|
|
||
| class ComparerPlotter: | ||
| """Plotter class for Comparer | ||
|
|
||
|
|
@@ -62,6 +73,8 @@ def timeseries( | |
| ax=None, | ||
| figsize: Tuple[float, float] | None = None, | ||
| backend: str = "matplotlib", | ||
| style: list[str] | str | None = None, | ||
| color: list[str] | tuple | str | None = None, | ||
| **kwargs, | ||
| ): | ||
| """Timeseries plot showing compared data: observation vs modelled | ||
|
|
@@ -79,32 +92,62 @@ def timeseries( | |
| backend : str, optional | ||
| use "plotly" (interactive) or "matplotlib" backend, | ||
| by default "matplotlib" | ||
| style: list of str, optional | ||
| Only for matplotlib backend. Containing line styles of the model results. Cannot be passed together with color input. | ||
| by default None | ||
| color: list of str, optional | ||
| Only for matplotlib backend. containing colors of the model results. | ||
| If len(colors) == num_models + 1, the first color will be used for the observations. | ||
| Cannot be passed together with style input. | ||
| by default None | ||
| **kwargs | ||
| other keyword arguments to fig.update_layout (plotly backend) | ||
|
|
||
| Returns | ||
| ------- | ||
| matplotlib.axes.Axes or plotly.graph_objects.Figure | ||
| """ | ||
|
|
||
| from ._comparison import MOD_COLORS | ||
|
|
||
| cmp = self.comparer | ||
|
|
||
| if title is None: | ||
| title = cmp.name | ||
|
|
||
| if color is not None and style is not None: | ||
| raise ValueError( | ||
| "It is not possible to pass both the color argument and the style argument. Choose one." | ||
| ) | ||
|
|
||
| # Color for observations: | ||
| obs_color = cmp.data[cmp._obs_name].attrs["color"] | ||
|
|
||
| color = _check_arg_length_match_nmodels(color, cmp.n_models) | ||
| style = _check_arg_length_match_nmodels(style, cmp.n_models) | ||
|
|
||
| if color is not None and len(color) > cmp.n_models: | ||
| # If more than n_models colors is given, the first color is used for the observations | ||
| obs_color = color[0] | ||
| color = color[1:] | ||
|
|
||
| if backend == "matplotlib": | ||
| fig, ax = _get_fig_ax(ax, figsize) | ||
| for j in range(cmp.n_models): | ||
| key = cmp.mod_names[j] | ||
| mod = cmp.raw_mod_data[key]._values_as_series | ||
| mod.plot(ax=ax, color=MOD_COLORS[j]) | ||
| if style is not None: | ||
| mod.plot(ax=ax, style=style[j]) | ||
FrejaTerpPetersen marked this conversation as resolved.
Show resolved
Hide resolved
|
||
| else: | ||
| if color is None: | ||
| color = MOD_COLORS | ||
| mod.plot(ax=ax, color=color[j]) | ||
|
|
||
| ax.scatter( | ||
| cmp.time, | ||
| cmp.data[cmp._obs_name].values, | ||
| marker=".", | ||
|
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. style does not affect the observations, is this the intended behaviour?
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Yes, observations can't have their style changed now. THis is a design choice, I guess? We could allow the user to input style for obs? Might lead to confusion, however, since I guess the user is pretty happy with a dot for the obs
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I see the color can be changed. But not the marker. |
||
| color=cmp.data[cmp._obs_name].attrs["color"], | ||
| color=obs_color, | ||
| ) | ||
| ax.set_ylabel(cmp._unit_text) | ||
| ax.legend([*cmp.mod_names, cmp._obs_name]) | ||
|
|
@@ -117,6 +160,15 @@ def timeseries( | |
| elif backend == "plotly": # pragma: no cover | ||
| import plotly.graph_objects as go # type: ignore | ||
|
|
||
| if style is not None: | ||
| raise NotImplementedError( | ||
| "style argument is not supported for plotly backend" | ||
| ) | ||
| if color is not None: | ||
| raise NotImplementedError( | ||
| "color argument not supported for plotly backend" | ||
| ) | ||
|
|
||
| mod_scatter_list = [] | ||
| for j in range(cmp.n_models): | ||
| key = cmp.mod_names[j] | ||
|
|
||
Large diffs are not rendered by default.
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.
This doesn't account for the case where the user passes more arguments than n_mod. This should not be silently ignored.