-
-
Save dmeliza/3251476 to your computer and use it in GitHub Desktop.
| # -*- coding: utf-8 -*- | |
| # -*- mode: python -*- | |
| # Adapted from mpl_toolkits.axes_grid1 | |
| # LICENSE: Python Software Foundation (http://docs.python.org/license.html) | |
| from matplotlib.offsetbox import AnchoredOffsetbox | |
| class AnchoredScaleBar(AnchoredOffsetbox): | |
| def __init__(self, transform, sizex=0, sizey=0, labelx=None, labely=None, loc=4, | |
| pad=0.1, borderpad=0.1, sep=2, prop=None, barcolor="black", barwidth=None, | |
| **kwargs): | |
| """ | |
| Draw a horizontal and/or vertical bar with the size in data coordinate | |
| of the give axes. A label will be drawn underneath (center-aligned). | |
| - transform : the coordinate frame (typically axes.transData) | |
| - sizex,sizey : width of x,y bar, in data units. 0 to omit | |
| - labelx,labely : labels for x,y bars; None to omit | |
| - loc : position in containing axes | |
| - pad, borderpad : padding, in fraction of the legend font size (or prop) | |
| - sep : separation between labels and bars in points. | |
| - **kwargs : additional arguments passed to base class constructor | |
| """ | |
| from matplotlib.patches import Rectangle | |
| from matplotlib.offsetbox import AuxTransformBox, VPacker, HPacker, TextArea, DrawingArea | |
| bars = AuxTransformBox(transform) | |
| if sizex: | |
| bars.add_artist(Rectangle((0,0), sizex, 0, ec=barcolor, lw=barwidth, fc="none")) | |
| if sizey: | |
| bars.add_artist(Rectangle((0,0), 0, sizey, ec=barcolor, lw=barwidth, fc="none")) | |
| if sizex and labelx: | |
| self.xlabel = TextArea(labelx) | |
| bars = VPacker(children=[bars, self.xlabel], align="center", pad=0, sep=sep) | |
| if sizey and labely: | |
| self.ylabel = TextArea(labely) | |
| bars = HPacker(children=[self.ylabel, bars], align="center", pad=0, sep=sep) | |
| AnchoredOffsetbox.__init__(self, loc, pad=pad, borderpad=borderpad, | |
| child=bars, prop=prop, frameon=False, **kwargs) | |
| def add_scalebar(ax, matchx=True, matchy=True, hidex=True, hidey=True, **kwargs): | |
| """ Add scalebars to axes | |
| Adds a set of scale bars to *ax*, matching the size to the ticks of the plot | |
| and optionally hiding the x and y axes | |
| - ax : the axis to attach ticks to | |
| - matchx,matchy : if True, set size of scale bars to spacing between ticks | |
| if False, size should be set using sizex and sizey params | |
| - hidex,hidey : if True, hide x-axis and y-axis of parent | |
| - **kwargs : additional arguments passed to AnchoredScaleBars | |
| Returns created scalebar object | |
| """ | |
| def f(axis): | |
| l = axis.get_majorticklocs() | |
| return len(l)>1 and (l[1] - l[0]) | |
| if matchx: | |
| kwargs['sizex'] = f(ax.xaxis) | |
| kwargs['labelx'] = str(kwargs['sizex']) | |
| if matchy: | |
| kwargs['sizey'] = f(ax.yaxis) | |
| kwargs['labely'] = str(kwargs['sizey']) | |
| sb = AnchoredScaleBar(ax.transData, **kwargs) | |
| ax.add_artist(sb) | |
| if hidex : ax.xaxis.set_visible(False) | |
| if hidey : ax.yaxis.set_visible(False) | |
| if hidex and hidey: ax.set_frame_on(False) | |
| return sb |
I agree! :)
Thanks
Thanks for this, I've used it for a few months now. It looks like it is adapted from AnchoredSizeBar ( in mpl_toolkits.axes_grid1.anchored_artists). That one can only make a horizontal bar, this one can make both horizontal and vertical bars.
Is axes_grid2 a real thing, or is that a typo of axes_grid1?
Glad it's been of use! axes_grid2 is a typo; thanks for catching it.
The last revision should fix issues with the bars not displaying in recent versions of matplotlib. Plus now you can customize color and width
Hi @dmeliza thank you for sharing this -- it's helpful!
Not sure if you're updating this but thought I'd let you know that minimumdescent (like in line 32) is now deprecated:
https://matplotlib.org/stable/api/api_changes.html#minimumdescent-parameter-property-of-textarea
Looks like it won't affect this since you set it to False anyway, but removing the parameter avoids a warning.
Thanks! Have not been using this myself any more, but appreciate the fix should I need to dust off my matplotlib skillz. Removed the offending parameter.
Excellent, thanks!
Amazing! Thanks, @dmeliza!
AWESOME! Thanks a lot!
This is awesome.