From 958e329b198a9036fc121d11775815ded7c9acad Mon Sep 17 00:00:00 2001 From: Oscar Gustafsson Date: Sat, 4 Jun 2022 00:28:17 +0200 Subject: [PATCH] Rename ncol parameter to ncols --- .../rename_ncol_keyword_in_legend.rst | 7 +++++ .../backends/qt_editor/figureoptions.py | 6 ++-- lib/matplotlib/legend.py | 29 ++++++++++++------- lib/matplotlib/tests/test_axes.py | 2 +- lib/matplotlib/tests/test_legend.py | 15 ++++++++-- lib/matplotlib/tests/test_offsetbox.py | 2 +- 6 files changed, 43 insertions(+), 18 deletions(-) create mode 100644 doc/users/next_whats_new/rename_ncol_keyword_in_legend.rst diff --git a/doc/users/next_whats_new/rename_ncol_keyword_in_legend.rst b/doc/users/next_whats_new/rename_ncol_keyword_in_legend.rst new file mode 100644 index 000000000000..54db966bf8a9 --- /dev/null +++ b/doc/users/next_whats_new/rename_ncol_keyword_in_legend.rst @@ -0,0 +1,7 @@ +``ncol`` keyword argument to ``legend`` renamed to ``ncols`` +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +The ``ncol`` keyword argument to `~.Axes.legend` for controlling the number of +columns is renamed to ``ncols`` for consistency with the ``ncols`` and +``nrows`` keywords of `~.Figure.subplots` and `~.GridSpec`. +``ncol`` is still supported though. diff --git a/lib/matplotlib/backends/qt_editor/figureoptions.py b/lib/matplotlib/backends/qt_editor/figureoptions.py index b7c42028e00e..67e00006910f 100644 --- a/lib/matplotlib/backends/qt_editor/figureoptions.py +++ b/lib/matplotlib/backends/qt_editor/figureoptions.py @@ -230,12 +230,12 @@ def apply_callback(data): # re-generate legend, if checkbox is checked if generate_legend: draggable = None - ncol = 1 + ncols = 1 if axes.legend_ is not None: old_legend = axes.get_legend() draggable = old_legend._draggable is not None - ncol = old_legend._ncol - new_legend = axes.legend(ncol=ncol) + ncols = old_legend._ncols + new_legend = axes.legend(ncols=ncols) if new_legend: new_legend.set_draggable(draggable) diff --git a/lib/matplotlib/legend.py b/lib/matplotlib/legend.py index ffe043c67461..bf67d9dc5a8d 100644 --- a/lib/matplotlib/legend.py +++ b/lib/matplotlib/legend.py @@ -162,9 +162,12 @@ def _update_bbox_to_anchor(self, loc_in_canvas): loc='upper right', bbox_to_anchor=(0.5, 0.5) -ncol : int, default: 1 +ncols : int, default: 1 The number of columns that the legend has. + For backward compatibility, the spelling *ncol* is also supported + but it is discouraged. If both are given, *ncols* takes precedence. + prop : None or `matplotlib.font_manager.FontProperties` or dict The font properties of the legend. If None (default), the current :data:`matplotlib.rcParams` will be used. @@ -317,7 +320,7 @@ def __init__( borderaxespad=None, # pad between the axes and legend border columnspacing=None, # spacing between columns - ncol=1, # number of columns + ncols=1, # number of columns mode=None, # horizontal distribution of columns: None or "expand" fancybox=None, # True: fancy box, False: rounded box, None: rcParam @@ -333,6 +336,8 @@ def __init__( frameon=None, # draw frame handler_map=None, title_fontproperties=None, # properties for the legend title + *, + ncol=1 # synonym for ncols (backward compatibility) ): """ Parameters @@ -418,8 +423,8 @@ def val_or_rc(val, rc_name): handles = list(handles) if len(handles) < 2: - ncol = 1 - self._ncol = ncol + ncols = 1 + self._ncols = ncols if ncols != 1 else ncol if self.numpoints <= 0: raise ValueError("numpoints must be > 0; it was %d" % numpoints) @@ -581,6 +586,10 @@ def _set_loc(self, loc): self.stale = True self._legend_box.set_offset(self._findoffset) + def set_ncols(self, ncols): + """Set the number of columns.""" + self._ncols = ncols + def _get_loc(self): return self._loc_real @@ -767,12 +776,12 @@ def _init_legend_box(self, handles, labels, markerfirst=True): handles_and_labels.append((handlebox, textbox)) columnbox = [] - # array_split splits n handles_and_labels into ncol columns, with the - # first n%ncol columns having an extra entry. filter(len, ...) handles - # the case where n < ncol: the last ncol-n columns are empty and get - # filtered out. - for handles_and_labels_column \ - in filter(len, np.array_split(handles_and_labels, self._ncol)): + # array_split splits n handles_and_labels into ncols columns, with the + # first n%ncols columns having an extra entry. filter(len, ...) + # handles the case where n < ncols: the last ncols-n columns are empty + # and get filtered out. + for handles_and_labels_column in filter( + len, np.array_split(handles_and_labels, self._ncols)): # pack handlebox and labelbox into itembox itemboxes = [HPacker(pad=0, sep=self.handletextpad * fontsize, diff --git a/lib/matplotlib/tests/test_axes.py b/lib/matplotlib/tests/test_axes.py index 72e5f63cd2ab..143d10a252e3 100644 --- a/lib/matplotlib/tests/test_axes.py +++ b/lib/matplotlib/tests/test_axes.py @@ -4013,7 +4013,7 @@ def test_hist_stacked_bar(): fig, ax = plt.subplots() ax.hist(d, bins=10, histtype='barstacked', align='mid', color=colors, label=labels) - ax.legend(loc='upper right', bbox_to_anchor=(1.0, 1.0), ncol=1) + ax.legend(loc='upper right', bbox_to_anchor=(1.0, 1.0), ncols=1) def test_hist_barstacked_bottom_unchanged(): diff --git a/lib/matplotlib/tests/test_legend.py b/lib/matplotlib/tests/test_legend.py index a2b7479a801e..063477a595d9 100644 --- a/lib/matplotlib/tests/test_legend.py +++ b/lib/matplotlib/tests/test_legend.py @@ -5,7 +5,7 @@ import numpy as np import pytest -from matplotlib.testing.decorators import image_comparison +from matplotlib.testing.decorators import check_figures_equal, image_comparison from matplotlib.testing._markers import needs_usetex import matplotlib.pyplot as plt import matplotlib as mpl @@ -148,7 +148,7 @@ def test_fancy(): plt.errorbar(np.arange(10), np.arange(10), xerr=0.5, yerr=0.5, label='XX') plt.legend(loc="center left", bbox_to_anchor=[1.0, 0.5], - ncol=2, shadow=True, title="My legend", numpoints=1) + ncols=2, shadow=True, title="My legend", numpoints=1) @image_comparison(['framealpha'], remove_text=True, @@ -190,7 +190,7 @@ def test_legend_expand(): ax.plot(x, x - 50, 'o', label='y=-1') l2 = ax.legend(loc='right', mode=mode) ax.add_artist(l2) - ax.legend(loc='lower left', mode=mode, ncol=2) + ax.legend(loc='lower left', mode=mode, ncols=2) @image_comparison(['hatching'], remove_text=True, style='default') @@ -926,3 +926,12 @@ def test_legend_markers_from_line2d(): assert markers == new_markers == _markers assert labels == new_labels + + +@check_figures_equal() +def test_ncol_ncols(fig_test, fig_ref): + # Test that both ncol and ncols work + strings = ["a", "b", "c", "d", "e", "f"] + ncols = 3 + fig_test.legend(strings, ncol=ncols) + fig_ref.legend(strings, ncols=ncols) diff --git a/lib/matplotlib/tests/test_offsetbox.py b/lib/matplotlib/tests/test_offsetbox.py index 832ff3ffe58a..561fe230c2f7 100644 --- a/lib/matplotlib/tests/test_offsetbox.py +++ b/lib/matplotlib/tests/test_offsetbox.py @@ -117,7 +117,7 @@ def test_expand_with_tight_layout(): d2 = [2, 1] ax.plot(d1, label='series 1') ax.plot(d2, label='series 2') - ax.legend(ncol=2, mode='expand') + ax.legend(ncols=2, mode='expand') fig.tight_layout() # where the crash used to happen