Esempio n. 1
0
def xy_data(xdata, ydata, eydata=None, exdata=None, label=None, xlabel='', ylabel='',               \
            title='', shell_history=1, xshift=0, yshift=0, xshift_every=1, yshift_every=1,        \
            coarsen=0, style=None,  clear=True, axes=None, xscale='linear', yscale='linear', grid=False,       \
            legend='best', legend_max=20, autoformat=True, tall=False, draw=True, **kwargs):
    """
    Plots specified data.

    xdata, ydata        Arrays (or arrays of arrays) of data to plot
    eydata, exdata      Arrays of x and y errorbar values
    label               string or array of strings for the line labels
    xlabel=''           label for the x-axis
    ylabel=''           label for the y-axis
    title=''            title for the axes; set to None to have nothing.
    shell_history=1     how many commands from the pyshell history to include
                        with the title
    xshift=0, yshift=0  progressive shifts on the data, to make waterfall plots
    xshift_every=1      perform the progressive shift every 1 or n'th line.
    yshift_every=1      perform the progressive shift every 1 or n'th line.
    style               style cycle object.
    clear=True          if no axes are specified, clear the figure, otherwise
                        clear just the axes.
    axes=None           which axes to use, or "gca" for the current axes
    xscale,yscale       'linear' by default. Set either to 'log' for log axes
    grid=False          Should we draw a grid on the axes?
    legend='best'       where to place the legend (see pylab.legend())
                        Set this to None to ignore the legend.
    legend_max=20       number of legend entries before it's truncated with '...'
    autoformat=True     Should we format the figure for printing?
    False               Should the format be tall?
    draw=True           whether or not to draw the plot after plotting


    **kwargs are sent to pylab.errorbar()
    """

    _pylab.ioff()

    # make sure everything is at least iterable.
    if not _fun.is_iterable(xdata): xdata = [xdata]
    if not _fun.is_iterable(exdata): exdata = [exdata]
    if not _fun.is_iterable(ydata): ydata = [ydata]
    if not _fun.is_iterable(eydata): eydata = [eydata]

    # make sure at least xdata and ydata are 2-D
    if _fun.is_a_number(xdata[0]): xdata = [xdata]
    if _fun.is_a_number(ydata[0]): ydata = [ydata]

    # make sure the number of data sets agrees
    N = max(len(xdata), len(ydata))
    for n in range(N - len(xdata)):
        xdata.append(xdata[0])
    for n in range(N - len(ydata)):
        ydata.append(ydata[0])
    for n in range(N - len(exdata)):
        exdata.append(exdata[0])
    for n in range(N - len(eydata)):
        eydata.append(eydata[0])

    # loop over each x and y data set, making sure None's are all converted
    # to counting arrays
    for n in range(N):

        # clean up the [None]'s
        if _fun.is_iterable(xdata[n]) and xdata[n][0] == None: xdata[n] = None
        if _fun.is_iterable(ydata[n]) and ydata[n][0] == None: ydata[n] = None

        if xdata[n] == None and ydata[n] == None:
            print "ERROR: " + str(n) + "'th data set is (None, None)."
            return

        if xdata[n] == None: xdata[n] = _n.arange(len(ydata[n]))
        if ydata[n] == None: ydata[n] = _n.arange(len(xdata[n]))

    # check that the labels is a list of strings of the same length
    if not _fun.is_iterable(label): label = [label] * N
    while len(label) < len(ydata):
        label.append(label[0])

    # concatenate if necessary
    if len(label) > legend_max:
        label[legend_max - 2] = '...'
        for n in range(legend_max - 1, len(label) - 1):
            label[n] = "_nolegend_"

    # clear the figure?
    if clear and not axes: _pylab.gcf().clear()  # axes cleared later

    # setup axes
    if axes == "gca" or axes == None: axes = _pylab.gca()

    # if we're clearing the axes
    if clear: axes.clear()

    # set the current axes
    _pylab.axes(axes)

    # now loop over the list of data in xdata and ydata
    for n in range(0, len(xdata)):
        # get the label
        if label: l = str(label[n])
        else: l = str(n)

        # calculate the x an y progressive shifts
        dx = xshift * (n / xshift_every)
        dy = yshift * (n / yshift_every)

        # if we're supposed to coarsen the data, do so.
        x = _fun.coarsen_array(xdata[n], coarsen)
        y = _fun.coarsen_array(ydata[n], coarsen)
        ey = _fun.coarsen_array(eydata[n], coarsen, 'quadrature')
        ex = _fun.coarsen_array(exdata[n], coarsen, 'quadrature')

        # update the style
        if not style == None: kwargs.update(style.next())
        axes.errorbar(x + dx, y + dy, label=l, yerr=ey, xerr=ex, **kwargs)

    _pylab.xscale(xscale)
    _pylab.yscale(yscale)
    if legend: axes.legend(loc=legend)
    axes.set_xlabel(xlabel)
    axes.set_ylabel(ylabel)

    # for some arguments there should be no title.
    if title in [None, False, 0]:
        axes.set_title('')

    # add the commands to the title
    else:
        title = str(title)
        history = _fun.get_shell_history()
        for n in range(0, min(shell_history, len(history))):
            title = title + "\n" + history[n].split('\n')[0].strip()

        title = title + '\nPlot created ' + _time.asctime()
        axes.set_title(title)

    if grid: _pylab.grid(True)

    if autoformat:
        _pt.format_figure(draw=False)
        _pt.auto_zoom(axes=axes, draw=False)

    # update the canvas
    if draw:
        _pylab.ion()
        _pylab.draw()
        _pylab.show()

    return axes
