diff --git a/lib/matplotlib/axes/_axes.py b/lib/matplotlib/axes/_axes.py index 5ffd8a7bae08..9ac471934a50 100644 --- a/lib/matplotlib/axes/_axes.py +++ b/lib/matplotlib/axes/_axes.py @@ -2475,7 +2475,7 @@ def pie(self, x, explode=None, labels=None, colors=None, autopct=None, pctdistance=0.6, shadow=False, labeldistance=1.1, startangle=None, radius=None, counterclock=True, wedgeprops=None, textprops=None, center=(0, 0), - frame=False): + frame=False, rotatelabels=False): r""" Plot a pie chart. @@ -2542,6 +2542,9 @@ def pie(self, x, explode=None, labels=None, colors=None, *frame*: [ *False* | *True* ] Plot axes frame with the chart. + *rotatelabels*: [ *False* | *True* ] + Rotate each label to the angle of the corresponding slice. + The pie chart will probably look best if the figure and axes are square, or the Axes aspect is equal. e.g.:: @@ -2639,12 +2642,18 @@ def get_next_color(): xt = x + labeldistance * radius * math.cos(thetam) yt = y + labeldistance * radius * math.sin(thetam) - label_alignment = xt > 0 and 'left' or 'right' + label_alignment_h = xt > 0 and 'left' or 'right' + label_alignment_v = 'center' + label_rotation = 'horizontal' + if rotatelabels: + label_alignment_v = yt > 0 and 'bottom' or 'top' + label_rotation = np.rad2deg(thetam) + (0 if xt > 0 else 180) t = self.text(xt, yt, label, size=rcParams['xtick.labelsize'], - horizontalalignment=label_alignment, - verticalalignment='center', + horizontalalignment=label_alignment_h, + verticalalignment=label_alignment_v, + rotation=label_rotation, **textprops) texts.append(t) diff --git a/lib/matplotlib/pyplot.py b/lib/matplotlib/pyplot.py index f6801ff4ca66..3a8f70f761b6 100644 --- a/lib/matplotlib/pyplot.py +++ b/lib/matplotlib/pyplot.py @@ -3208,7 +3208,7 @@ def phase_spectrum(x, Fs=None, Fc=None, window=None, pad_to=None, sides=None, def pie(x, explode=None, labels=None, colors=None, autopct=None, pctdistance=0.6, shadow=False, labeldistance=1.1, startangle=None, radius=None, counterclock=True, wedgeprops=None, textprops=None, - center=(0, 0), frame=False, hold=None, data=None): + center=(0, 0), frame=False, rotatelabels=False, hold=None, data=None): ax = gca() # Deprecated: allow callers to override the hold state # by passing hold=True|False @@ -3225,7 +3225,7 @@ def pie(x, explode=None, labels=None, colors=None, autopct=None, labeldistance=labeldistance, startangle=startangle, radius=radius, counterclock=counterclock, wedgeprops=wedgeprops, textprops=textprops, center=center, - frame=frame, data=data) + frame=frame, rotatelabels=rotatelabels, data=data) finally: ax._hold = washold diff --git a/lib/matplotlib/tests/baseline_images/test_axes/pie_rotatelabels_true.png b/lib/matplotlib/tests/baseline_images/test_axes/pie_rotatelabels_true.png new file mode 100644 index 000000000000..91664207dee7 Binary files /dev/null and b/lib/matplotlib/tests/baseline_images/test_axes/pie_rotatelabels_true.png differ diff --git a/lib/matplotlib/tests/test_axes.py b/lib/matplotlib/tests/test_axes.py index 41d604808b5d..7506d0dac286 100644 --- a/lib/matplotlib/tests/test_axes.py +++ b/lib/matplotlib/tests/test_axes.py @@ -4242,6 +4242,22 @@ def test_pie_frame_grid(): plt.axis('equal') +@image_comparison(baseline_images=['pie_rotatelabels_true'], + extensions=['png']) +def test_pie_rotatelabels_true(): + # The slices will be ordered and plotted counter-clockwise. + labels = 'Hogwarts', 'Frogs', 'Dogs', 'Logs' + sizes = [15, 30, 45, 10] + colors = ['yellowgreen', 'gold', 'lightskyblue', 'lightcoral'] + explode = (0, 0.1, 0, 0) # only "explode" the 2nd slice (i.e. 'Hogs') + + plt.pie(sizes, explode=explode, labels=labels, colors=colors, + autopct='%1.1f%%', shadow=True, startangle=90, + rotatelabels=True) + # Set aspect ratio to be equal so that pie is drawn as a circle. + plt.axis('equal') + + @image_comparison(baseline_images=['set_get_ticklabels'], extensions=['png']) def test_set_get_ticklabels(): # test issue 2246