Home > Blockchain >  Pass argument to __init__ method in python
Pass argument to __init__ method in python

Time:01-05

I would like to add a scalebar to a plot and use the following code:

import numpy as np
import matplotlib.pyplot as plt
from matplotlib.offsetbox import AnchoredOffsetbox

class AnchoredScaleBar(AnchoredOffsetbox):
    def __init__(self, transform, sizex=1, sizey=3, labelx='', labely='', loc=3,
             pad=0.1, borderpad=0.1, sep=1, 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, minimumdescent=False)
            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=False, matchy=False, hidex=False, hidey=False, **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

Example data:

x = np.arange(10)
y = 3*x

#plot data
fig1, ax1 = plt.subplots()
ax1.set_xlabel('x')
ax1.set_ylabel('y')
ax1.plot(x,y)

Add scalebar with sizex=1, sizey=10:

AnchoredScaleBar(ax1.transData, sizex=1,sizey =10)

sb = add_scalebar(ax1, matchx=False, matchy = False)
ax1.add_artist(sb)

Plotted data scalebar

A scalebar is now added to the plot but instead of having a size of sizex=1, sizey=10 it adds a scalebar with the default size of sizex=1, sizey=3 as specified in the init function header.

However, the size of the scalebar changes when specifying sizex=1, sizey=10 in the init header.

????Is there a way to call AnchoredScaleBar and pass different sizex and sizey arguments without changing the values in the init header????

CodePudding user response:

You're not using the AnchoredScaleBar that you're initializing at the beginning of your snippet. You should rather do:

sb = add_scalebar(ax1, matchx=False, matchy=False, sizex=1, sizey=10)
ax1.add_artist(sb)

so that sizex and sizey are passed to AnchoredScaleBar through the kwargs

  •  Tags:  
  • Related