Hi again,

I found an example that implements something like I described:

http://matplotlib.sourceforge.net/examples/pylab_examples/anchored_artists.html?highlight=size%20bar

However, it did not allow to set arbitrary position. I modified the example to 
provide the anchor_to_bbox argument of AnchoredOffsetbox that allows to set the 
scale bars position in axes coordinates. The big gotcha is that you have to 
provide the loc argument to fix the that point should be adjusted to the 
coordinates (1 for upper right, 2 for upper left, see the docs of legend for 
all the codes). This is not clear in the documentation. 

In the example attached, I add two scalebars: vertical and horizontal that 
cross at the lower right corner.

Bartosz
from matplotlib.patches import Rectangle, Ellipse

from matplotlib.offsetbox import AnchoredOffsetbox, AuxTransformBox, VPacker,\
     TextArea, HPacker 

import matplotlib.pyplot as plt

class XSizeBar(AnchoredOffsetbox):
    def __init__(self, pos,  size, label, loc, ax=None,
                 pad=0.1, borderpad=0.1, sep=2, prop=None, frameon=True):
        """
        Draw a horizontal bar with the size in data coordinate of the give axes.
        A label will be drawn underneath (center-alinged).

        pad, borderpad in fraction of the legend font size (or prop)
        sep in points.
        """
        if not ax:
            ax = plt.gca()

        self.size_bar = AuxTransformBox(ax.transData)
        self.size_bar.add_artist(Rectangle((0,0), size, 0, fc="none"))

        self.txt_label = TextArea(label, minimumdescent=False)

        self._box = VPacker(children=[self.size_bar, self.txt_label],
                            align="center",
                            pad=0, sep=sep)

        AnchoredOffsetbox.__init__(self, loc, pad=pad, borderpad=borderpad,
                                   child=self._box,
                                   prop=prop,
                                   bbox_to_anchor=pos,
                                   bbox_transform=ax.transAxes,
                                   frameon=frameon)

class YSizeBar(AnchoredOffsetbox):
    def __init__(self, pos,  size, label, loc, ax=None,
                 pad=0.1, borderpad=0.1, sep=2, prop=None, frameon=True):
        if not ax:
            ax = plt.gca()

        self.size_bar = AuxTransformBox(ax.transData)
        self.size_bar.add_artist(Rectangle((0,0), 0, size, fc="none"))

        self.txt_label = TextArea(label, minimumdescent=False)

        self._box = HPacker(children=[self.size_bar, self.txt_label],
                            align="center",
                            pad=0, sep=sep)

        AnchoredOffsetbox.__init__(self, loc, pad=pad, borderpad=borderpad,
                                   child=self._box,
                                   prop=prop,
                                   bbox_to_anchor=pos,
                                   bbox_transform=ax.transAxes,
                                   frameon=frameon)


if __name__ == "__main__":


    ax = plt.gca()
    ax.set_aspect(1.)

    # draw a horizontal bar with length of 0.1 in Data coordinate
    # (ax.transData) with a label underneath.
    x_asb =  XSizeBar((0.9,0.1),
                          0.1,
                          r"1 s",
                          loc=1,
                          pad=0., borderpad=0., sep=5,
                          frameon=False)
    
    y_asb =  YSizeBar((0.9,0.1),
                          0.1,
                          r"1 V",
                          loc=3,
                          pad=0., borderpad=0., sep=5,
                          frameon=False)
    ax.add_artist(x_asb)
    ax.add_artist(y_asb)

    plt.draw()
    plt.show()




On 21.02.2012, at 11:53, Bartosz Telenczuk wrote:

> Hi all,
> 
> I am trying to add to the axes a sizebar (a line of length specified in data 
> coordinates) at a fixed location relative to the axes (in axes coordinates). 
> The idea is that I have several subplots with different scales and I want to 
> add scalebar at the same position to each of them.
> 
> I tried using ScaledTranslation transformation, but with no success (after 
> export to SVG the scalebars are gone). I thought that I might use OffsetBox 
> (the same that the legend is based on), but I have no idea how to use it.
> 
> Do you have any suggestions?
> 
> Thanks,
> 
> Bartosz
> ------------------------------------------------------------------------------
> Keep Your Developer Skills Current with LearnDevNow!
> The most comprehensive online learning library for Microsoft developers
> is just $99.99! Visual Studio, SharePoint, SQL - plus HTML5, CSS3, MVC3,
> Metro Style Apps, more. Free future releases when you subscribe now!
> http://p.sf.net/sfu/learndevnow-d2d
> _______________________________________________
> Matplotlib-users mailing list
> Matplotlib-users@lists.sourceforge.net
> https://lists.sourceforge.net/lists/listinfo/matplotlib-users

Bartosz Telenczuk

Institute for Theoretical Biology
Humboldt University of Berlin, Germany
Phone: +4930/2093-8838
Homepage: http://neuroscience.telenczuk.pl

------------------------------------------------------------------------------
Keep Your Developer Skills Current with LearnDevNow!
The most comprehensive online learning library for Microsoft developers
is just $99.99! Visual Studio, SharePoint, SQL - plus HTML5, CSS3, MVC3,
Metro Style Apps, more. Free future releases when you subscribe now!
http://p.sf.net/sfu/learndevnow-d2d
_______________________________________________
Matplotlib-users mailing list
Matplotlib-users@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/matplotlib-users

Reply via email to