Skip to content
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

Make plotting api more consistent #267

Merged
merged 36 commits into from
Oct 12, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
36 commits
Select commit Hold shift + click to select a range
d1bf802
Add test setup to dynamically find plotting funcs
ryan-kipawa Sep 28, 2023
2535040
Add failing tests to check if plot params exist
ryan-kipawa Sep 28, 2023
0ed3f70
Add test to check for axes return annot and doc
ryan-kipawa Sep 28, 2023
cc3d41a
Add missing docstring for taylor_diagram
ryan-kipawa Sep 28, 2023
9590f55
Update wind_rose params, annotations, docstr
ryan-kipawa Sep 28, 2023
ffd4bfb
Update temporal_coverage return annotation and doc
ryan-kipawa Sep 28, 2023
7da8adc
Update spatial_overview return annotation and doc
ryan-kipawa Sep 28, 2023
1c5fde1
Update taylor_diagram params, docstr, and ret anno
ryan-kipawa Sep 28, 2023
ab548f1
Update scatter parms, return annot, and docs
ryan-kipawa Sep 29, 2023
df2ea78
Add kde figsize, title. Update return annot to ax
ryan-kipawa Sep 29, 2023
5049841
ax cannot be passed to plotly backend
ryan-kipawa Sep 29, 2023
338aba2
Merge branch 'main' into Make-consistent-plotting-API
ryan-kipawa Oct 5, 2023
335d55c
Timeseries plot accepts / ret ax
ryan-kipawa Oct 6, 2023
541c027
Add test for plotting functions to not return none
ryan-kipawa Oct 6, 2023
a879851
Add comparer plot tests for ax, title, figsize
ryan-kipawa Oct 6, 2023
ff1b2a1
Hist accepts ax and figsize
ryan-kipawa Oct 6, 2023
327df95
KDE consistent way to get ax
ryan-kipawa Oct 6, 2023
4a2556d
qq use explicit instead of implicit
ryan-kipawa Oct 6, 2023
1a9c6f4
Add figsize to box and consistent get ax
ryan-kipawa Oct 6, 2023
ce3964e
Remove rough plot api tests from standard pytest
ryan-kipawa Oct 6, 2023
c1a6442
Scatter uses implicit methods and fix cbar alpha
ryan-kipawa Oct 6, 2023
408b00b
Taylor plot return sfigure, does not accept ax
ryan-kipawa Oct 6, 2023
98ae25d
Add figsize and ax params to residual_his
ryan-kipawa Oct 6, 2023
203bde3
FIx linting errors
ryan-kipawa Oct 6, 2023
bef1e01
Fix mypy errors
ryan-kipawa Oct 7, 2023
6b3b709
Fix title test for older matplotlib versions
ryan-kipawa Oct 8, 2023
5b2ad3e
Add tests for comparer collection
ryan-kipawa Oct 9, 2023
078a51a
Add ax param for cc plotter
ryan-kipawa Oct 9, 2023
004d7b2
Add figsize, title to kde plot on collections
ryan-kipawa Oct 9, 2023
2c9d6cc
Add ax, figsize to collection hist plot
ryan-kipawa Oct 9, 2023
99c338b
Skip collection taylor plot tests temporarily
ryan-kipawa Oct 9, 2023
63b8825
Taylor plot should return figure object
ryan-kipawa Oct 9, 2023
453b09e
Remove unused import
ryan-kipawa Oct 9, 2023
2f50ecf
Add tests for matplotlib timeseries plots
ryan-kipawa Oct 9, 2023
35b3208
Timeseries should return ax
ryan-kipawa Oct 9, 2023
97cb41e
Clean up
ryan-kipawa Oct 11, 2023
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
49 changes: 33 additions & 16 deletions modelskill/comparison/_collection_plotter.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,16 +2,12 @@
from typing import Any, List, Union, Optional, Tuple, Sequence
from matplotlib.axes import Axes # type: ignore

import matplotlib.pyplot as plt # type: ignore
import pandas as pd

from .. import metrics as mtr
from ..utils import _get_idx
from ..plotting import taylor_diagram, scatter, TaylorPoint
from ..plotting._misc import (
_xtick_directional,
_ytick_directional,
)
from ..plotting._misc import _xtick_directional, _ytick_directional, _get_fig_ax