Esempio n. 2
0
def xy_data(xdata, ydata, eydata=None, exdata=None, label=None, xlabel='', ylabel='',               \
            title='', shell_history=1, xshift=0, yshift=0, xshift_every=1, yshift_every=1,        \
            coarsen=0, style=None,  clear=True, axes=None, xscale='linear', yscale='linear', grid=False,       \
            legend='best', legend_max=20, autoformat=True, tall=False, draw=True, **kwargs):
    """
    Plots specified data.

    xdata, ydata        Arrays (or arrays of arrays) of data to plot
    eydata, exdata      Arrays of x and y errorbar values
    label               string or array of strings for the line labels
    xlabel=''           label for the x-axis
    ylabel=''           label for the y-axis
    title=''            title for the axes; set to None to have nothing.
    shell_history=1     how many commands from the pyshell history to include
                        with the title
    xshift=0, yshift=0  progressive shifts on the data, to make waterfall plots
    xshift_every=1      perform the progressive shift every 1 or n'th line.
    yshift_every=1      perform the progressive shift every 1 or n'th line.
    style               style cycle object.
    clear=True          if no axes are specified, clear the figure, otherwise
                        clear just the axes.
    axes=None           which axes to use, or "gca" for the current axes
    xscale,yscale       'linear' by default. Set either to 'log' for log axes
    grid=False          Should we draw a grid on the axes?
    legend='best'       where to place the legend (see pylab.legend())
                        Set this to None to ignore the legend.
    legend_max=20       number of legend entries before it's truncated with '...'
    autoformat=True     Should we format the figure for printing?
    False               Should the format be tall?
    draw=True           whether or not to draw the plot after plotting


    **kwargs are sent to pylab.errorbar()
    """

    _pylab.ioff()

    # make sure everything is at least iterable.
    if not _fun.is_iterable(xdata):  xdata  = [xdata]
    if not _fun.is_iterable(exdata): exdata = [exdata]
    if not _fun.is_iterable(ydata):  ydata  = [ydata]
    if not _fun.is_iterable(eydata): eydata = [eydata]

    # make sure at least xdata and ydata are 2-D
    if _fun.is_a_number(xdata[0]): xdata = [xdata]
    if _fun.is_a_number(ydata[0]): ydata = [ydata]

    # make sure the number of data sets agrees
    N = max(len(xdata),len(ydata))
    for n in range(N-len( xdata)):  xdata.append( xdata[0])
    for n in range(N-len( ydata)):  ydata.append( ydata[0])
    for n in range(N-len(exdata)): exdata.append(exdata[0])
    for n in range(N-len(eydata)): eydata.append(eydata[0])

    # loop over each x and y data set, making sure None's are all converted
    # to counting arrays
    for n in range(N):

        # clean up the [None]'s
        if _fun.is_iterable(xdata[n]) and xdata[n][0] is None: xdata[n] = None
        if _fun.is_iterable(ydata[n]) and ydata[n][0] is None: ydata[n] = None

        if xdata[n] is None and ydata[n] is None:
            print "ERROR: "+str(n)+"'th data set is (None, None)."
            return

        if xdata[n] is None: xdata[n] = _n.arange(len(ydata[n]))
        if ydata[n] is None: ydata[n] = _n.arange(len(xdata[n]))

    # check that the labels is a list of strings of the same length
    if not _fun.is_iterable(label): label = [label]*N
    while len(label) < len(ydata):  label.append(label[0])

    # concatenate if necessary
    if len(label) > legend_max:
        label[legend_max-2] = '...'
        for n in range(legend_max-1,len(label)-1): label[n] = "_nolegend_"

    # clear the figure?
    if clear and not axes: _pylab.gcf().clear() # axes cleared later

    # setup axes
    if axes=="gca" or axes is None: axes = _pylab.gca()

    # if we're clearing the axes
    if clear: axes.clear()

    # set the current axes
    _pylab.axes(axes)

    # now loop over the list of data in xdata and ydata
    for n in range(0,len(xdata)):
        # get the label
        if label: l = str(label[n])
        else:     l = str(n)

        # calculate the x an y progressive shifts
        dx = xshift*(n/xshift_every)
        dy = yshift*(n/yshift_every)
        
        # if we're supposed to coarsen the data, do so.
        x  = _fun.coarsen_array(xdata[n],  coarsen)
        y  = _fun.coarsen_array(ydata[n],  coarsen)
        ey = _fun.coarsen_array(eydata[n], coarsen, 'quadrature')
        ex = _fun.coarsen_array(exdata[n], coarsen, 'quadrature')

        # update the style
        if not style is None: kwargs.update(style.next())
        axes.errorbar(x+dx, y+dy, label=l, yerr=ey, xerr=ex, **kwargs)

    _pylab.xscale(xscale)
    _pylab.yscale(yscale)
    if legend: axes.legend(loc=legend)
    axes.set_xlabel(xlabel)
    axes.set_ylabel(ylabel)

    # for some arguments there should be no title.
    if title in [None, False, 0]:
        axes.set_title('')

    # add the commands to the title
    else:
        title = str(title)
        history = _fun.get_shell_history()
        for n in range(0, min(shell_history, len(history))):
            title = title + "\n" + history[n].split('\n')[0].strip()

        title = title + '\nPlot created ' + _time.asctime()
        axes.set_title(title)

    if grid: _pylab.grid(True)

    if autoformat:
        _pt.format_figure(draw=False)
        _pt.auto_zoom(axes=axes, draw=False)

    # update the canvas
    if draw:
        _pylab.ion()
        _pylab.draw()
        _pylab.show()

    return axes
