From 3f450f33d9e0b370114498d19cae039a26650901 Mon Sep 17 00:00:00 2001 From: Andrija Date: Thu, 14 Sep 2023 19:30:08 +0200 Subject: [PATCH 1/4] Add the smothing option for 1d-marginals --- src/corner/core.py | 60 ++++++++++++++++++++++++++-------------------- 1 file changed, 34 insertions(+), 26 deletions(-) diff --git a/src/corner/core.py b/src/corner/core.py index d742556..0f9c4a8 100644 --- a/src/corner/core.py +++ b/src/corner/core.py @@ -19,6 +19,7 @@ LogFormatterMathtext, LogLocator, MaxNLocator, + NullFormatter, NullLocator, ScalarFormatter, ) @@ -28,6 +29,11 @@ except ImportError: gaussian_filter = None +try: + from scipy.interpolate import interp1d +except ImportError: + interp1d = None + def corner_impl( xs, @@ -58,7 +64,7 @@ def corner_impl( reverse=False, labelpad=0.0, hist_kwargs=None, - **hist2d_kwargs, + **hist2d_kwargs ): if quantiles is None: quantiles = [] @@ -125,7 +131,8 @@ def corner_impl( if fig is None: fig, axes = pl.subplots(K, K, figsize=(dim, dim)) else: - axes, new_fig = _get_fig_axes(fig, K) + new_fig = False + axes = _get_fig_axes(fig, K) # Format the figure. lb = lbdim / dim @@ -135,7 +142,6 @@ def corner_impl( ) # Parse the parameter ranges. - force_range = False if range is None: if "extents" in hist2d_kwargs: logging.warning( @@ -160,8 +166,6 @@ def corner_impl( ) else: - force_range = True - # If any of the extents are percentiles, convert them to ranges. # Also make sure it's a normal list. range = list(range) @@ -234,11 +238,19 @@ def corner_impl( else: if gaussian_filter is None: raise ImportError("Please install scipy for smoothing") - n, _ = np.histogram(x, bins=bins_1d, weights=weights) + n, _ = np.histogram(x, bins=bins_1d, weights=weights, density=True) n = gaussian_filter(n, smooth1d) x0 = np.array(list(zip(bins_1d[:-1], bins_1d[1:]))).flatten() y0 = np.array(list(zip(n, n))).flatten() - ax.plot(x0, y0, **hist_kwargs) + if smooth1d is not None and interp1d is not None: + # Now use a continuos line for the plot instead of histogram counts + bins_1d_centers = 0.5*(bins_1d[1:] + bins_1d[:-1]) + pdfinterpolated = interp1d(bins_1d_centers, n, fill_value="extrapolate") + newx = np.linspace(bins_1d.min(), bins_1d.max(), bins_1d.size) + nonzero = pdfinterpolated(newx) > 0 + ax.plot(newx[nonzero], pdfinterpolated(newx)[nonzero], **hist_kwargs) + else: + ax.plot(x0, y0, **hist_kwargs) # Plot quantiles if wanted. if len(quantiles) > 0: @@ -286,14 +298,14 @@ def corner_impl( ax.set_title(title, **title_kwargs) # Set up the axes. - _set_xlim(force_range, new_fig, ax, range[i]) + _set_xlim(new_fig, ax, range[i]) ax.set_xscale(axes_scale[i]) if scale_hist: maxn = np.max(n) - _set_ylim(force_range, new_fig, ax, [-0.1 * maxn, 1.1 * maxn]) + _set_ylim(new_fig, ax, [-0.1 * maxn, 1.1 * maxn]) else: - _set_ylim(force_range, new_fig, ax, [0, 1.1 * np.max(n)]) + _set_ylim(new_fig, ax, [0, 1.1 * np.max(n)]) ax.set_yticklabels([]) if max_n_ticks == 0: @@ -378,7 +390,6 @@ def corner_impl( smooth=smooth, bins=[bins[j], bins[i]], new_fig=new_fig, - force_range=force_range, **hist2d_kwargs, ) @@ -539,9 +550,9 @@ def hist2d( data_kwargs=None, pcolor_kwargs=None, new_fig=True, - force_range=False, - **kwargs, + **kwargs ): + """ Plot a 2-D histogram of samples. @@ -561,9 +572,6 @@ def hist2d( levels : array_like The contour levels to draw. - If None, (0.5, 1, 1.5, 2)-sigma equivalent contours are drawn, - i.e., containing 11.8%, 39.3%, 67.5% and 86.4% of the samples. - See https://corner.readthedocs.io/en/latest/pages/sigmas/ ax : matplotlib.Axes A axes instance on which to add the 2-D histogram. @@ -797,8 +805,8 @@ def hist2d( contour_kwargs["colors"] = contour_kwargs.get("colors", color) ax.contour(X2, Y2, H2.T, V, **contour_kwargs) - _set_xlim(force_range, new_fig, ax, range[0]) - _set_ylim(force_range, new_fig, ax, range[1]) + _set_xlim(new_fig, ax, range[0]) + _set_ylim(new_fig, ax, range[1]) ax.set_xscale(axes_scale[0]) ax.set_yscale(axes_scale[1]) @@ -828,7 +836,7 @@ def overplot_lines(fig, xs, reverse=False, **kwargs): """ K = len(xs) - axes, _ = _get_fig_axes(fig, K) + axes = _get_fig_axes(fig, K) if reverse: for k1 in range(K): if xs[k1] is not None: @@ -877,7 +885,7 @@ def overplot_points(fig, xs, reverse=False, **kwargs): kwargs["linestyle"] = kwargs.pop("linestyle", "none") xs = _parse_input(xs) K = len(xs) - axes, _ = _get_fig_axes(fig, K) + axes = _get_fig_axes(fig, K) if reverse: for k1 in range(K): for k2 in range(k1): @@ -901,9 +909,9 @@ def _parse_input(xs): def _get_fig_axes(fig, K): if not fig.axes: - return fig.subplots(K, K), True + return fig.subplots(K, K) try: - return np.array(fig.axes).reshape((K, K)), False + return np.array(fig.axes).reshape((K, K)) except ValueError: raise ValueError( ( @@ -913,15 +921,15 @@ def _get_fig_axes(fig, K): ) -def _set_xlim(force, new_fig, ax, new_xlim): - if force or new_fig: +def _set_xlim(new_fig, ax, new_xlim): + if new_fig: return ax.set_xlim(new_xlim) xlim = ax.get_xlim() return ax.set_xlim([min(xlim[0], new_xlim[0]), max(xlim[1], new_xlim[1])]) -def _set_ylim(force, new_fig, ax, new_ylim): - if force or new_fig: +def _set_ylim(new_fig, ax, new_ylim): + if new_fig: return ax.set_ylim(new_ylim) ylim = ax.get_ylim() return ax.set_ylim([min(ylim[0], new_ylim[0]), max(ylim[1], new_ylim[1])]) From b5036cd982bb09bbe20ba1640db98d44ce2adaa0 Mon Sep 17 00:00:00 2001 From: "pre-commit-ci[bot]" <66853113+pre-commit-ci[bot]@users.noreply.github.com> Date: Thu, 14 Sep 2023 17:31:04 +0000 Subject: [PATCH 2/4] [pre-commit.ci] auto fixes from pre-commit.com hooks for more information, see https://pre-commit.ci --- src/corner/core.py | 17 +++++++++++------ 1 file changed, 11 insertions(+), 6 deletions(-) diff --git a/src/corner/core.py b/src/corner/core.py index 0f9c4a8..792f79f 100644 --- a/src/corner/core.py +++ b/src/corner/core.py @@ -64,7 +64,7 @@ def corner_impl( reverse=False, labelpad=0.0, hist_kwargs=None, - **hist2d_kwargs + **hist2d_kwargs, ): if quantiles is None: quantiles = [] @@ -244,11 +244,17 @@ def corner_impl( y0 = np.array(list(zip(n, n))).flatten() if smooth1d is not None and interp1d is not None: # Now use a continuos line for the plot instead of histogram counts - bins_1d_centers = 0.5*(bins_1d[1:] + bins_1d[:-1]) - pdfinterpolated = interp1d(bins_1d_centers, n, fill_value="extrapolate") + bins_1d_centers = 0.5 * (bins_1d[1:] + bins_1d[:-1]) + pdfinterpolated = interp1d( + bins_1d_centers, n, fill_value="extrapolate" + ) newx = np.linspace(bins_1d.min(), bins_1d.max(), bins_1d.size) nonzero = pdfinterpolated(newx) > 0 - ax.plot(newx[nonzero], pdfinterpolated(newx)[nonzero], **hist_kwargs) + ax.plot( + newx[nonzero], + pdfinterpolated(newx)[nonzero], + **hist_kwargs, + ) else: ax.plot(x0, y0, **hist_kwargs) @@ -550,9 +556,8 @@ def hist2d( data_kwargs=None, pcolor_kwargs=None, new_fig=True, - **kwargs + **kwargs, ): - """ Plot a 2-D histogram of samples. From 469b58ee1c56d0f259b3e12af3b33699b914e5e4 Mon Sep 17 00:00:00 2001 From: Andrija Date: Mon, 18 Sep 2023 23:39:08 +0200 Subject: [PATCH 3/4] Sync with HEAD of main --- src/corner/core.py | 50 +++++++++++++++++++++++----------------------- 1 file changed, 25 insertions(+), 25 deletions(-) diff --git a/src/corner/core.py b/src/corner/core.py index 792f79f..92067d5 100644 --- a/src/corner/core.py +++ b/src/corner/core.py @@ -19,7 +19,6 @@ LogFormatterMathtext, LogLocator, MaxNLocator, - NullFormatter, NullLocator, ScalarFormatter, ) @@ -131,8 +130,7 @@ def corner_impl( if fig is None: fig, axes = pl.subplots(K, K, figsize=(dim, dim)) else: - new_fig = False - axes = _get_fig_axes(fig, K) + axes, new_fig = _get_fig_axes(fig, K) # Format the figure. lb = lbdim / dim @@ -142,6 +140,7 @@ def corner_impl( ) # Parse the parameter ranges. + force_range = False if range is None: if "extents" in hist2d_kwargs: logging.warning( @@ -166,6 +165,8 @@ def corner_impl( ) else: + force_range = True + # If any of the extents are percentiles, convert them to ranges. # Also make sure it's a normal list. range = list(range) @@ -244,17 +245,11 @@ def corner_impl( y0 = np.array(list(zip(n, n))).flatten() if smooth1d is not None and interp1d is not None: # Now use a continuos line for the plot instead of histogram counts - bins_1d_centers = 0.5 * (bins_1d[1:] + bins_1d[:-1]) - pdfinterpolated = interp1d( - bins_1d_centers, n, fill_value="extrapolate" - ) + bins_1d_centers = 0.5*(bins_1d[1:] + bins_1d[:-1]) + pdfinterpolated = interp1d(bins_1d_centers, n, fill_value="extrapolate") newx = np.linspace(bins_1d.min(), bins_1d.max(), bins_1d.size) nonzero = pdfinterpolated(newx) > 0 - ax.plot( - newx[nonzero], - pdfinterpolated(newx)[nonzero], - **hist_kwargs, - ) + ax.plot(newx[nonzero], pdfinterpolated(newx)[nonzero], **hist_kwargs) else: ax.plot(x0, y0, **hist_kwargs) @@ -304,14 +299,14 @@ def corner_impl( ax.set_title(title, **title_kwargs) # Set up the axes. - _set_xlim(new_fig, ax, range[i]) + _set_xlim(force_range, new_fig, ax, range[i]) ax.set_xscale(axes_scale[i]) if scale_hist: maxn = np.max(n) - _set_ylim(new_fig, ax, [-0.1 * maxn, 1.1 * maxn]) + _set_ylim(force_range, new_fig, ax, [-0.1 * maxn, 1.1 * maxn]) else: - _set_ylim(new_fig, ax, [0, 1.1 * np.max(n)]) + _set_ylim(force_range, new_fig, ax, [0, 1.1 * np.max(n)]) ax.set_yticklabels([]) if max_n_ticks == 0: @@ -396,6 +391,7 @@ def corner_impl( smooth=smooth, bins=[bins[j], bins[i]], new_fig=new_fig, + force_range=force_range, **hist2d_kwargs, ) @@ -556,6 +552,7 @@ def hist2d( data_kwargs=None, pcolor_kwargs=None, new_fig=True, + force_range=False, **kwargs, ): """ @@ -577,6 +574,9 @@ def hist2d( levels : array_like The contour levels to draw. + If None, (0.5, 1, 1.5, 2)-sigma equivalent contours are drawn, + i.e., containing 11.8%, 39.3%, 67.5% and 86.4% of the samples. + See https://corner.readthedocs.io/en/latest/pages/sigmas/ ax : matplotlib.Axes A axes instance on which to add the 2-D histogram. @@ -810,8 +810,8 @@ def hist2d( contour_kwargs["colors"] = contour_kwargs.get("colors", color) ax.contour(X2, Y2, H2.T, V, **contour_kwargs) - _set_xlim(new_fig, ax, range[0]) - _set_ylim(new_fig, ax, range[1]) + _set_xlim(force_range, new_fig, ax, range[0]) + _set_ylim(force_range, new_fig, ax, range[1]) ax.set_xscale(axes_scale[0]) ax.set_yscale(axes_scale[1]) @@ -841,7 +841,7 @@ def overplot_lines(fig, xs, reverse=False, **kwargs): """ K = len(xs) - axes = _get_fig_axes(fig, K) + axes, _ = _get_fig_axes(fig, K) if reverse: for k1 in range(K): if xs[k1] is not None: @@ -890,7 +890,7 @@ def overplot_points(fig, xs, reverse=False, **kwargs): kwargs["linestyle"] = kwargs.pop("linestyle", "none") xs = _parse_input(xs) K = len(xs) - axes = _get_fig_axes(fig, K) + axes, _ = _get_fig_axes(fig, K) if reverse: for k1 in range(K): for k2 in range(k1): @@ -914,9 +914,9 @@ def _parse_input(xs): def _get_fig_axes(fig, K): if not fig.axes: - return fig.subplots(K, K) + return fig.subplots(K, K), True try: - return np.array(fig.axes).reshape((K, K)) + return np.array(fig.axes).reshape((K, K)), False except ValueError: raise ValueError( ( @@ -926,15 +926,15 @@ def _get_fig_axes(fig, K): ) -def _set_xlim(new_fig, ax, new_xlim): - if new_fig: +def _set_xlim(force, new_fig, ax, new_xlim): + if force or new_fig: return ax.set_xlim(new_xlim) xlim = ax.get_xlim() return ax.set_xlim([min(xlim[0], new_xlim[0]), max(xlim[1], new_xlim[1])]) -def _set_ylim(new_fig, ax, new_ylim): - if new_fig: +def _set_ylim(force, new_fig, ax, new_ylim): + if force or new_fig: return ax.set_ylim(new_ylim) ylim = ax.get_ylim() return ax.set_ylim([min(ylim[0], new_ylim[0]), max(ylim[1], new_ylim[1])]) From c87ddfb23cdac3677c730bbee8c6fd982dc53ed5 Mon Sep 17 00:00:00 2001 From: "pre-commit-ci[bot]" <66853113+pre-commit-ci[bot]@users.noreply.github.com> Date: Mon, 18 Sep 2023 21:39:39 +0000 Subject: [PATCH 4/4] [pre-commit.ci] auto fixes from pre-commit.com hooks for more information, see https://pre-commit.ci --- src/corner/core.py | 12 +++++++++--- 1 file changed, 9 insertions(+), 3 deletions(-) diff --git a/src/corner/core.py b/src/corner/core.py index 92067d5..9b78c0b 100644 --- a/src/corner/core.py +++ b/src/corner/core.py @@ -245,11 +245,17 @@ def corner_impl( y0 = np.array(list(zip(n, n))).flatten() if smooth1d is not None and interp1d is not None: # Now use a continuos line for the plot instead of histogram counts - bins_1d_centers = 0.5*(bins_1d[1:] + bins_1d[:-1]) - pdfinterpolated = interp1d(bins_1d_centers, n, fill_value="extrapolate") + bins_1d_centers = 0.5 * (bins_1d[1:] + bins_1d[:-1]) + pdfinterpolated = interp1d( + bins_1d_centers, n, fill_value="extrapolate" + ) newx = np.linspace(bins_1d.min(), bins_1d.max(), bins_1d.size) nonzero = pdfinterpolated(newx) > 0 - ax.plot(newx[nonzero], pdfinterpolated(newx)[nonzero], **hist_kwargs) + ax.plot( + newx[nonzero], + pdfinterpolated(newx)[nonzero], + **hist_kwargs, + ) else: ax.plot(x0, y0, **hist_kwargs)