class ComparerCollectionPlotter:
Expand Down Expand Up @@ -41,6 +37,7 @@ def scatter(
xlabel: Optional[str] = None,
ylabel: Optional[str] = None,
skill_table: Optional[Union[str, List[str], bool]] = None,
ax: Optional[Axes] = None,
**kwargs,
):
"""Scatter plot showing compared data: observation vs modelled
Expand Down Expand Up @@ -95,6 +92,8 @@ def scatter(
list of modelskill.metrics or boolean, if True then by default modelskill.options.metrics.list.
This kword adds a box at the right of the scatter plot,
by default False
ax : matplotlib axes, optional
axes to plot on, by default None
kwargs

Examples
Expand Down Expand Up @@ -167,6 +166,7 @@ def scatter(
ylabel=ylabel,
skill_df=skill_df,
units=units,
ax=ax,
**kwargs,
)

Expand All @@ -176,13 +176,17 @@ def scatter(

return ax

def kde(self, ax=None, **kwargs) -> Axes:
def kde(self, ax=None, figsize=None, title=None, **kwargs) -> Axes:
"""Plot kernel density estimate of observation and model data.

Parameters
----------
ax : Axes, optional
matplotlib axes, by default None
figsize : tuple, optional
width and height of the figure, by default None
title : str, optional
plot title, by default None
**kwargs
passed to pandas.DataFrame.plot.kde()

Expand All @@ -198,8 +202,7 @@ def kde(self, ax=None, **kwargs) -> Axes:
>>> cc.plot.kde(bw_method='silverman')

"""
if ax is None:
ax = plt.gca()
_, ax = _get_fig_ax(ax, figsize)

df = self.cc.to_dataframe()
ax = df.obs_val.plot.kde(
Expand All @@ -213,9 +216,10 @@ def kde(self, ax=None, **kwargs) -> Axes:
# TODO use unit_text from the first comparer
# TODO make sure they are conistent
# then it should be a property of the collection, not only the comparer
plt.xlabel(f"{self.cc[0].unit_text}")
ax.set_xlabel(f"{self.cc[0].unit_text}")

# TODO title?
default_title = f"KDE plot for {', '.join(cmp.name for cmp in self.cc)}"
ax.set_title(title or default_title)
ax.legend()

# remove y-axis, ticks and label
Expand All @@ -240,6 +244,8 @@ def hist(
title: Optional[str] = None,
density=True,
alpha: float = 0.5,
ax=None,
figsize: Optional[Tuple[float, float]] = None,
**kwargs,
):
"""Plot histogram of specific model and all observations.
Expand All @@ -258,6 +264,10 @@ def hist(
If True, draw and return a probability density, by default True
alpha : float, optional
alpha transparency fraction, by default 0.5
ax : matplotlib axes, optional
axes to plot on, by default None
figsize : tuple, optional
width and height of the figure, by default None
kwargs : other keyword arguments to df.hist()

Returns
Expand All @@ -276,6 +286,8 @@ def hist(
"""
from ._comparison import MOD_COLORS

_, ax = _get_fig_ax(ax, figsize)

mod_id = _get_idx(model, self.cc.mod_names)
mod_name = self.cc.mod_names[mod_id]

Expand All @@ -285,21 +297,22 @@ def hist(
df = cmp.to_dataframe()
kwargs["alpha"] = alpha
kwargs["density"] = density
ax = df.mod_val.hist(bins=bins, color=MOD_COLORS[mod_id], **kwargs)
df.mod_val.hist(bins=bins, color=MOD_COLORS[mod_id], ax=ax, **kwargs)
df.obs_val.hist(
bins=bins,
color=self.cc[0].data["Observation"].attrs["color"],
ax=ax,
**kwargs,
)

ax.legend([mod_name, "observations"])
plt.title(title)
plt.xlabel(f"{self.cc[df.observation[0]].unit_text}")
ax.set_title(title)
ax.set_xlabel(f"{self.cc[df.observation.iloc[0]].unit_text}")

if density:
plt.ylabel("density")
ax.set_ylabel("density")
else:
plt.ylabel("count")
ax.set_ylabel("count")

if self.is_directional:
_xtick_directional(ax)
Expand Down Expand Up @@ -348,6 +361,10 @@ def taylor(
title : str, optional
title of the plot, by default "Taylor diagram"

Returns
-------
matplotlib.figure.Figure

Examples
------
>>> cc.plot.taylor()
Expand Down Expand Up @@ -387,7 +404,7 @@ def taylor(
for r in df.itertuples()
]

taylor_diagram(
return taylor_diagram(
obs_std=ref_std,
points=pts,
figsize=figsize,
Expand Down
Loading