Esempio n. 3
0
def xy_data(xdata, ydata, eydata=None, exdata=None, label=None, xlabel='', ylabel='',               \
            title='', shell_history=0, xshift=0, yshift=0, xshift_every=1, yshift_every=1,        \
            coarsen=0, style=None,  clear=True, axes=None, xscale='linear', yscale='linear', grid=False,       \
            legend='best', legend_max=20, autoformat=True, autoformat_window=True, tall=False, draw=True, **kwargs):
    """
    Plots specified data.

    Parameters
    ----------
    xdata, ydata        
        Arrays (or arrays of arrays) of data to plot
    eydata=None, exdata=None     
        Arrays of x and y errorbar values
    label=None         
        String or array of strings for the line labels
    xlabel=''           
        Label for the x-axis
    ylabel=''           
        Label for the y-axis
    title=''            
        Title for the axes; set to None to have nothing.
    shell_history=0     
        How many commands from the pyshell history to include with the title
    xshift=0, yshift=0  
        Progressive shifts on the data, to make waterfall plots
    xshift_every=1      
        Perform the progressive shift every 1 or n'th line.
    yshift_every=1      
        perform the progressive shift every 1 or n'th line.
    style=None            
        style cycle object.
    clear=True          
        If no axes are specified (see below), clear the figure, otherwise clear just the axes.
    axes=None           
        Which matplotlib axes to use, or "gca" for the current axes
    xscale='linear', yscale='linear'      
        'linear' or 'log' x and y axis scales.
    grid=False          
        Should we draw a grid on the axes?
    legend='best'       
        Where to place the legend (see pylab.legend() for options)
        Set this to None to ignore the legend.
    legend_max=20
        Number of legend entries before it's truncated with '...'
    autoformat=True     
        Should we format the figure for printing?
    autoformat_window=True
        Should we resize and reposition the window when autoformatting?
    tall=False               
        Should the format be tall?
    draw=True           
        Whether or not to draw the plot after plotting.

    See matplotlib's errorbar() function for additional optional keyword arguments.
    """
    _pylab.ioff()

    # Make sure the dimensionality of the data sets matches
    xdata, ydata = _match_data_sets(xdata, ydata)
    exdata = _match_error_to_data_set(xdata, exdata)
    eydata = _match_error_to_data_set(ydata, eydata)

    # check that the labels is a list of strings of the same length
    if not _fun.is_iterable(label): label = [label] * len(xdata)
    while len(label) < len(ydata):
        label.append(label[0])

    # concatenate if necessary
    if len(label) > legend_max:
        label[legend_max - 2] = '...'
        for n in range(legend_max - 1, len(label) - 1):
            label[n] = "_nolegend_"

    # clear the figure?
    if clear and not axes: _pylab.gcf().clear()  # axes cleared later

    # setup axes
    if axes == "gca" or axes is None: axes = _pylab.gca()

    # if we're clearing the axes
    if clear: axes.clear()

    # set the current axes
    _pylab.axes(axes)

    # now loop over the list of data in xdata and ydata
    for n in range(0, len(xdata)):
        # get the label
        l = str(n) + ": " + str(label[n])

        # calculate the x an y progressive shifts
        dx = xshift * (n / xshift_every)
        dy = yshift * (n / yshift_every)

        # if we're supposed to coarsen the data, do so.
        x = _fun.coarsen_array(xdata[n], coarsen)
        y = _fun.coarsen_array(ydata[n], coarsen)
        ey = _fun.coarsen_array(eydata[n], coarsen, 'quadrature')
        ex = _fun.coarsen_array(exdata[n], coarsen, 'quadrature')

        # update the style
        if not style is None: kwargs.update(next(style))
        axes.errorbar(x + dx, y + dy, label=l, yerr=ey, xerr=ex, **kwargs)

    _pylab.xscale(xscale)
    _pylab.yscale(yscale)
    if legend: axes.legend(loc=legend)
    axes.set_xlabel(xlabel)
    axes.set_ylabel(ylabel)

    # for some arguments there should be no title.
    if title in [None, False, 0]:
        axes.set_title('')

    # add the commands to the title
    else:
        title = str(title)
        history = _fun.get_shell_history()
        for n in range(0, min(shell_history, len(history))):
            title = title + "\n" + history[n].split('\n')[0].strip()

        title = title + '\nPlot created ' + _time.asctime()
        axes.set_title(title)

    if grid: _pylab.grid(True)

    if autoformat:
        _pt.format_figure(draw=False, modify_geometry=autoformat_window)
        _pt.auto_zoom(axes=axes, draw=False)

    # update the canvas
    if draw:
        _pylab.ion()
        _pylab.draw()
        _pylab.show()

    return axes
