|
1 | 1 | """Common plots.""" |
2 | 2 |
|
3 | 3 | import numpy as np |
4 | | -from scipy.stats import gaussian_kde |
5 | | -from sklearn.covariance import EmpiricalCovariance, MinCovDet |
6 | | - |
7 | 4 | from matplotlib.patches import Ellipse |
8 | 5 | from matplotlib.transforms import Affine2D |
| 6 | +from scipy.stats import gaussian_kde |
| 7 | +from sklearn.covariance import EmpiricalCovariance, MinCovDet |
9 | 8 |
|
10 | 9 | from .chart_utils import figwrapper, nospines, plotwrapper |
11 | | -from .colors import cmap_colors |
| 10 | +from .colors import cmap_colors, neutral |
12 | 11 | from .typing import Color |
13 | 12 |
|
14 | 13 | __all__ = [ |
15 | 14 | "hist", |
16 | 15 | "hist2d", |
17 | 16 | "errorplot", |
| 17 | + "violinplot", |
18 | 18 | "bar", |
19 | 19 | "lines", |
20 | 20 | "waterfall", |
|
23 | 23 | ] |
24 | 24 |
|
25 | 25 |
|
| 26 | +@plotwrapper |
| 27 | +def violinplot( |
| 28 | + data, |
| 29 | + xs, |
| 30 | + fc=neutral[3], |
| 31 | + ec=neutral[9], |
| 32 | + mc=neutral[1], |
| 33 | + showmedians=True, |
| 34 | + showmeans=False, |
| 35 | + showquartiles=True, |
| 36 | + **kwargs, |
| 37 | +): |
| 38 | + _ = kwargs.pop("fig") |
| 39 | + ax = kwargs.pop("ax") |
| 40 | + |
| 41 | + data = np.atleast_2d(data).T |
| 42 | + |
| 43 | + if isinstance(xs, float) or isinstance(xs, int): |
| 44 | + xs = [ |
| 45 | + xs, |
| 46 | + ] |
| 47 | + |
| 48 | + parts = ax.violinplot( |
| 49 | + data, positions=xs, showmeans=False, showmedians=False, showextrema=False |
| 50 | + ) |
| 51 | + |
| 52 | + for pc in parts["bodies"]: |
| 53 | + pc.set_facecolor(fc) |
| 54 | + pc.set_edgecolor(ec) |
| 55 | + pc.set_alpha(1.0) |
| 56 | + |
| 57 | + q1, medians, q3 = np.percentile(data, [25, 50, 75], axis=0) |
| 58 | + |
| 59 | + ax.vlines( |
| 60 | + xs, |
| 61 | + np.min(data, axis=0), |
| 62 | + np.max(data, axis=0), |
| 63 | + color=ec, |
| 64 | + linestyle="-", |
| 65 | + lw=1, |
| 66 | + zorder=10, |
| 67 | + label="Extrema", |
| 68 | + ) |
| 69 | + |
| 70 | + if showquartiles: |
| 71 | + ax.vlines(xs, q1, q3, color=ec, linestyle="-", lw=5, zorder=5) |
| 72 | + |
| 73 | + if showmedians: |
| 74 | + ax.scatter(xs, medians, marker="o", color=mc, s=15, zorder=20) |
| 75 | + |
| 76 | + if showmeans: |
| 77 | + ax.scatter( |
| 78 | + xs, |
| 79 | + np.mean(data, axis=0), |
| 80 | + marker="s", |
| 81 | + color=mc, |
| 82 | + s=15, |
| 83 | + zorder=20, |
| 84 | + ) |
| 85 | + |
| 86 | + |
26 | 87 | @plotwrapper |
27 | 88 | def hist(*args, **kwargs): |
28 | 89 | """Wrapper for matplotlib.hist function.""" |
@@ -81,7 +142,7 @@ def errorplot( |
81 | 142 | err_color: Color = "#cccccc", |
82 | 143 | alpha_fill=1.0, |
83 | 144 | clip_on=True, |
84 | | - **kwargs |
| 145 | + **kwargs, |
85 | 146 | ): |
86 | 147 | """Plot a line with error bars.""" |
87 | 148 | ax = kwargs["ax"] |
@@ -129,7 +190,15 @@ def errorplot( |
129 | 190 |
|
130 | 191 | @plotwrapper |
131 | 192 | def bar( |
132 | | - labels, data, color="#888888", width=0.7, offset=0.0, err=None, capsize=5, capthick=2, **kwargs |
| 193 | + labels, |
| 194 | + data, |
| 195 | + color="#888888", |
| 196 | + width=0.7, |
| 197 | + offset=0.0, |
| 198 | + err=None, |
| 199 | + capsize=5, |
| 200 | + capthick=2, |
| 201 | + **kwargs, |
133 | 202 | ): |
134 | 203 | """Bar chart. |
135 | 204 |
|
@@ -279,7 +348,7 @@ def ellipse(x, y, n_std=3.0, facecolor="none", estimator="empirical", **kwargs): |
279 | 348 | width=ell_radius_x * 2, |
280 | 349 | height=ell_radius_y * 2, |
281 | 350 | facecolor=facecolor, |
282 | | - **kwargs |
| 351 | + **kwargs, |
283 | 352 | ) |
284 | 353 |
|
285 | 354 | # Calculating the stdandard deviation of x from |
|
0 commit comments