diff --git a/examples/pylab_examples/demo_tight_labels.py b/examples/pylab_examples/demo_tight_labels.py new file mode 100644 index 000000000000..d745e12169ef --- /dev/null +++ b/examples/pylab_examples/demo_tight_labels.py @@ -0,0 +1,8 @@ +import matplotlib.pyplot as plt + +for n in [1, 2, 3, 5]: + fig, axes_list = plt.subplots(n, n) + plt.tight_labels(0.5, 0.3) + plt.tight_layout() + +plt.show() diff --git a/lib/matplotlib/axes.py b/lib/matplotlib/axes.py index a5418abbff90..5bbf8b0bc69a 100644 --- a/lib/matplotlib/axes.py +++ b/lib/matplotlib/axes.py @@ -8435,6 +8435,14 @@ def triplot(self, *args, **kwargs): mtri.triplot(self, *args, **kwargs) triplot.__doc__ = mtri.triplot.__doc__ + def optimize_ticker_nbin(self, + max_label_fraction_x, max_label_fraction_y, + renderer): + if max_label_fraction_x: + self.xaxis.optimize_ticker_nbin(max_label_fraction_x, renderer) + if max_label_fraction_y: + self.yaxis.optimize_ticker_nbin(max_label_fraction_y, renderer) + from matplotlib.gridspec import GridSpec, SubplotSpec diff --git a/lib/matplotlib/axis.py b/lib/matplotlib/axis.py index 43db8b9b7f9f..aa2dbe68adf3 100644 --- a/lib/matplotlib/axis.py +++ b/lib/matplotlib/axis.py @@ -1528,6 +1528,40 @@ def axis_date(self, tz=None): tz = pytz.timezone(tz) self.update_units(datetime.datetime(2009,1,1,0,0,0,0,tz)) + def optimize_ticker_nbin(self, max_label_fraction, renderer): + """ + update the _nbin attribute of the major ticker so it is the maximum integer + that the occupy fraction of labels are less than the *max_label_fraction*. + """ + + if not self.get_visible(): return + + if not 0. <= max_label_fraction <= 1.: + raise ValueError() + + min_nbin = self.major.locator._nbins + + while self._get_label_occupy_fraction(renderer) < max_label_fraction: + self.major.locator._nbins *= 2 + else: + max_nbin = self.major.locator._nbins + + if min_nbin == max_nbin: + min_nbin=1 + + while True: + if max_nbin - min_nbin <= 1: + break + new_nbin = int(0.5*(min_nbin+max_nbin)) + self.major.locator._nbins = new_nbin + if self._get_label_occupy_fraction(renderer) < max_label_fraction: + min_nbin = new_nbin + else: + max_nbin = new_nbin + + self.major.locator._nbins = min_nbin + + class XAxis(Axis): __name__ = 'xaxis' @@ -1786,6 +1820,22 @@ def set_default_intervals(self): self.axes.viewLim.intervalx = xmin, xmax + def _get_label_occupy_fraction(self, renderer): + """ + Return label_total_length / axis_length + """ + ticks_to_draw = self._update_ticks(renderer) + ticklabelBoxes, ticklabelBoxes2 = self._get_tick_bboxes(ticks_to_draw, renderer) + + if not ticklabelBoxes: + ticklabelBoxes = ticklabelBoxes2 + + label_total_length = sum([bb.width for bb in ticklabelBoxes]) + + axis_length = self.axes.bbox.width + + return label_total_length / axis_length + class YAxis(Axis): __name__ = 'yaxis' @@ -2049,3 +2099,20 @@ def set_default_intervals(self): self.axes.dataLim.intervaly = ymin, ymax if not viewMutated: self.axes.viewLim.intervaly = ymin, ymax + + + def _get_label_occupy_fraction(self, renderer): + """ + Return label_total_length / axis_length + """ + ticks_to_draw = self._update_ticks(renderer) + ticklabelBoxes, ticklabelBoxes2 = self._get_tick_bboxes(ticks_to_draw, renderer) + + if not ticklabelBoxes: + ticklabelBoxes = ticklabelBoxes2 + + label_total_length = sum([bb.height for bb in ticklabelBoxes]) + + axis_length = self.axes.bbox.height + + return label_total_length / axis_length diff --git a/lib/matplotlib/figure.py b/lib/matplotlib/figure.py index 467fd009eb8c..fcbf246fa9c1 100644 --- a/lib/matplotlib/figure.py +++ b/lib/matplotlib/figure.py @@ -1417,6 +1417,18 @@ def tight_layout(self, renderer=None, pad=1.2, h_pad=None, w_pad=None): self.subplots_adjust(**kwargs) + def tight_labels(self, renderer=None, label_fraction_x=0.5, label_fraction_y=0.3): + """ + """ + + from tight_layout import get_renderer + + if renderer is None: + renderer = get_renderer(self) + + for ax in self.axes: + ax.optimize_ticker_nbin( label_fraction_x, label_fraction_y, renderer) + def figaspect(arg): """ diff --git a/lib/matplotlib/pyplot.py b/lib/matplotlib/pyplot.py index e174b0cb015e..c4fc8f62bbeb 100644 --- a/lib/matplotlib/pyplot.py +++ b/lib/matplotlib/pyplot.py @@ -1057,6 +1057,15 @@ def tight_layout(pad=1.2, h_pad=None, w_pad=None): draw_if_interactive() +def tight_labels(label_fraction_x=0.5, label_fraction_y=0.3): + """ + """ + + fig = gcf() + fig.tight_labels(None, label_fraction_x, label_fraction_y) + draw_if_interactive() + + def box(on=None): """