Esempio n. 4
0
    def get_XYZ(self, xaxis=None, yaxis=None, xlabel=None, ylabel=None, xcoarsen=0, ycoarsen=0):

        """
        This will assemble the X, Y, Z data for a 2d colorplot or surface.

        yaxis=None          What values to use for the y-axis data. "first" means take the first column
                            yaxis=None means just use bin number
        xaxis=None          What values to use for the x-axis data, can be a header array
                            xaxis="first" means pop off the first row of the data
        xcoarsen, ycoarsen  How much to coarsen the columns or rows

        """


        # next we assemble the 2-d array for the colorplot
        Z=[]
        for c in self.ckeys:
            # transform so the image plotting has the same orientation as the data
            # in the file itself.
            col = list(self.columns[c])
            col.reverse()
            Z.append(col)

        # initialize the axis labels
        X=[]
        for n in range(len(Z)): X.append(n)
        self.xlabel = "x-step number"

        Y=[]
        for n in range(len(Z[0])): Y.append(n)
        self.ylabel = "y-step number"
        Y.reverse()

        # now if we're supposed to, pop off the first column as Y labels
        if yaxis=="first":

            # just pop off the first column (Z columns are already reversed)
            Y = Z.pop(0)
            self.ylabel = "y-values"

            # pop the first element of the X-data
            X.pop(0)


        # otherwise, it's a column value
        elif not yaxis==None:
            Y = list(self.c(yaxis))
            Y.reverse()
            self.ylabel = yaxis



        # if we're supposed to, pop off the top row for the x-axis values
        if xaxis == "first":
            X = []
            for n in range(len(Z)):
                X.append(Z[n].pop(-1))

            self.xlabel = "x-values"

            # pop the first element of the Y-data
            Y.pop(-1)

        # otherwise, if we specified a row from the header, use that
        elif not xaxis==None:
            X = array(self.h(xaxis))

            # trim X down to the length of the Zd.ZX row
            X.resize(len(Z[:])-1)

            self.xlabel = xaxis



        # now if we're supposed to coarsen, do so (produces a numpy array)
        self.X = _fun.coarsen_array(X, xcoarsen)
        self.Y = _fun.coarsen_array(Y, ycoarsen)

        # Z has to be transposed to make the data file look like the plot
        self.Z = _fun.coarsen_matrix(Z, xcoarsen, ycoarsen).transpose()

        # if we specified labels, they trump everything
        if xlabel: self.xlabel = xlabel
        if ylabel: self.ylabel = ylabel

        return
