diff --git a/tests/output/oo/test_filled_with_colormap_calm_limit.png b/tests/output/oo/test_filled_with_colormap_calm_limit.png new file mode 100644 index 0000000..e052cdb Binary files /dev/null and b/tests/output/oo/test_filled_with_colormap_calm_limit.png differ diff --git a/tests/output/oo/test_filled_with_colormap_contours_calm_limit.png b/tests/output/oo/test_filled_with_colormap_contours_calm_limit.png new file mode 100644 index 0000000..b48ad07 Binary files /dev/null and b/tests/output/oo/test_filled_with_colormap_contours_calm_limit.png differ diff --git a/tests/output/oo/test_windrose_stacked_histogram_normed_calm_limit.png b/tests/output/oo/test_windrose_stacked_histogram_normed_calm_limit.png new file mode 100644 index 0000000..5a7f277 Binary files /dev/null and b/tests/output/oo/test_windrose_stacked_histogram_normed_calm_limit.png differ diff --git a/tests/output/oo/test_windrose_stacked_histogram_not_normed_binned_calm_limit.png b/tests/output/oo/test_windrose_stacked_histogram_not_normed_binned_calm_limit.png new file mode 100644 index 0000000..be8630c Binary files /dev/null and b/tests/output/oo/test_windrose_stacked_histogram_not_normed_binned_calm_limit.png differ diff --git a/tests/output/oo/test_without_filled_with_colormap_contours_calm_limit.png b/tests/output/oo/test_without_filled_with_colormap_contours_calm_limit.png new file mode 100644 index 0000000..d9b7727 Binary files /dev/null and b/tests/output/oo/test_without_filled_with_colormap_contours_calm_limit.png differ diff --git a/tests/test_windrose_np_mpl_oo.py b/tests/test_windrose_np_mpl_oo.py index 68f43bb..0c9120e 100644 --- a/tests/test_windrose_np_mpl_oo.py +++ b/tests/test_windrose_np_mpl_oo.py @@ -45,6 +45,24 @@ def test_windrose_stacked_histogram_not_normed_binned(): return ax.figure +@pytest.mark.mpl_image_compare(baseline_dir="output/oo", tolerance=6.5) +def test_windrose_stacked_histogram_not_normed_binned_calm_limit(): + # Another stacked histogram representation, not normed, with bins limits and a calm limit + ax = WindroseAxes.from_ax() + ax.box(wd, ws, bins=bins, calm_limit=0.2) + ax.set_legend() + return ax.figure + + +@pytest.mark.mpl_image_compare(baseline_dir="output/oo", tolerance=15.5) +def test_windrose_stacked_histogram_normed_calm_limit(): + # windrose like a stacked histogram with normed (displayed in percent) results and a calm limit + ax = WindroseAxes.from_ax() + ax.bar(wd, ws, normed=True, opening=0.8, edgecolor="white", calm_limit=0.2) + ax.set_legend() + return ax.figure + + @pytest.mark.mpl_image_compare(baseline_dir="output/oo") def test_filled_with_colormap(): # A windrose in filled representation, with a controlled colormap @@ -54,6 +72,15 @@ def test_filled_with_colormap(): return ax.figure +@pytest.mark.mpl_image_compare(baseline_dir="output/oo") +def test_filled_with_colormap_calm_limit(): + # A windrose in filled representation, with a controlled colormap and a calm limit + ax = WindroseAxes.from_ax() + ax.contourf(wd, ws, bins=bins, cmap=cm.hot, calm_limit=0.2) + ax.set_legend() + return ax.figure + + @pytest.mark.mpl_image_compare(baseline_dir="output/oo") def test_filled_with_colormap_contours(): # Same as above, but with contours over each filled region... @@ -64,6 +91,16 @@ def test_filled_with_colormap_contours(): return ax.figure +@pytest.mark.mpl_image_compare(baseline_dir="output/oo") +def test_filled_with_colormap_contours_calm_limit(): + # Same as above, but with contours over each filled region... + ax = WindroseAxes.from_ax() + ax.contourf(wd, ws, bins=bins, cmap=cm.hot, calm_limit=0.2) + ax.contour(wd, ws, bins=bins, colors="black", calm_limit=0.2) + ax.set_legend() + return ax.figure + + @pytest.mark.mpl_image_compare(baseline_dir="output/oo") def test_without_filled_with_colormap_contours(): ax = WindroseAxes.from_ax() @@ -72,6 +109,14 @@ def test_without_filled_with_colormap_contours(): return ax.figure +@pytest.mark.mpl_image_compare(baseline_dir="output/oo") +def test_without_filled_with_colormap_contours_calm_limit(): + ax = WindroseAxes.from_ax() + ax.contour(wd, ws, bins=bins, cmap=cm.hot, lw=3, calm_limit=0.2) + ax.set_legend() + return ax.figure + + @pytest.mark.mpl_image_compare(baseline_dir="output/oo") def test_pdf(): ax = WindAxes.from_ax() diff --git a/windrose/windrose.py b/windrose/windrose.py index 2e450f9..536626d 100644 --- a/windrose/windrose.py +++ b/windrose/windrose.py @@ -14,8 +14,6 @@ DIR_DEFAULT = "direction" FIGSIZE_DEFAULT = (8, 8) DPI_DEFAULT = 80 -CALM_CIRCLE_COLOR = "red" -CALM_CIRCLE_ALPHA = 0.4 DEFAULT_THETA_LABELS = ["E", "N-E", "N", "N-W", "W", "S-W", "S", "S-E"] @@ -314,6 +312,7 @@ def _init_plot(self, direction, var, **kwargs): # Calm condition, mask data if needed calm_limit = kwargs.pop("calm_limit", None) + total = len(var) if calm_limit is not None: mask = var > calm_limit self.calm_count = len(var) - np.count_nonzero(mask) @@ -404,25 +403,15 @@ def _init_plot(self, direction, var, **kwargs): nsector, normed, blowto, + total, ) return bins, nbins, nsector, colors, angles, kwargs def _calm_circle(self): - """ - Draw the calm centered circle - and return the initial offset for plots methods - """ + """Draw the calm centered circle""" if self.calm_count and self.calm_count > 0: - circle = mpl.patches.Circle( - (0.0, 0.0), - self.calm_count, - transform=self.transData._b, - color=CALM_CIRCLE_COLOR, - alpha=CALM_CIRCLE_ALPHA, - ) - self.add_artist(circle) - return self.calm_count or 0 + self.set_rorigin(-(np.sqrt(self.calm_count / np.pi))) def contour(self, direction, var, **kwargs): """ @@ -482,10 +471,11 @@ def contour(self, direction, var, **kwargs): ), ) - offset = self._calm_circle() + self._calm_circle() + origin = 0 for i in range(nbins): - val = vals[i, :] + offset - offset += vals[i, :] + val = vals[i, :] + origin + origin += vals[i, :] zorder = ZBASE + nbins - i patch = self.plot(angles, val, color=colors[i], zorder=zorder, **kwargs) self.patches_list.extend(patch) @@ -550,10 +540,11 @@ def contourf(self, direction, var, **kwargs): ), ), ) - offset = self._calm_circle() + self._calm_circle() + origin = 0 for i in range(nbins): - val = vals[i, :] + offset - offset += vals[i, :] + val = vals[i, :] + origin + origin += vals[i, :] zorder = ZBASE + nbins - i patch = self.fill( np.append(angles, 0), @@ -624,17 +615,17 @@ def bar(self, direction, var, **kwargs): dtheta = 2 * np.pi / nsector opening = dtheta * opening - offs = self._calm_circle() + self._calm_circle() for j in range(nsector): - offset = offs + origin = 0 for i in range(nbins): if i > 0: - offset += self._info["table"][i - 1, j] + origin += self._info["table"][i - 1, j] val = self._info["table"][i, j] zorder = ZBASE + nbins - i patch = mpl.patches.Rectangle( - (angles[j] - opening / 2, offset), + (angles[j] - opening / 2, origin), opening, val, facecolor=colors[i], @@ -698,17 +689,17 @@ def box(self, direction, var, **kwargs): raise ValueError("edgecolor must be a string color") opening = np.linspace(0.0, np.pi / 16, nbins) - offs = self._calm_circle() + self._calm_circle() for j in range(nsector): - offset = offs + origin = 0 for i in range(nbins): if i > 0: - offset += self._info["table"][i - 1, j] + origin += self._info["table"][i - 1, j] val = self._info["table"][i, j] zorder = ZBASE + nbins - i patch = mpl.patches.Rectangle( - (angles[j] - opening[i] / 2, offset), + (angles[j] - opening[i] / 2, origin), opening[i], val, facecolor=colors[i], @@ -769,7 +760,7 @@ def pdf( return (self, params) -def histogram(direction, var, bins, nsector, normed=False, blowto=False): +def histogram(direction, var, bins, nsector, normed=False, blowto=False, total=0): """ Returns an array where, for each sector of wind (centred on the north), we have the number of time the wind comes with a @@ -819,7 +810,7 @@ def histogram(direction, var, bins, nsector, normed=False, blowto=False): # and remove the last col table = table[:, :-1] if normed: - table = table * 100 / table.sum() + table = table * 100 / total return dir_edges, var_bins, table