From 64c5b9d7f83410d105d4f65696a72c8ec28bfb72 Mon Sep 17 00:00:00 2001 From: aloctavodia Date: Thu, 24 Dec 2020 12:57:43 -0300 Subject: [PATCH 1/4] remove hard limits, show hlines only when show_bins is True --- arviz/plots/backends/bokeh/khatplot.py | 28 ++++++++++----------- arviz/plots/backends/matplotlib/khatplot.py | 10 +++----- arviz/plots/khatplot.py | 18 ++++++++++--- 3 files changed, 32 insertions(+), 24 deletions(-) diff --git a/arviz/plots/backends/bokeh/khatplot.py b/arviz/plots/backends/bokeh/khatplot.py index 64e5e976da..a5e1c79a78 100644 --- a/arviz/plots/backends/bokeh/khatplot.py +++ b/arviz/plots/backends/bokeh/khatplot.py @@ -21,7 +21,7 @@ def plot_khat( xdata, khats, kwargs, - annotate, + threshold, coord_labels, show_bins, hlines_kwargs, # pylint: disable=unused-argument @@ -103,22 +103,11 @@ def plot_khat( fill_alpha=alphas, ) - if annotate: - idxs = xdata[khats > 1] + if threshold is not None: + idxs = xdata[khats > threshold] for idx in idxs: ax.text(x=[idx], y=[khats[idx]], text=[coord_labels[idx]]) - for hline in [0, 0.5, 0.7, 1]: - _hline = Span( - location=hline, - dimension="width", - line_color="grey", - line_width=line_width, - line_dash="dashed", - ) - - ax.renderers.append(_hline) - ymin = min(khats) ymax = max(khats) xmax = len(khats) @@ -134,6 +123,17 @@ def plot_khat( text=[bin_format.format(count, count / n_data_points * 100)], ) ax.x_range._property_values["end"] = xmax + 1 # pylint: disable=protected-access + for hline in [0, 0.5, 0.7, 1]: + _hline = Span( + location=hline, + dimension="width", + line_color="grey", + line_width=line_width, + line_dash="dashed", + ) + + ax.renderers.append(_hline) + ax.xaxis.axis_label = "Data Point" ax.yaxis.axis_label = "Shape parameter k" diff --git a/arviz/plots/backends/matplotlib/khatplot.py b/arviz/plots/backends/matplotlib/khatplot.py index 8c76a94b92..a75a84b30f 100644 --- a/arviz/plots/backends/matplotlib/khatplot.py +++ b/arviz/plots/backends/matplotlib/khatplot.py @@ -20,7 +20,7 @@ def plot_khat( xdata, khats, kwargs, - annotate, + threshold, coord_labels, show_bins, hlines_kwargs, @@ -109,8 +109,8 @@ def plot_khat( sc_plot = ax.scatter(xdata, khats, c=rgba_c, **kwargs) - if annotate: - idxs = xdata[khats > 1] + if threshold is not None: + idxs = xdata[khats > threshold] for idx in idxs: ax.text( idx, @@ -125,7 +125,6 @@ def plot_khat( if show_bins: xmax += n_data_points / 12 ylims1 = ax.get_ylim() - ax.hlines([0, 0.5, 0.7, 1], xmin=xmin, xmax=xmax, linewidth=linewidth, **hlines_kwargs) ylims2 = ax.get_ylim() ymin = min(ylims1[0], ylims2[0]) ymax = min(ylims1[1], ylims2[1]) @@ -141,8 +140,7 @@ def plot_khat( horizontalalignment="center", verticalalignment="center", ) - ax.set_ylim(ymin, ymax) - ax.set_xlim(xmin, xmax) + ax.hlines([0, 0.5, 0.7, 1], xmin=xmin, xmax=xmax, linewidth=linewidth, **hlines_kwargs) ax.set_xlabel("Data Point", fontsize=ax_labelsize) ax.set_ylabel(r"Shape parameter k", fontsize=ax_labelsize) diff --git a/arviz/plots/khatplot.py b/arviz/plots/khatplot.py index e52f7843cf..d2ab014a8f 100644 --- a/arviz/plots/khatplot.py +++ b/arviz/plots/khatplot.py @@ -1,4 +1,6 @@ """Pareto tail indices plot.""" +import logging + import numpy as np from xarray import DataArray @@ -7,6 +9,8 @@ from ..utils import get_coords from .plot_utils import format_coords_as_labels, get_plotting_function +_log = logging.getLogger(__name__) + def plot_khat( khats, @@ -15,6 +19,7 @@ def plot_khat( show_bins=False, bin_format="{1:.1f}%", annotate=False, + threshold=None, hover_label=False, hover_format="{1}", figsize=None, @@ -46,8 +51,9 @@ def plot_khat( Show the number of khats which fall in each bin. bin_format : str, optional The string is used as formatting guide calling ``bin_format.format(count, pct)``. - annotate : bool, optional - Show the labels of k values larger than 1. + threshold : float, optional + Show the labels of k values larger than threshold. Defaults to `None`, + no observations will be highlighted. hover_label : bool, optional Show the datapoint label when hovering over it with the mouse. Requires an interactive backend. @@ -103,7 +109,7 @@ def plot_khat( >>> centered_eight = az.load_arviz_data("centered_eight") >>> khats = az.loo(centered_eight, pointwise=True).pareto_k - >>> az.plot_khat(khats, xlabels=True, annotate=True) + >>> az.plot_khat(khats, xlabels=True, threshold=1) Use custom color scheme @@ -117,6 +123,10 @@ def plot_khat( >>> az.plot_khat(loo_radon, color=colors) """ + if annotate: + _log.warn("annotate will be deprecated, please use threshold instead") + threshold = annotate + if coords is None: coords = {} @@ -152,7 +162,7 @@ def plot_khat( xdata=xdata, khats=khats, kwargs=kwargs, - annotate=annotate, + threshold=threshold, coord_labels=coord_labels, show_bins=show_bins, hlines_kwargs=hlines_kwargs, From c6ec65ab3ede0915a84f8af8dadcbd76a1e94761 Mon Sep 17 00:00:00 2001 From: aloctavodia Date: Thu, 24 Dec 2020 13:00:55 -0300 Subject: [PATCH 2/4] remove hard limits, show hlines only when show_bins is True --- arviz/plots/backends/bokeh/khatplot.py | 7 ------- 1 file changed, 7 deletions(-) diff --git a/arviz/plots/backends/bokeh/khatplot.py b/arviz/plots/backends/bokeh/khatplot.py index a5e1c79a78..052ce71cf1 100644 --- a/arviz/plots/backends/bokeh/khatplot.py +++ b/arviz/plots/backends/bokeh/khatplot.py @@ -137,13 +137,6 @@ def plot_khat( ax.xaxis.axis_label = "Data Point" ax.yaxis.axis_label = "Shape parameter k" - if ymin > 0: - ax.y_range._property_values["start"] = -0.02 # pylint: disable=protected-access - if ymax < 1: - ax.y_range._property_values["end"] = 1.02 # pylint: disable=protected-access - elif ymax > 1 & annotate: - ax.y_range._property_values["end"] = 1.1 * ymax # pylint: disable=protected-access - show_layout(ax, show) return ax From b7ba0c130567cecf751f4c3f760b4d6f5c4bff87 Mon Sep 17 00:00:00 2001 From: aloctavodia Date: Sat, 26 Dec 2020 15:06:17 -0300 Subject: [PATCH 3/4] update chagelog, revert most changes in bokeh --- CHANGELOG.md | 2 ++ arviz/plots/backends/bokeh/khatplot.py | 35 ++++++++++++++------- arviz/plots/backends/matplotlib/khatplot.py | 9 +++++- arviz/plots/khatplot.py | 8 +++-- 4 files changed, 40 insertions(+), 14 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 9ccd06693f..7b713ed92c 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -32,7 +32,9 @@ * Switch to `compact=True` by default in our plots ([1468](https://github.com/arviz-devs/arviz/issues/1468)) * `plot_elpd`, avoid modifying the input dict ([1477](https://github.com/arviz-devs/arviz/issues/1477)) + ### Deprecation +* `plot_khat` deprecate `annotate` argument in favor of `threshold`. The new argument accepts floats ([1478](https://github.com/arviz-devs/arviz/issues/1478)) ### Documentation * Reorganize documentation and change sphinx theme ([1406](https://github.com/arviz-devs/arviz/pull/1406)) diff --git a/arviz/plots/backends/bokeh/khatplot.py b/arviz/plots/backends/bokeh/khatplot.py index 052ce71cf1..e6421387fa 100644 --- a/arviz/plots/backends/bokeh/khatplot.py +++ b/arviz/plots/backends/bokeh/khatplot.py @@ -23,8 +23,9 @@ def plot_khat( kwargs, threshold, coord_labels, + show_hlines, show_bins, - hlines_kwargs, # pylint: disable=unused-argument + hlines_kwargs, xlabels, # pylint: disable=unused-argument legend, # pylint: disable=unused-argument color, @@ -49,6 +50,10 @@ def plot_khat( (figsize, *_, line_width, _) = _scale_fig_size(figsize, textsize) + if hlines_kwargs is None: + hlines_kwargs = {} + hlines_kwargs.setdefault("hlines", [0, 0.5, 0.7, 1]) + cmap = None if isinstance(color, str): if color in dims: @@ -108,6 +113,17 @@ def plot_khat( for idx in idxs: ax.text(x=[idx], y=[khats[idx]], text=[coord_labels[idx]]) + if show_hlines: + for hline in hlines_kwargs.pop("hlines"): + _hline = Span( + location=hline, + dimension="width", + line_color="grey", + line_width=line_width, + line_dash="dashed", + ) + ax.renderers.append(_hline) + ymin = min(khats) ymax = max(khats) xmax = len(khats) @@ -123,20 +139,17 @@ def plot_khat( text=[bin_format.format(count, count / n_data_points * 100)], ) ax.x_range._property_values["end"] = xmax + 1 # pylint: disable=protected-access - for hline in [0, 0.5, 0.7, 1]: - _hline = Span( - location=hline, - dimension="width", - line_color="grey", - line_width=line_width, - line_dash="dashed", - ) - - ax.renderers.append(_hline) ax.xaxis.axis_label = "Data Point" ax.yaxis.axis_label = "Shape parameter k" + if ymin > 0: + ax.y_range._property_values["start"] = -0.02 # pylint: disable=protected-access + if ymax < 1: + ax.y_range._property_values["end"] = 1.02 # pylint: disable=protected-access + elif ymax > 1 & threshold: + ax.y_range._property_values["end"] = 1.1 * ymax # pylint: disable=protected-access + show_layout(ax, show) return ax diff --git a/arviz/plots/backends/matplotlib/khatplot.py b/arviz/plots/backends/matplotlib/khatplot.py index a75a84b30f..a19cceef21 100644 --- a/arviz/plots/backends/matplotlib/khatplot.py +++ b/arviz/plots/backends/matplotlib/khatplot.py @@ -22,6 +22,7 @@ def plot_khat( kwargs, threshold, coord_labels, + show_hlines, show_bins, hlines_kwargs, xlabels, @@ -61,6 +62,7 @@ def plot_khat( backend_kwargs["squeeze"] = True hlines_kwargs = matplotlib_kwarg_dealiaser(hlines_kwargs, "hlines") + hlines_kwargs.setdefault("hlines", [0, 0.5, 0.7, 1]) hlines_kwargs.setdefault("linestyle", [":", "-.", "--", "-"]) hlines_kwargs.setdefault("alpha", 0.7) hlines_kwargs.setdefault("zorder", -1) @@ -128,6 +130,12 @@ def plot_khat( ylims2 = ax.get_ylim() ymin = min(ylims1[0], ylims2[0]) ymax = min(ylims1[1], ylims2[1]) + + if show_hlines: + ax.hlines( + hlines_kwargs.pop("hlines"), xmin=xmin, xmax=xmax, linewidth=linewidth, **hlines_kwargs + ) + if show_bins: bin_edges = np.array([ymin, 0.5, 0.7, 1, ymax]) bin_edges = bin_edges[(bin_edges >= ymin) & (bin_edges <= ymax)] @@ -140,7 +148,6 @@ def plot_khat( horizontalalignment="center", verticalalignment="center", ) - ax.hlines([0, 0.5, 0.7, 1], xmin=xmin, xmax=xmax, linewidth=linewidth, **hlines_kwargs) ax.set_xlabel("Data Point", fontsize=ax_labelsize) ax.set_ylabel(r"Shape parameter k", fontsize=ax_labelsize) diff --git a/arviz/plots/khatplot.py b/arviz/plots/khatplot.py index d2ab014a8f..3a451c7e61 100644 --- a/arviz/plots/khatplot.py +++ b/arviz/plots/khatplot.py @@ -16,6 +16,7 @@ def plot_khat( khats, color="C0", xlabels=False, + show_hlines=False, show_bins=False, bin_format="{1:.1f}%", annotate=False, @@ -47,8 +48,10 @@ def plot_khat( otherwise, it will be interpreted as a list of the dims to be used for the color code xlabels : bool, optional Use coords as xticklabels + show_hlines : bool, optional + Show the horizontal lines, by default at the values [0, 0.5, 0.7, 1]. show_bins : bool, optional - Show the number of khats which fall in each bin. + Show the percentage of khats falling in each bin, as delimited by hlines. bin_format : str, optional The string is used as formatting guide calling ``bin_format.format(count, pct)``. threshold : float, optional @@ -124,7 +127,7 @@ def plot_khat( """ if annotate: - _log.warn("annotate will be deprecated, please use threshold instead") + _log.warning("annotate will be deprecated, please use threshold instead") threshold = annotate if coords is None: @@ -164,6 +167,7 @@ def plot_khat( kwargs=kwargs, threshold=threshold, coord_labels=coord_labels, + show_hlines=show_hlines, show_bins=show_bins, hlines_kwargs=hlines_kwargs, xlabels=xlabels, From 32d87684f6bd8575d875f19f0d9c873ce0836687 Mon Sep 17 00:00:00 2001 From: aloctavodia Date: Sun, 27 Dec 2020 18:29:39 -0300 Subject: [PATCH 4/4] update tests --- arviz/tests/base_tests/test_plots_bokeh.py | 18 ++++++++++++++---- .../tests/base_tests/test_plots_matplotlib.py | 18 ++++++++++++++---- 2 files changed, 28 insertions(+), 8 deletions(-) diff --git a/arviz/tests/base_tests/test_plots_bokeh.py b/arviz/tests/base_tests/test_plots_bokeh.py index b99698e3af..23eccc003d 100644 --- a/arviz/tests/base_tests/test_plots_bokeh.py +++ b/arviz/tests/base_tests/test_plots_bokeh.py @@ -601,7 +601,12 @@ def test_plot_joint_bad(models): {"color": "obs_dim", "legend": True, "hover_label": True}, {"color": "blue", "coords": {"obs_dim": slice(2, 4)}}, {"color": np.random.uniform(size=8), "show_bins": True}, - {"color": np.random.uniform(size=(8, 3)), "show_bins": True, "annotate": True}, + { + "color": np.random.uniform(size=(8, 3)), + "show_bins": True, + "show_hlines": True, + "threshold": 1, + }, ], ) @pytest.mark.parametrize("input_type", ["elpd_data", "data_array", "array"]) @@ -628,7 +633,12 @@ def test_plot_khat(models, input_type, kwargs): {"color": "dim2", "legend": True, "hover_label": True}, {"color": "blue", "coords": {"dim2": slice(2, 4)}}, {"color": np.random.uniform(size=35), "show_bins": True}, - {"color": np.random.uniform(size=(35, 3)), "show_bins": True, "annotate": True}, + { + "color": np.random.uniform(size=(35, 3)), + "show_bins": True, + "show_hlines": True, + "threshold": 1, + }, ], ) @pytest.mark.parametrize("input_type", ["elpd_data", "data_array", "array"]) @@ -650,9 +660,9 @@ def test_plot_khat_multidim(multidim_models, input_type, kwargs): assert axes -def test_plot_khat_annotate(): +def test_plot_khat_threshold(): khats = np.array([0, 0, 0.6, 0.6, 0.8, 0.9, 0.9, 2, 3, 4, 1.5]) - axes = plot_khat(khats, annotate=True, backend="bokeh", show=False) + axes = plot_khat(khats, threshold=1, backend="bokeh", show=False) assert axes diff --git a/arviz/tests/base_tests/test_plots_matplotlib.py b/arviz/tests/base_tests/test_plots_matplotlib.py index 0ff4e38ded..4c3ee5cef5 100644 --- a/arviz/tests/base_tests/test_plots_matplotlib.py +++ b/arviz/tests/base_tests/test_plots_matplotlib.py @@ -1138,7 +1138,12 @@ def test_plot_elpd_one_model(models): {"color": "obs_dim", "legend": True, "hover_label": True}, {"color": "blue", "coords": {"obs_dim": slice(2, 4)}}, {"color": np.random.uniform(size=8), "show_bins": True}, - {"color": np.random.uniform(size=(8, 3)), "show_bins": True, "annotate": True}, + { + "color": np.random.uniform(size=(8, 3)), + "show_bins": True, + "show_hlines": True, + "threshold": 1, + }, ], ) @pytest.mark.parametrize("input_type", ["elpd_data", "data_array", "array"]) @@ -1165,7 +1170,12 @@ def test_plot_khat(models, input_type, kwargs): {"color": "dim2", "legend": True, "hover_label": True}, {"color": "blue", "coords": {"dim2": slice(2, 4)}}, {"color": np.random.uniform(size=35), "show_bins": True}, - {"color": np.random.uniform(size=(35, 3)), "show_bins": True, "annotate": True}, + { + "color": np.random.uniform(size=(35, 3)), + "show_bins": True, + "show_hlines": True, + "threshold": 1, + }, ], ) @pytest.mark.parametrize("input_type", ["elpd_data", "data_array", "array"]) @@ -1187,9 +1197,9 @@ def test_plot_khat_multidim(multidim_models, input_type, kwargs): assert axes -def test_plot_khat_annotate(): +def test_plot_khat_threshold(): khats = np.array([0, 0, 0.6, 0.6, 0.8, 0.9, 0.9, 2, 3, 4, 1.5]) - axes = plot_khat(khats, annotate=True) + axes = plot_khat(khats, threshold=1) assert axes