Esempio n. 5
0
def xy_data(xdata, ydata, eydata=None, exdata=None, label=None, xlabel='', ylabel='',               \
            title='', shell_history=0, xshift=0, yshift=0, xshift_every=1, yshift_every=1,        \
            coarsen=0, style=None,  clear=True, axes=None, xscale='linear', yscale='linear', grid=False,       \
            legend='best', legend_max=20, autoformat=True, autoformat_window=True, tall=False, draw=True, **kwargs):
    """
    Plots specified data.

    Parameters
    ----------
    xdata, ydata        
        Arrays (or arrays of arrays) of data to plot
    eydata=None, exdata=None     
        Arrays of x and y errorbar values
    label=None         
        String or array of strings for the line labels
    xlabel=''           
        Label for the x-axis
    ylabel=''           
        Label for the y-axis
    title=''            
        Title for the axes; set to None to have nothing.
    shell_history=0     
        How many commands from the pyshell history to include with the title
    xshift=0, yshift=0  
        Progressive shifts on the data, to make waterfall plots
    xshift_every=1      
        Perform the progressive shift every 1 or n'th line.
    yshift_every=1      
        perform the progressive shift every 1 or n'th line.
    style=None            
        style cycle object.
    clear=True          
        If no axes are specified (see below), clear the figure, otherwise clear just the axes.
    axes=None           
        Which matplotlib axes to use, or "gca" for the current axes
    xscale='linear', yscale='linear'      
        'linear' or 'log' x and y axis scales.
    grid=False          
        Should we draw a grid on the axes?
    legend='best'       
        Where to place the legend (see pylab.legend() for options)
        Set this to None to ignore the legend.
    legend_max=20
        Number of legend entries before it's truncated with '...'
    autoformat=True     
        Should we format the figure for printing?
    autoformat_window=True
        Should we resize and reposition the window when autoformatting?
    tall=False               
        Should the format be tall?
    draw=True           
        Whether or not to draw the plot after plotting.

    See matplotlib's errorbar() function for additional optional keyword arguments.
    """
    _pylab.ioff()
    
    # Make sure the dimensionality of the data sets matches
    xdata, ydata = _match_data_sets(xdata, ydata)
    exdata = _match_error_to_data_set(xdata, exdata)
    eydata = _match_error_to_data_set(ydata, eydata)
    
    # check that the labels is a list of strings of the same length
    if not _fun.is_iterable(label): label = [label]*len(xdata)
    while len(label) < len(ydata):  label.append(label[0])
    
    # concatenate if necessary
    if len(label) > legend_max:
        label[legend_max-2] = '...'
        for n in range(legend_max-1,len(label)-1): label[n] = "_nolegend_"

    # clear the figure?
    if clear and not axes: _pylab.gcf().clear() # axes cleared later

    # setup axes
    if axes=="gca" or axes is None: axes = _pylab.gca()

    # if we're clearing the axes
    if clear: axes.clear()

    # set the current axes
    _pylab.axes(axes)

    # now loop over the list of data in xdata and ydata
    for n in range(0,len(xdata)):
        # get the label
        if label[n]=='_nolegend_':
            l = '_nolegend_'
        else:
            l = str(n)+": "+str(label[n])
        
        # calculate the x an y progressive shifts
        dx = xshift*(n/xshift_every)
        dy = yshift*(n/yshift_every)
        
        # if we're supposed to coarsen the data, do so.
        x  = _fun.coarsen_array(xdata[n],  coarsen)
        y  = _fun.coarsen_array(ydata[n],  coarsen)
        ey = _fun.coarsen_array(eydata[n], coarsen, 'quadrature')
        ex = _fun.coarsen_array(exdata[n], coarsen, 'quadrature')

        # update the style
        if not style is None: kwargs.update(next(style))
        axes.errorbar(x+dx, y+dy, label=l, yerr=ey, xerr=ex, **kwargs)

    _pylab.xscale(xscale)
    _pylab.yscale(yscale)
    if legend: axes.legend(loc=legend)
    axes.set_xlabel(xlabel)
    axes.set_ylabel(ylabel)

    # for some arguments there should be no title.
    if title in [None, False, 0]:
        axes.set_title('')

    # add the commands to the title
    else:
        title = str(title)
        history = _fun.get_shell_history()
        for n in range(0, min(shell_history, len(history))):
            title = title + "\n" + history[n].split('\n')[0].strip()

        title = title + '\nPlot created ' + _time.asctime()
        axes.set_title(title)

    if grid: _pylab.grid(True)

    if autoformat:
        _pt.format_figure(draw=False, modify_geometry=autoformat_window)
        _pt.auto_zoom(axes=axes, draw=False)

    # update the canvas
    if draw:
        _pylab.ion()
        _pylab.draw()
        _pylab.show()

    return axes
