diff --git a/doc/users/whats_new/plotting.rst b/doc/users/whats_new/plotting.rst index 1139b5e78e78..1ca2f6a69434 100644 --- a/doc/users/whats_new/plotting.rst +++ b/doc/users/whats_new/plotting.rst @@ -1,3 +1,11 @@ +Plot bar and barh with labels +````````````````````````````` + +Added kwarg "tick_label" to bar and barh to support plotting bar graphs with a +text label for each bar. +Example: + bar([1, 2], [1, 1], tick_label=['bar1', 'bar2']) + Added center and frame kwargs to pie ```````````````````````````````````` diff --git a/lib/matplotlib/axes/_axes.py b/lib/matplotlib/axes/_axes.py index 0659bbce362c..9389e7ea4220 100644 --- a/lib/matplotlib/axes/_axes.py +++ b/lib/matplotlib/axes/_axes.py @@ -1838,6 +1838,10 @@ def bar(self, left, height, width=0.8, bottom=None, **kwargs): linewidth; If 0, don't draw edges. default: None + tick_label : string or array-like, optional + the tick labels of the bars + default: None + xerr : scalar or array-like, optional if not None, will be used to generate errorbar(s) on the bar chart default: None @@ -1908,6 +1912,9 @@ def bar(self, left, height, width=0.8, bottom=None, **kwargs): edgecolor = kwargs.pop('edgecolor', None) linewidth = kwargs.pop('linewidth', None) + tick_label = kwargs.pop('tick_label', None) + label_ticks_flag = tick_label is not None + # Because xerr and yerr will be passed to errorbar, # most dimension checking and processing will be left # to the errorbar method. @@ -1938,6 +1945,7 @@ def make_iterable(x): _bottom = bottom bottom = make_iterable(bottom) linewidth = make_iterable(linewidth) + tick_label = make_iterable(tick_label) adjust_ylim = False adjust_xlim = False @@ -1956,6 +1964,9 @@ def make_iterable(x): width *= nbars if len(bottom) == 1: bottom *= nbars + + tick_label_axis = self.xaxis + tick_label_position = left elif orientation == 'horizontal': self._process_unit_info(xdata=width, ydata=bottom, kwargs=kwargs) if log: @@ -1971,11 +1982,16 @@ def make_iterable(x): left *= nbars if len(height) == 1: height *= nbars + + tick_label_axis = self.yaxis + tick_label_position = bottom else: raise ValueError('invalid orientation: %s' % orientation) if len(linewidth) < nbars: linewidth *= nbars + if len(tick_label) < nbars: + tick_label *= nbars if color is None: color = [None] * nbars @@ -2008,6 +2024,9 @@ def make_iterable(x): if len(bottom) != nbars: raise ValueError("incompatible sizes: argument 'bottom' " "must be length %d or scalar" % nbars) + if len(tick_label) != nbars: + raise ValueError("incompatible sizes: argument 'tick_label' " + "must be length %d or string" % nbars) patches = [] @@ -2103,6 +2122,10 @@ def make_iterable(x): bar_container = BarContainer(patches, errorbar, label=label) self.add_container(bar_container) + if label_ticks_flag: + tick_label_axis.set_ticks(tick_label_position) + tick_label_axis.set_ticklabels(tick_label) + return bar_container @docstring.dedent_interpd @@ -2148,6 +2171,9 @@ def barh(self, bottom, width, height=0.8, left=None, **kwargs): width of bar edge(s). If None, use default linewidth; If 0, don't draw edges. + tick_label : string or array-like, optional, default: None + the tick labels of the bars + xerr : scalar or array-like, optional, default: None if not None, will be used to generate errorbar(s) on the bar chart diff --git a/lib/matplotlib/tests/baseline_images/test_axes/bar_tick_label_multiple.png b/lib/matplotlib/tests/baseline_images/test_axes/bar_tick_label_multiple.png new file mode 100644 index 000000000000..a0ce8625befc Binary files /dev/null and b/lib/matplotlib/tests/baseline_images/test_axes/bar_tick_label_multiple.png differ diff --git a/lib/matplotlib/tests/baseline_images/test_axes/bar_tick_label_single.png b/lib/matplotlib/tests/baseline_images/test_axes/bar_tick_label_single.png new file mode 100644 index 000000000000..e4742e58af9b Binary files /dev/null and b/lib/matplotlib/tests/baseline_images/test_axes/bar_tick_label_single.png differ diff --git a/lib/matplotlib/tests/baseline_images/test_axes/barh_tick_label.png b/lib/matplotlib/tests/baseline_images/test_axes/barh_tick_label.png new file mode 100644 index 000000000000..e83d42a4290d Binary files /dev/null and b/lib/matplotlib/tests/baseline_images/test_axes/barh_tick_label.png differ diff --git a/lib/matplotlib/tests/test_axes.py b/lib/matplotlib/tests/test_axes.py index fe6c5c4567a9..de71bd409275 100644 --- a/lib/matplotlib/tests/test_axes.py +++ b/lib/matplotlib/tests/test_axes.py @@ -131,7 +131,6 @@ def test_twinx_cla(): @image_comparison(baseline_images=["minorticks_on_rcParams_both"], extensions=['png']) def test_minorticks_on_rcParams_both(): - fig = plt.figure() matplotlib.rcParams['xtick.minor.visible'] = True matplotlib.rcParams['ytick.minor.visible'] = True @@ -1011,6 +1010,32 @@ def test_marker_edges(): ax.plot(x+0.2, np.sin(x), 'y.', ms=30.0, mew=2, mec='b') +@image_comparison(baseline_images=['bar_tick_label_single'], + extensions=['png']) +def test_bar_tick_label_single(): + # From 2516: plot bar with array of string labels for x axis + ax = plt.gca() + ax.bar(0, 1 , tick_label='a') + + +@image_comparison(baseline_images=['bar_tick_label_multiple'], + extensions=['png']) +def test_bar_tick_label_multiple(): + # From 2516: plot bar with array of string labels for x axis + ax = plt.gca() + ax.bar([1, 2.5], [1, 2], width=[0.2, 0.5], tick_label=['a', 'b'], + align='center') + + +@image_comparison(baseline_images=['barh_tick_label'], + extensions=['png']) +def test_barh_tick_label(): + # From 2516: plot barh with array of string labels for y axis + ax = plt.gca() + ax.barh([1, 2.5], [1, 2], height=[0.2, 0.5], tick_label=['a', 'b'], + align='center') + + @image_comparison(baseline_images=['hist_log'], remove_text=True) def test_hist_log():