Created
January 31, 2012 01:40
-
-
Save tonysyu/1708133 to your computer and use it in GitHub Desktop.
Hacky attempt at automatically adjusting the number of tick labels
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
""" | |
Automatically adjust the number of ticklabels based on label width. | |
This is a hacky attempt at an auto tick locator and misses *many* use cases. | |
To test, stretch and shrink the x-axis. | |
""" | |
import numpy as np | |
import matplotlib.pyplot as plt | |
import matplotlib.ticker as mtick | |
import matplotlib.axis as maxis | |
class AutoLocator(mtick.MaxNLocator): | |
"""Tick locator that tries to be smart. | |
Parameters | |
---------- | |
nbins : int | |
Maximum number of bins---i.e., tick intervals. | |
steps : list of numbers | |
Allowable steps for lowest displayed digit. This is a sequence of | |
"nice" numbers starting with 1 and ending with 10. | |
""" | |
def __init__(self, nbins=9, steps=[1, 2, 5, 10], fontsize=None): | |
mtick.MaxNLocator.__init__(self, nbins=nbins, steps=steps) | |
if fontsize is None: | |
fontsize = plt.rcParams['font.size'] | |
self.fontsize = fontsize | |
self._nbins_cached = nbins | |
def bin_boundaries(self, vmin, vmax): | |
"""Return bin boundaries (a.k.a. tick locations).""" | |
# The calculation of the label width should actually depend on the | |
# tick Formatter instance. | |
label_width = max(len('%g' % v) for v in (vmin, vmax)) | |
# This is only an approximate calculation of the label width | |
label_px_width = label_width * self.fontsize | |
w, h = self.axis.axes.figure.canvas.get_width_height() | |
if not isinstance(self.axis, maxis.XAxis): | |
raise NotImplementedError("Currently only XAxis is supported.") | |
# Use figure width to calculate the number of bins---only valid for x-axis. | |
# The following nbins calculation is approximate since it should vary | |
# with subplot parameters---i.e. padding on the left and right of | |
# subplots and multiple columns in a subplot grid. | |
self._nbins = min(self._nbins_cached, int(w / label_px_width)) | |
return mtick.MaxNLocator.bin_boundaries(self, vmin, vmax) | |
if __name__ == '__main__': | |
fig, ax = plt.subplots() | |
x = np.linspace(0, 7000000) | |
y = np.sin(x) | |
ax.plot(x, y) | |
ax.xaxis.set_major_locator(AutoLocator()) | |
plt.tight_layout() | |
plt.show() |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment