Setting levels for 2D KDE contour plot returns errors for Bokeh backend
See original GitHub issueDescribe the bug
Setting the levels
parameter for either contour_kwargs
or contourf_kwargs
in plot_kde
returns errors for the Bokeh backend.
To Reproduce
import numpy as np
import arviz as az
rng = np.random.default_rng()
data = rng.multivariate_normal([2, 2], [[1, 0.4], [0.4, 0.8]], 1000000)
levels = [0, 0.01, 0.07, 0.13, 0.2]
ax = az.plot_kde(
data[:, 0],
data[:, 1],
contourf_kwargs={"levels": levels},
contour_kwargs={"levels": levels},
backend="bokeh",
)
returns the error
---------------------------------------------------------------------------
ValueError Traceback (most recent call last)
<ipython-input-7-6f97bf89ac37> in <module>
6
7 levels = [0, 0.01, 0.07, 0.13, 0.2]
----> 8 ax = az.plot_kde(
9 data[:, 0],
10 data[:, 1],
/opt/arviz/arviz/plots/kdeplot.py in plot_kde(values, values2, cumulative, rug, label, bw, adaptive, circular, quantiles, rotated, contour, hdi_probs, fill_last, figsize, textsize, plot_kwargs, fill_kwargs, rug_kwargs, contour_kwargs, contourf_kwargs, pcolormesh_kwargs, is_circular, ax, legend, backend, backend_kwargs, show, return_glyph, **kwargs)
341 # TODO: Add backend kwargs
342 plot = get_plotting_function("plot_kde", "kdeplot", backend)
--> 343 ax = plot(**kde_plot_args)
344
345 return ax
/opt/arviz/arviz/plots/backends/bokeh/kdeplot.py in plot_kde(density, lower, upper, density_q, xmin, xmax, ymin, ymax, gridsize, values, values2, rug, label, quantiles, rotated, contour, fill_last, figsize, textsize, plot_kwargs, fill_kwargs, rug_kwargs, contour_kwargs, contourf_kwargs, pcolormesh_kwargs, is_circular, ax, legend, backend_kwargs, show, return_glyph)
185 else:
186 levels_scaled_nonclip = _scale_axis(np.asarray(levels), scaled_density_args)
--> 187 levels_scaled = np.clip(levels_scaled_nonclip, 0, 1)
188
189 cmap = contourf_kwargs.pop("cmap", "viridis")
<__array_function__ internals> in clip(*args, **kwargs)
/usr/local/envs/testenv_3.8_PYSTAN_latest_PYRO_latest_EMCEE_latest_TF_latest/lib/python3.8/site-packages/numpy/core/fromnumeric.py in clip(a, a_min, a_max, out, **kwargs)
2095
2096 """
-> 2097 return _wrapfunc(a, 'clip', a_min, a_max, out=out, **kwargs)
2098
2099
/usr/local/envs/testenv_3.8_PYSTAN_latest_PYRO_latest_EMCEE_latest_TF_latest/lib/python3.8/site-packages/numpy/core/fromnumeric.py in _wrapfunc(obj, method, *args, **kwds)
53 bound = getattr(obj, method, None)
54 if bound is None:
---> 55 return _wrapit(obj, method, *args, **kwds)
56
57 try:
/usr/local/envs/testenv_3.8_PYSTAN_latest_PYRO_latest_EMCEE_latest_TF_latest/lib/python3.8/site-packages/numpy/core/fromnumeric.py in _wrapit(obj, method, *args, **kwds)
42 except AttributeError:
43 wrap = None
---> 44 result = getattr(asarray(obj), method)(*args, **kwds)
45 if wrap:
46 if not isinstance(result, mu.ndarray):
/usr/local/envs/testenv_3.8_PYSTAN_latest_PYRO_latest_EMCEE_latest_TF_latest/lib/python3.8/site-packages/numpy/core/_methods.py in _clip(a, min, max, out, casting, **kwargs)
138 um.maximum, a, min, out=out, casting=casting, **kwargs)
139 else:
--> 140 return _clip_dep_invoke_with_casting(
141 um.clip, a, min, max, out=out, casting=casting, **kwargs)
142
/usr/local/envs/testenv_3.8_PYSTAN_latest_PYRO_latest_EMCEE_latest_TF_latest/lib/python3.8/site-packages/numpy/core/_methods.py in _clip_dep_invoke_with_casting(ufunc, out, casting, *args, **kwargs)
92 # try to deal with broken casting rules
93 try:
---> 94 return ufunc(*args, out=out, **kwargs)
95 except _exceptions._UFuncOutputCastingError as e:
96 # Numpy 1.17.0, 2019-02-24
ValueError: The truth value of an array with more than one element is ambiguous. Use a.any() or a.all()
If instead levels
is set to an integer specifying the number of contours desired (e.g. levels=3
), a different error is thrown.
---------------------------------------------------------------------------
AttributeError Traceback (most recent call last)
<ipython-input-8-eec0f47bee3b> in <module>
6
7 levels = 3 #[0, 0.01, 0.07, 0.13, 0.2]
----> 8 ax = az.plot_kde(
9 data[:, 0],
10 data[:, 1],
/opt/arviz/arviz/plots/kdeplot.py in plot_kde(values, values2, cumulative, rug, label, bw, adaptive, circular, quantiles, rotated, contour, hdi_probs, fill_last, figsize, textsize, plot_kwargs, fill_kwargs, rug_kwargs, contour_kwargs, contourf_kwargs, pcolormesh_kwargs, is_circular, ax, legend, backend, backend_kwargs, show, return_glyph, **kwargs)
341 # TODO: Add backend kwargs
342 plot = get_plotting_function("plot_kde", "kdeplot", backend)
--> 343 ax = plot(**kde_plot_args)
344
345 return ax
/opt/arviz/arviz/plots/backends/bokeh/kdeplot.py in plot_kde(density, lower, upper, density_q, xmin, xmax, ymin, ymax, gridsize, values, values2, rug, label, quantiles, rotated, contour, fill_last, figsize, textsize, plot_kwargs, fill_kwargs, rug_kwargs, contour_kwargs, contourf_kwargs, pcolormesh_kwargs, is_circular, ax, legend, backend_kwargs, show, return_glyph)
207 vertices, _ = contour_generator.create_filled_contour(level, level_upper)
208 for seg in vertices:
--> 209 patch = ax.patch(*seg.T, fill_color=color, **contour_kwargs)
210 glyphs.append(patch)
211
/usr/local/envs/testenv_3.8_PYSTAN_latest_PYRO_latest_EMCEE_latest_TF_latest/lib/python3.8/site-packages/bokeh/plotting/_decorators.py in wrapped(self, *args, **kwargs)
79 for arg, param in zip(args, sigparams[1:]):
80 kwargs[param.name] = arg
---> 81 return create_renderer(glyphclass, self, **kwargs)
82
83 wrapped.__signature__ = Signature(parameters=sigparams)
/usr/local/envs/testenv_3.8_PYSTAN_latest_PYRO_latest_EMCEE_latest_TF_latest/lib/python3.8/site-packages/bokeh/plotting/_renderer.py in create_renderer(glyphclass, plot, **kwargs)
115 muted_visuals = None
116
--> 117 glyph = make_glyph(glyphclass, kwargs, glyph_visuals)
118 nonselection_glyph = make_glyph(glyphclass, kwargs, nonselection_visuals)
119 selection_glyph = make_glyph(glyphclass, kwargs, selection_visuals)
/usr/local/envs/testenv_3.8_PYSTAN_latest_PYRO_latest_EMCEE_latest_TF_latest/lib/python3.8/site-packages/bokeh/plotting/_renderer.py in make_glyph(glyphclass, kws, extra)
144 kws = kws.copy()
145 kws.update(extra)
--> 146 return glyphclass(**kws)
147
148 def pop_visuals(glyphclass, props, prefix="", defaults={}, override_defaults={}):
/usr/local/envs/testenv_3.8_PYSTAN_latest_PYRO_latest_EMCEE_latest_TF_latest/lib/python3.8/site-packages/bokeh/model.py in __init__(self, **kwargs)
234 kwargs.pop("id", None)
235
--> 236 super().__init__(**kwargs)
237 default_theme.apply_to_model(self)
238
/usr/local/envs/testenv_3.8_PYSTAN_latest_PYRO_latest_EMCEE_latest_TF_latest/lib/python3.8/site-packages/bokeh/core/has_props.py in __init__(self, **properties)
267
268 for name, value in properties.items():
--> 269 setattr(self, name, value)
270
271 self._initialized = True
/usr/local/envs/testenv_3.8_PYSTAN_latest_PYRO_latest_EMCEE_latest_TF_latest/lib/python3.8/site-packages/bokeh/core/has_props.py in __setattr__(self, name, value)
303 matches, text = props, "possible"
304
--> 305 raise AttributeError("unexpected attribute '%s' to %s, %s attributes are %s" %
306 (name, self.__class__.__name__, text, nice_join(matches)))
307
AttributeError: unexpected attribute 'levels' to Patch, possible attributes are fill_alpha, fill_color, hatch_alpha, hatch_color, hatch_extra, hatch_pattern, hatch_scale, hatch_weight, js_event_callbacks, js_property_callbacks, line_alpha, line_cap, line_color, line_dash, line_dash_offset, line_join, line_width, name, subscribed_events, syncable, tags, x or y
Expected behavior
In both cases, I’d expect plots to be produced. For comparison, here are the plots produced when backend="matplotlib"
:
for the first instance (where
levels = [0, 0.01, 0.07, 0.13, 0.2]
) and
for the second instance (where
levels = 3
)
Additional context
I used the docker development image, using the ./scripts/container.sh --lab
command and a Jupyter Notebook to execute the code. Not sure if it’s relevant but I ran the docker container on Ubuntu 20.04.2 LTS, using Firefox 87.0 to access Jupyter Lab.
Issue Analytics
- State:
- Created 2 years ago
- Comments:5 (5 by maintainers)
Ok, we just probably need to pop levels from contour_dict and use
np.asarray
Oh, sorry, I should have checked back before submitting my PR