Esempio n. 6
0
    def get_XYZ(self,
                xaxis=None,
                yaxis=None,
                xlabel=None,
                ylabel=None,
                xcoarsen=0,
                ycoarsen=0):
        """
        This will assemble the X, Y, Z data for a 2d colorplot or surface.

        yaxis=None          What values to use for the y-axis data. "first" means take the first column
                            yaxis=None means just use bin number
        xaxis=None          What values to use for the x-axis data, can be a header array
                            xaxis="first" means pop off the first row of the data
        xcoarsen, ycoarsen  How much to coarsen the columns or rows

        """

        # next we assemble the 2-d array for the colorplot
        Z = []
        for c in self.ckeys:
            # transform so the image plotting has the same orientation as the data
            # in the file itself.
            col = list(self.columns[c])
            col.reverse()
            Z.append(col)

        # initialize the axis labels
        X = []
        for n in range(len(Z)):
            X.append(n)
        self.xlabel = "x-step number"

        Y = []
        for n in range(len(Z[0])):
            Y.append(n)
        self.ylabel = "y-step number"
        Y.reverse()

        # now if we're supposed to, pop off the first column as Y labels
        if yaxis == "first":

            # just pop off the first column (Z columns are already reversed)
            Y = Z.pop(0)
            self.ylabel = "y-values"

            # pop the first element of the X-data
            X.pop(0)

        # otherwise, it's a column value
        elif not yaxis == None:
            Y = list(self.c(yaxis))
            Y.reverse()
            self.ylabel = yaxis

        # if we're supposed to, pop off the top row for the x-axis values
        if xaxis == "first":
            X = []
            for n in range(len(Z)):
                X.append(Z[n].pop(-1))

            self.xlabel = "x-values"

            # pop the first element of the Y-data
            Y.pop(-1)

        # otherwise, if we specified a row from the header, use that
        elif not xaxis == None:
            X = array(self.h(xaxis))

            # trim X down to the length of the Zd.ZX row
            X.resize(len(Z[:]) - 1)

            self.xlabel = xaxis

        # now if we're supposed to coarsen, do so (produces a numpy array)
        self.X = _fun.coarsen_array(X, xcoarsen)
        self.Y = _fun.coarsen_array(Y, ycoarsen)

        # Z has to be transposed to make the data file look like the plot
        self.Z = _fun.coarsen_matrix(Z, xcoarsen, ycoarsen).transpose()

        # if we specified labels, they trump everything
        if xlabel: self.xlabel = xlabel
        if ylabel: self.ylabel = ylabel

        return