def addSettings(klass, s): """Construct list of settings.""" GenericPlotter.addSettings(s) # get rid of default key setting s.remove('key') s.add( setting.Strings('keys', ('',), descr=_('Key text for each dataset'), usertext=_('Key text')), 0) s.add( setting.DatasetOrStr('labels', '', descr=_('Dataset or string to label bars'), usertext=_('Labels'), datatype='text'), 5 ) s.add( setting.Choice('mode', ('grouped', 'stacked', 'stacked-area'), 'grouped', descr=_('Show datasets grouped ' 'together or as a single bar'), usertext=_('Mode')), 0) s.add( setting.Choice('direction', ('horizontal', 'vertical'), 'vertical', descr = _('Horizontal or vertical bar chart'), usertext=_('Direction')), 0 ) s.add( setting.Dataset('posn', '', descr = _('Dataset containing position of bars' ' (optional)'), usertext=_('Positions')), 0 ) s.add( setting.Datasets('lengths', ('y',), descr = _('Datasets containing lengths of bars'), usertext=_('Lengths')), 0 ) s.add( setting.Float('barfill', 0.75, minval = 0., maxval = 1., descr = _('Filling fraction of bars' ' (between 0 and 1)'), usertext=_('Bar fill'), formatting=True) ) s.add( setting.Float('groupfill', 0.9, minval = 0., maxval = 1., descr = _('Filling fraction of groups of bars' ' (between 0 and 1)'), usertext=_('Group fill'), formatting=True) ) s.add( setting.Choice('errorstyle', ('none', 'bar', 'barends'), 'bar', descr=_('Error bar style to show'), usertext=_('Error style'), formatting=True) ) s.add(BarFill('BarFill', descr=_('Bar fill'), usertext=_('Fill')), pixmap = 'settings_bgfill') s.add(BarLine('BarLine', descr=_('Bar line'), usertext=_('Line')), pixmap = 'settings_border') s.add( setting.ErrorBarLine('ErrorBarLine', descr = _('Error bar line settings'), usertext = _('Error bar line')), pixmap = 'settings_ploterrorline' )
def __init__(self, parent, name=None): """Initialise XY plotter plotting (xdata, ydata). xdata and ydata are strings specifying the data in the document""" GenericPlotter.__init__(self, parent, name=name) if type(self) == PointPlotter: self.readDefaults()
def __init__(self, parent, name=None): """Initialise plotter.""" GenericPlotter.__init__(self, parent, name=name) if type(self) == FunctionPlotter: self.readDefaults() self.checker = FunctionChecker()
def addSettings(klass, s): """Construct list of settings.""" GenericPlotter.addSettings(s) s.add( setting.Int('steps', 50, minval=3, descr=_('Number of steps to evaluate the function' ' over'), usertext=_('Steps'), formatting=True), 0) s.add( setting.Choice('variable', ['x', 'y'], 'x', descr=_('Variable the function is a function of'), usertext=_('Variable')), 0) s.add( setting.Str('function', 'x', descr=_('Function expression'), usertext=_('Function')), 0) s.add( setting.FloatOrAuto( 'min', 'Auto', descr=_('Minimum value at which to plot function'), usertext=_('Min'))) s.add( setting.FloatOrAuto( 'max', 'Auto', descr=_('Maximum value at which to plot function'), usertext=_('Max'))) s.add(setting.Line('Line', descr=_('Function line settings'), usertext=_('Plot line')), pixmap='settings_plotline') s.add(setting.PlotterFill('FillBelow', descr=_('Fill below function'), usertext=_('Fill below')), pixmap='settings_plotfillbelow') s.add(setting.PlotterFill('FillAbove', descr=_('Fill above function'), usertext=_('Fill above')), pixmap='settings_plotfillabove')
def draw(self, parentposn, phelper, outerbounds=None): """Plot the data on a plotter.""" widgetposn = GenericPlotter.draw(self, parentposn, phelper, outerbounds=outerbounds) s = self.settings # exit if hidden if s.hide: return # get data doc = self.document positions = s.get('posn').getData(doc) lengths = s.get('lengths').getData(doc) if not lengths: return # get axes widgets axes = self.parent.getAxes( (s.xAxis, s.yAxis) ) # return if there are no proper axes if ( None in axes or axes[0].settings.direction != 'horizontal' or axes[1].settings.direction != 'vertical' ): return # where the bars are to be placed horizontally barposns, maxwidth = self.findBarPositions(lengths, positions, axes, widgetposn) # only use finite positions origposnlen = len(barposns) validposn = N.isfinite(barposns) barposns = barposns[validposn] # this is a bit rubbish - we take the datasets and # make sure they have the same lengths as posns and remove NaNs # Datasets are stored as dicts dsvals = [] for dataset in lengths: vals = {} for key in ('data', 'serr', 'nerr', 'perr'): v = getattr(dataset, key) if v is not None: vals[key] = extend1DArray(N.nan_to_num(v), origposnlen)[validposn] dsvals.append(vals) # clip data within bounds of plotter clip = self.clipAxesBounds(axes, widgetposn) painter = phelper.painter(self, widgetposn, clip=clip) # actually do the drawing fn = {'stacked': self.barDrawStacked, 'stacked-area': self.areaDrawStacked, 'grouped': self.barDrawGroup}[s.mode] fn(painter, barposns, maxwidth, dsvals, axes, widgetposn, clip)
def draw(self, parentposn, painthelper, outerbounds = None): """Draw the function.""" posn = GenericPlotter.draw(self, parentposn, painthelper, outerbounds = outerbounds) x1, y1, x2, y2 = posn s = self.settings # exit if hidden or function blank if s.hide or s.function.strip() == '': return # get axes widgets axes = self.parent.getAxes( (s.xAxis, s.yAxis) ) # return if there's no proper axes if ( None in axes or axes[0].settings.direction != 'horizontal' or axes[1].settings.direction != 'vertical' ): return # clip data within bounds of plotter cliprect = self.clipAxesBounds(axes, posn) painter = painthelper.painter(self, posn, clip=cliprect) # get the points to plot by evaluating the function (xpts, ypts), (pxpts, pypts) = self.calcFunctionPoints(axes, posn) # draw the function line if pxpts is None or pypts is None: # not sure how to deal with errors here painter.setPen( setting.settingdb.color('error') ) f = qt4.QFont() f.setPointSize(20) painter.setFont(f) painter.drawText( qt4.QRectF(x1, y1, x2-x1, y2-y1), qt4.Qt.AlignCenter, "Cannot evaluate '%s'" % s.function ) else: if not s.FillBelow.hide: painter.setBrush( s.FillBelow.makeQBrush() ) painter.setPen( qt4.QPen(qt4.Qt.NoPen) ) self._fillRegion(painter, pxpts, pypts, posn, True, cliprect) if not s.FillAbove.hide: painter.setBrush( s.FillAbove.makeQBrush() ) painter.setPen( qt4.QPen(qt4.Qt.NoPen) ) self._fillRegion(painter, pxpts, pypts, posn, False, cliprect) if not s.Line.hide: painter.setBrush( qt4.QBrush() ) painter.setPen( s.Line.makeQPen(painter) ) self._plotLine(painter, pxpts, pypts, posn, cliprect)
def addSettings(klass, s): """Construct list of settings.""" GenericPlotter.addSettings(s) s.add( setting.Int('steps', 50, minval = 3, descr = _('Number of steps to evaluate the function' ' over'), usertext=_('Steps'), formatting=True), 0 ) s.add( setting.Choice('variable', ['x', 'y'], 'x', descr=_('Variable the function is a function of'), usertext=_('Variable')), 0 ) s.add( setting.Str('function', 'x', descr=_('Function expression'), usertext=_('Function')), 0 ) s.add(setting.FloatOrAuto('min', 'Auto', descr=_('Minimum value at which to plot function'), usertext=_('Min'))) s.add(setting.FloatOrAuto('max', 'Auto', descr=_('Maximum value at which to plot function'), usertext=_('Max'))) s.add( setting.Line('Line', descr = _('Function line settings'), usertext = _('Plot line')), pixmap = 'settings_plotline' ) s.add( setting.PlotterFill('FillBelow', descr = _('Fill below function'), usertext = _('Fill below')), pixmap = 'settings_plotfillbelow' ) s.add( setting.PlotterFill('FillAbove', descr = _('Fill above function'), usertext = _('Fill above')), pixmap = 'settings_plotfillabove' )
def draw(self, parentposn, painthelper, outerbounds=None): """Draw the function.""" posn = GenericPlotter.draw(self, parentposn, painthelper, outerbounds=outerbounds) x1, y1, x2, y2 = posn s = self.settings # exit if hidden or function blank if s.hide or s.function.strip() == '': return # get axes widgets axes = self.parent.getAxes((s.xAxis, s.yAxis)) # return if there's no proper axes if (None in axes or axes[0].settings.direction != 'horizontal' or axes[1].settings.direction != 'vertical'): return # clip data within bounds of plotter cliprect = self.clipAxesBounds(axes, posn) painter = painthelper.painter(self, posn, clip=cliprect) # get the points to plot by evaluating the function (xpts, ypts), (pxpts, pypts) = self.calcFunctionPoints(axes, posn) # draw the function line if pxpts is None or pypts is None: # not sure how to deal with errors here painter.setPen(setting.settingdb.color('error')) f = qt4.QFont() f.setPointSize(20) painter.setFont(f) painter.drawText(qt4.QRectF(x1, y1, x2 - x1, y2 - y1), qt4.Qt.AlignCenter, "Cannot evaluate '%s'" % s.function) else: if not s.FillBelow.hide: self._fillRegion(painter, pxpts, pypts, posn, True, cliprect, s.FillBelow) if not s.FillAbove.hide: self._fillRegion(painter, pxpts, pypts, posn, False, cliprect, s.FillAbove) if not s.Line.hide: painter.setBrush(qt4.QBrush()) painter.setPen(s.Line.makeQPen(painter)) self._plotLine(painter, pxpts, pypts, posn, cliprect)
def draw(self, parentposn, phelper, outerbounds=None): """Plot the data on a plotter.""" widgetposn = GenericPlotter.draw(self, parentposn, phelper, outerbounds=outerbounds) s = self.settings # exit if hidden if s.hide: return # get data doc = self.document positions = self.getPosns() if s.calculate: # calculate from data values = s.get('values').getData(doc) if values is None: return else: # use manual datasets datasets = [ s.get(x).getData(doc) for x in ('whiskermin', 'whiskermax', 'boxmin', 'boxmax', 'mean', 'median') ] if None in datasets: return # get axes widgets axes = self.parent.getAxes( (s.xAxis, s.yAxis) ) # return if there are no proper axes if ( None in axes or axes[0].settings.direction != 'horizontal' or axes[1].settings.direction != 'vertical' ): return clip = self.clipAxesBounds(axes, widgetposn) painter = phelper.painter(self, widgetposn, clip=clip) # get boxes visible along direction of boxes to work out width horz = (s.direction == 'horizontal') plotposns = axes[horz].dataToPlotterCoords(widgetposn, positions) if horz: inplot = (plotposns > widgetposn[1]) & (plotposns < widgetposn[3]) else: inplot = (plotposns > widgetposn[0]) & (plotposns < widgetposn[2]) inplotposn = plotposns[inplot] if inplotposn.shape[0] < 2: if horz: width = (widgetposn[3]-widgetposn[1])*0.5 else: width = (widgetposn[2]-widgetposn[0])*0.5 else: # use minimum different between points to get width inplotposn.sort() width = N.nanmin(inplotposn[1:] - inplotposn[:-1]) # adjust width width = width * s.fillfraction if s.calculate: # calculated boxes for vals, plotpos in izip(values, plotposns): stats = _Stats() stats.calculate(vals.data, s.whiskermode) self.plotBox(painter, axes, plotpos, widgetposn, width, clip, stats) else: # manually given boxes vals = [d.data for d in datasets] + [plotposns] lens = [len(d) for d in vals] for i in xrange(min(lens)): stats = _Stats() stats.topwhisker = vals[0][i] stats.botwhisker = vals[1][i] stats.botquart = vals[2][i] stats.topquart = vals[3][i] stats.mean = vals[4][i] stats.median = vals[5][i] stats.outliers = N.array([]) self.plotBox(painter, axes, vals[6][i], widgetposn, width, clip, stats)
def __init__(self, parent, name=None): """Initialise bar chart.""" GenericPlotter.__init__(self, parent, name=name) if type(self) == BarPlotter: self.readDefaults()
def __init__(self, parent, name=None): """Initialise box plot.""" GenericPlotter.__init__(self, parent, name=name) if type(self) == BoxPlot: self.readDefaults()
def addSettings(klass, s): """Construct list of settings.""" GenericPlotter.addSettings(s) s.remove('key') s.add( setting.Choice('whiskermode', ('min/max', '1.5IQR', '1 stddev', '9/91 percentile', '2/98 percentile'), '1.5IQR', descr = _('Whisker mode'), usertext=_('Whisker mode')), 0 ) s.add( setting.Choice('direction', ('horizontal', 'vertical'), 'vertical', descr = _('Horizontal or vertical boxes'), usertext=_('Direction')), 0 ) s.add( setting.DatasetOrStr('labels', '', descr=_('Dataset or string to label bars'), usertext=_('Labels'), datatype='text'), 0 ) s.add( setting.DatasetOrFloatList( 'posn', '', descr = _('Dataset or list of values giving ' 'positions of boxes (optional)'), usertext=_('Positions')), 0 ) # calculate statistics from these datasets s.add( setting.Datasets('values', ('data',), descr = _('Datasets containing values to ' 'calculate statistics for'), usertext=_('Datasets')), 0 ) # alternate mode where data are provided for boxes s.add( setting.DatasetOrFloatList( 'whiskermax', '', descr=_('Dataset with whisker maxima or list of values'), usertext=_('Whisker max')), 0 ) s.add( setting.DatasetOrFloatList( 'whiskermin', '', descr=_('Dataset with whisker minima or list of values'), usertext=_('Whisker min')), 0 ) s.add( setting.DatasetOrFloatList( 'boxmax', '', descr=_('Dataset with box maxima or list of values'), usertext=_('Box max')), 0 ) s.add( setting.DatasetOrFloatList( 'boxmin', '', descr=_('Dataset with box minima or list of values'), usertext=_('Box min')), 0 ) s.add( setting.DatasetOrFloatList( 'median', '', descr=_('Dataset with medians or list of values'), usertext=_('Median')), 0 ) s.add( setting.DatasetOrFloatList( 'mean', '', descr=_('Dataset with means or list of values'), usertext=_('Mean')), 0 ) # switch between different modes s.add( setting.BoolSwitch('calculate', True, descr = _('Calculate statistics from datasets' ' rather than given manually'), usertext = _('Calculate'), settingstrue=('whiskermode', 'values'), settingsfalse=('boxmin', 'whiskermin', 'boxmax', 'whiskermax', 'mean', 'median')), 0 ) # formatting options s.add( setting.Float('fillfraction', 0.75, descr = _('Fill fraction of boxes'), usertext=_('Fill fraction'), formatting=True) ) s.add( setting.Marker('outliersmarker', 'circle', descr = _('Marker for outliers'), usertext=_('Outliers'), formatting=True) ) s.add( setting.Marker('meanmarker', 'linecross', descr = _('Marker for mean'), usertext=_('Mean'), formatting=True) ) s.add( setting.DistancePt('markerSize', '3pt', descr = _('Size of markers to plot'), usertext=_('Markers size'), formatting=True) ) s.add( setting.GraphBrush( 'Fill', descr = _('Box fill'), usertext=_('Box fill')), pixmap='settings_bgfill' ) s.add( setting.Line('Border', descr = _('Box border line'), usertext=_('Box border')), pixmap='settings_border') s.add( setting.Line('Whisker', descr = _('Whisker line'), usertext=_('Whisker line')), pixmap='settings_whisker') s.add( setting.Line('MarkersLine', descr = _('Line around markers'), usertext = _('Markers border')), pixmap = 'settings_plotmarkerline' ) s.add( setting.BoxPlotMarkerFillBrush('MarkersFill', descr = _('Markers fill'), usertext = _('Markers fill')), pixmap = 'settings_plotmarkerfill' )
def draw(self, parentposn, phelper, outerbounds=None): """Plot the data on a plotter.""" posn = GenericPlotter.draw(self, parentposn, phelper, outerbounds=outerbounds) x1, y1, x2, y2 = posn s = self.settings # exit if hidden if s.hide: return # get data doc = self.document xv = s.get("xData").getData(doc) yv = s.get("yData").getData(doc) text = s.get("labels").getData(doc, checknull=True) scalepoints = s.get("scalePoints").getData(doc) if not xv or not yv: return # if text entered, then multiply up to get same number of values # as datapoints if text: length = min(len(xv.data), len(yv.data)) text = text * (length / len(text)) + text[: length % len(text)] # get axes widgets axes = self._fetchAxes() if not axes: return # clip data within bounds of plotter cliprect = self.clipAxesBounds(axes, posn) painter = phelper.painter(self, posn, clip=cliprect) # loop over chopped up values for xvals, yvals, tvals, ptvals in document.generateValidDatasetParts(xv, yv, text, scalepoints): # print "Calculating coordinates" # calc plotter coords of x and y points xplotter = axes[0].dataToPlotterCoords(posn, xvals.data) yplotter = axes[1].dataToPlotterCoords(posn, yvals.data) # print "Painting error bars" # plot errors bars self._plotErrors(posn, painter, xplotter, yplotter, axes, xvals, yvals, cliprect) # print "Painting plot line" # plot data line (and/or filling above or below) if not s.PlotLine.hide or not s.FillAbove.hide or not s.FillBelow.hide: if s.PlotLine.bezierJoin and hasqtloops: self._drawBezierLine(painter, xplotter, yplotter, posn, xvals, yvals) else: self._drawPlotLine(painter, xplotter, yplotter, posn, xvals, yvals, cliprect) # plot the points (we do this last so they are on top) markersize = s.get("markerSize").convert(painter) if not s.MarkerLine.hide or not s.MarkerFill.hide: # print "Painting marker fill" if not s.MarkerFill.hide: # filling for markers painter.setBrush(s.MarkerFill.makeQBrush()) else: # no-filling brush painter.setBrush(qt4.QBrush()) # print "Painting marker lines" if not s.MarkerLine.hide: # edges of markers painter.setPen(s.MarkerLine.makeQPen(painter)) else: # invisible pen painter.setPen(qt4.QPen(qt4.Qt.NoPen)) # thin datapoints as required if s.thinfactor <= 1: xplt, yplt = xplotter, yplotter else: xplt, yplt = (xplotter[:: s.thinfactor], yplotter[:: s.thinfactor]) # whether to scale markers scaling = None if ptvals: scaling = ptvals.data # actually plot datapoints utils.plotMarkers(painter, xplt, yplt, s.marker, markersize, scaling=scaling, clip=cliprect) # finally plot any labels if tvals and not s.Label.hide: self.drawLabels(painter, xplotter, yplotter, tvals, markersize)
def addSettings(klass, s): """Construct list of settings.""" GenericPlotter.addSettings(s) s.remove("key") s.add( setting.Choice( "whiskermode", ("min/max", "1.5IQR", "1 stddev", "9/91 percentile", "2/98 percentile"), "1.5IQR", descr="Whisker mode", usertext="Whisker mode", ), 0, ) s.add( setting.Choice( "direction", ("horizontal", "vertical"), "vertical", descr="Horizontal or vertical boxes", usertext="Direction", ), 0, ) s.add( setting.DatasetOrStr( "labels", "", descr="Dataset or string to label bars", usertext="Labels", datatype="text" ), 0, ) s.add( setting.DatasetOrFloatList( "posn", "", descr="Dataset or list of values giving " "positions of boxes (optional)", usertext="Positions", ), 0, ) # calculate statistics from these datasets s.add( setting.Datasets( "values", ("data",), descr="Datasets containing values to " "calculate statistics for", usertext="Datasets", ), 0, ) # alternate mode where data are provided for boxes s.add( setting.DatasetOrFloatList( "whiskermax", "", descr="Dataset with whisker maxima or list of values", usertext="Whisker max" ), 0, ) s.add( setting.DatasetOrFloatList( "whiskermin", "", descr="Dataset with whisker minima or list of values", usertext="Whisker min" ), 0, ) s.add( setting.DatasetOrFloatList( "boxmax", "", descr="Dataset with box maxima or list of values", usertext="Box max" ), 0, ) s.add( setting.DatasetOrFloatList( "boxmin", "", descr="Dataset with box minima or list of values", usertext="Box min" ), 0, ) s.add( setting.DatasetOrFloatList("median", "", descr="Dataset with medians or list of values", usertext="Median"), 0, ) s.add(setting.DatasetOrFloatList("mean", "", descr="Dataset with means or list of values", usertext="Mean"), 0) # switch between different modes s.add( setting.BoolSwitch( "calculate", True, descr="Calculate statistics from datasets" " rather than given manually", usertext="Calculate", settingstrue=("whiskermode", "values"), settingsfalse=("boxmin", "whiskermin", "boxmax", "whiskermax", "mean", "median"), ), 0, ) # formatting options s.add( setting.Float( "fillfraction", 0.75, descr="Fill fraction of boxes", usertext="Fill fraction", formatting=True ) ) s.add( setting.Marker( "outliersmarker", "circle", descr="Marker for outliers", usertext="Outliers", formatting=True ) ) s.add(setting.Marker("meanmarker", "linecross", descr="Marker for mean", usertext="Mean", formatting=True)) s.add( setting.DistancePt( "markerSize", "3pt", descr="Size of markers to plot", usertext="Markers size", formatting=True ) ) s.add(setting.GraphBrush("Fill", descr="Box fill", usertext="Box fill"), pixmap="settings_bgfill") s.add(setting.Line("Border", descr="Box border line", usertext="Box border"), pixmap="settings_border") s.add(setting.Line("Whisker", descr="Whisker line", usertext="Whisker line"), pixmap="settings_whisker") s.add( setting.Line("MarkersLine", descr="Line around markers", usertext="Markers border"), pixmap="settings_plotmarkerline", ) s.add( setting.GraphBrush("MarkersFill", descr="Markers fill", usertext="Markers fill"), pixmap="settings_plotmarkerfill", )
def addSettings(klass, s): """Construct list of settings.""" GenericPlotter.addSettings(s) # get rid of default key setting s.remove('key') s.add( setting.Strings('keys', ('', ), descr=_('Key text for each dataset'), usertext=_('Key text')), 0) s.add( setting.DatasetOrStr('labels', '', descr=_('Dataset or string to label bars'), usertext=_('Labels'), datatype='text'), 5) s.add( setting.Choice('mode', ('grouped', 'stacked', 'stacked-area'), 'grouped', descr=_('Show datasets grouped ' 'together or as a single bar'), usertext=_('Mode')), 0) s.add( setting.Choice('direction', ('horizontal', 'vertical'), 'vertical', descr=_('Horizontal or vertical bar chart'), usertext=_('Direction')), 0) s.add( setting.Dataset('posn', '', descr=_('Dataset containing position of bars' ' (optional)'), usertext=_('Positions')), 0) s.add( setting.Datasets('lengths', ('y', ), descr=_('Datasets containing lengths of bars'), usertext=_('Lengths')), 0) s.add( setting.Float('barfill', 0.75, minval=0., maxval=1., descr=_('Filling fraction of bars' ' (between 0 and 1)'), usertext=_('Bar fill'), formatting=True)) s.add( setting.Float('groupfill', 0.9, minval=0., maxval=1., descr=_('Filling fraction of groups of bars' ' (between 0 and 1)'), usertext=_('Group fill'), formatting=True)) s.add( setting.Choice('errorstyle', ('none', 'bar', 'barends'), 'bar', descr=_('Error bar style to show'), usertext=_('Error style'), formatting=True)) s.add(BarFill('BarFill', descr=_('Bar fill'), usertext=_('Fill')), pixmap='settings_bgfill') s.add(BarLine('BarLine', descr=_('Bar line'), usertext=_('Line')), pixmap='settings_border') s.add(setting.ErrorBarLine('ErrorBarLine', descr=_('Error bar line settings'), usertext=_('Error bar line')), pixmap='settings_ploterrorline')
def draw(self, parentposn, phelper, outerbounds=None): """Plot the data on a plotter.""" widgetposn = GenericPlotter.draw(self, parentposn, phelper, outerbounds=outerbounds) s = self.settings # exit if hidden if s.hide: return # get data doc = self.document positions = s.get('posn').getData(doc) lengths = s.get('lengths').getData(doc) if not lengths: return # get axes widgets axes = self.parent.getAxes((s.xAxis, s.yAxis)) # return if there are no proper axes if (None in axes or axes[0].settings.direction != 'horizontal' or axes[1].settings.direction != 'vertical'): return # where the bars are to be placed horizontally barposns, maxwidth = self.findBarPositions(lengths, positions, axes, widgetposn) # only use finite positions origposnlen = len(barposns) validposn = N.isfinite(barposns) barposns = barposns[validposn] # this is a bit rubbish - we take the datasets and # make sure they have the same lengths as posns and remove NaNs # Datasets are stored as dicts dsvals = [] for dataset in lengths: vals = {} for key in ('data', 'serr', 'nerr', 'perr'): v = getattr(dataset, key) if v is not None: vals[key] = extend1DArray(N.nan_to_num(v), origposnlen)[validposn] dsvals.append(vals) # clip data within bounds of plotter clip = self.clipAxesBounds(axes, widgetposn) painter = phelper.painter(self, widgetposn, clip=clip) # actually do the drawing fn = { 'stacked': self.barDrawStacked, 'stacked-area': self.areaDrawStacked, 'grouped': self.barDrawGroup }[s.mode] fn(painter, barposns, maxwidth, dsvals, axes, widgetposn, clip)
def addSettings(klass, s): """Construct list of settings.""" GenericPlotter.addSettings(s) s.add( setting.Int('thinfactor', 1, minval=1, descr=_('Thin number of markers plotted' ' for each datapoint by this factor'), usertext=_('Thin markers'), formatting=True), 0) s.add( setting.DistancePt('markerSize', '3pt', descr=_('Size of marker to plot'), usertext=_('Marker size'), formatting=True), 0) s.add( setting.Marker('marker', 'circle', descr=_('Type of marker to plot'), usertext=_('Marker'), formatting=True), 0) s.add( setting.DatasetOrStr('labels', '', descr=_('Dataset or string to label points'), usertext=_('Labels'), datatype='text'), 5) s.add( setting.DatasetOrFloatList( 'scalePoints', '', descr=_('Scale size of plotted markers by this dataset or' ' list of values'), usertext=_('Scale markers')), 6) s.add(ColorSettings('Color')) s.add( setting.DatasetOrFloatList( 'yData', 'y', descr=_('Dataset containing y data or list of values'), usertext=_('Y data')), 0) s.add( setting.DatasetOrFloatList( 'xData', 'x', descr=_('Dataset containing x data or list of values'), usertext=_('X data')), 0) s.add( setting.ErrorStyle('errorStyle', 'bar', descr=_('Style of error bars to plot'), usertext=_('Error style'), formatting=True)) s.add(setting.XYPlotLine('PlotLine', descr=_('Plot line settings'), usertext=_('Plot line')), pixmap='settings_plotline') s.add(setting.Line('MarkerLine', descr=_('Line around the marker settings'), usertext=_('Marker border')), pixmap='settings_plotmarkerline') s.add(MarkerFillBrush('MarkerFill', descr=_('Marker fill settings'), usertext=_('Marker fill')), pixmap='settings_plotmarkerfill') s.add(setting.ErrorBarLine('ErrorBarLine', descr=_('Error bar line settings'), usertext=_('Error bar line')), pixmap='settings_ploterrorline') s.add(setting.PointFill('FillBelow', descr=_('Fill below plot line'), usertext=_('Fill below')), pixmap='settings_plotfillbelow') s.add(setting.PointFill('FillAbove', descr=_('Fill above plot line'), usertext=_('Fill above')), pixmap='settings_plotfillabove') s.add(setting.PointLabel('Label', descr=_('Label settings'), usertext=_('Label')), pixmap='settings_axislabel')
def addSettings(klass, s): """Construct list of settings.""" GenericPlotter.addSettings(s) s.remove('key') s.add( setting.Choice('whiskermode', ('min/max', '1.5IQR', '1 stddev', '9/91 percentile', '2/98 percentile'), '1.5IQR', descr=_('Whisker mode'), usertext=_('Whisker mode')), 0) s.add( setting.Choice('direction', ('horizontal', 'vertical'), 'vertical', descr=_('Horizontal or vertical boxes'), usertext=_('Direction')), 0) s.add( setting.DatasetOrStr('labels', '', descr=_('Dataset or string to label bars'), usertext=_('Labels'), datatype='text'), 0) s.add( setting.DatasetOrFloatList('posn', '', descr=_( 'Dataset or list of values giving ' 'positions of boxes (optional)'), usertext=_('Positions')), 0) # calculate statistics from these datasets s.add( setting.Datasets('values', ('data', ), descr=_('Datasets containing values to ' 'calculate statistics for'), usertext=_('Datasets')), 0) # alternate mode where data are provided for boxes s.add( setting.DatasetOrFloatList( 'whiskermax', '', descr=_('Dataset with whisker maxima or list of values'), usertext=_('Whisker max')), 0) s.add( setting.DatasetOrFloatList( 'whiskermin', '', descr=_('Dataset with whisker minima or list of values'), usertext=_('Whisker min')), 0) s.add( setting.DatasetOrFloatList( 'boxmax', '', descr=_('Dataset with box maxima or list of values'), usertext=_('Box max')), 0) s.add( setting.DatasetOrFloatList( 'boxmin', '', descr=_('Dataset with box minima or list of values'), usertext=_('Box min')), 0) s.add( setting.DatasetOrFloatList( 'median', '', descr=_('Dataset with medians or list of values'), usertext=_('Median')), 0) s.add( setting.DatasetOrFloatList( 'mean', '', descr=_('Dataset with means or list of values'), usertext=_('Mean')), 0) # switch between different modes s.add( setting.BoolSwitch('calculate', True, descr=_('Calculate statistics from datasets' ' rather than given manually'), usertext=_('Calculate'), settingstrue=('whiskermode', 'values'), settingsfalse=('boxmin', 'whiskermin', 'boxmax', 'whiskermax', 'mean', 'median')), 0) # formatting options s.add( setting.Float('fillfraction', 0.75, descr=_('Fill fraction of boxes'), usertext=_('Fill fraction'), formatting=True)) s.add( setting.Marker('outliersmarker', 'circle', descr=_('Marker for outliers'), usertext=_('Outliers'), formatting=True)) s.add( setting.Marker('meanmarker', 'linecross', descr=_('Marker for mean'), usertext=_('Mean'), formatting=True)) s.add( setting.DistancePt('markerSize', '3pt', descr=_('Size of markers to plot'), usertext=_('Markers size'), formatting=True)) s.add(setting.GraphBrush('Fill', descr=_('Box fill'), usertext=_('Box fill')), pixmap='settings_bgfill') s.add(setting.Line('Border', descr=_('Box border line'), usertext=_('Box border')), pixmap='settings_border') s.add(setting.Line('Whisker', descr=_('Whisker line'), usertext=_('Whisker line')), pixmap='settings_whisker') s.add(setting.Line('MarkersLine', descr=_('Line around markers'), usertext=_('Markers border')), pixmap='settings_plotmarkerline') s.add(setting.BoxPlotMarkerFillBrush('MarkersFill', descr=_('Markers fill'), usertext=_('Markers fill')), pixmap='settings_plotmarkerfill')
def draw(self, parentposn, phelper, outerbounds=None): """Plot the data on a plotter.""" posn = GenericPlotter.draw(self, parentposn, phelper, outerbounds=outerbounds) x1, y1, x2, y2 = posn s = self.settings # exit if hidden if s.hide: return # get data doc = self.document xv = s.get('xData').getData(doc) yv = s.get('yData').getData(doc) text = s.get('labels').getData(doc, checknull=True) scalepoints = s.get('scalePoints').getData(doc) colorpoints = s.Color.get('points').getData(doc) # if a missing dataset, make a fake dataset for the second one # based on a row number if xv and not yv and s.get('yData').isEmpty(): # use index for y data length = xv.data.shape[0] yv = document.DatasetRange(length, (1,length)) elif yv and not xv and s.get('xData').isEmpty(): # use index for x data length = yv.data.shape[0] xv = document.DatasetRange(length, (1,length)) if not xv or not yv: # no valid dataset, so exit return # if text entered, then multiply up to get same number of values # as datapoints if text: length = min( len(xv.data), len(yv.data) ) text = text*(length / len(text)) + text[:length % len(text)] # get axes widgets axes = self._fetchAxes() if not axes: # no valid axes, so exit return # clip data within bounds of plotter cliprect = self.clipAxesBounds(axes, posn) painter = phelper.painter(self, posn, clip=cliprect) # loop over chopped up values for xvals, yvals, tvals, ptvals, cvals in ( document.generateValidDatasetParts( xv, yv, text, scalepoints, colorpoints)): #print "Calculating coordinates" # calc plotter coords of x and y points xplotter = axes[0].dataToPlotterCoords(posn, xvals.data) yplotter = axes[1].dataToPlotterCoords(posn, yvals.data) #print "Painting error bars" # plot errors bars self._plotErrors(posn, painter, xplotter, yplotter, axes, xvals, yvals, cliprect) #print "Painting plot line" # plot data line (and/or filling above or below) if not s.PlotLine.hide or not s.FillAbove.hide or not s.FillBelow.hide: if s.PlotLine.bezierJoin and hasqtloops: self._drawBezierLine( painter, xplotter, yplotter, posn, xvals, yvals ) else: self._drawPlotLine( painter, xplotter, yplotter, posn, xvals, yvals, cliprect ) # plot the points (we do this last so they are on top) markersize = s.get('markerSize').convert(painter) if not s.MarkerLine.hide or not s.MarkerFill.hide: #print "Painting marker fill" if not s.MarkerFill.hide: # filling for markers painter.setBrush( s.MarkerFill.makeQBrush() ) else: # no-filling brush painter.setBrush( qt4.QBrush() ) #print "Painting marker lines" if not s.MarkerLine.hide: # edges of markers painter.setPen( s.MarkerLine.makeQPen(painter) ) else: # invisible pen painter.setPen( qt4.QPen(qt4.Qt.NoPen) ) # thin datapoints as required if s.thinfactor <= 1: xplt, yplt = xplotter, yplotter else: xplt, yplt = (xplotter[::s.thinfactor], yplotter[::s.thinfactor]) # whether to scale markers scaling = colorvals = cmap = None if ptvals: scaling = ptvals.data # color point individually if cvals: colorvals = utils.applyScaling( cvals.data, s.Color.scaling, s.Color.min, s.Color.max) cmap = self.document.getColormap( s.MarkerFill.colorMap, s.MarkerFill.colorMapInvert) # actually plot datapoints utils.plotMarkers(painter, xplt, yplt, s.marker, markersize, scaling=scaling, clip=cliprect, cmap=cmap, colorvals=colorvals) # finally plot any labels if tvals and not s.Label.hide: self.drawLabels(painter, xplotter, yplotter, tvals, markersize)
def addSettings(klass, s): """Construct list of settings.""" GenericPlotter.addSettings(s) s.add( setting.Int('thinfactor', 1, minval=1, descr=_('Thin number of markers plotted' ' for each datapoint by this factor'), usertext=_('Thin markers'), formatting=True), 0 ) s.add( setting.DistancePt('markerSize', '3pt', descr = _('Size of marker to plot'), usertext=_('Marker size'), formatting=True), 0 ) s.add( setting.Marker('marker', 'circle', descr = _('Type of marker to plot'), usertext=_('Marker'), formatting=True), 0 ) s.add( setting.DatasetOrStr('labels', '', descr=_('Dataset or string to label points'), usertext=_('Labels'), datatype='text'), 5 ) s.add( setting.DatasetOrFloatList( 'scalePoints', '', descr = _('Scale size of plotted markers by this dataset or' ' list of values'), usertext=_('Scale markers')), 6 ) s.add( ColorSettings('Color') ) s.add( setting.DatasetOrFloatList( 'yData', 'y', descr=_('Dataset containing y data or list of values'), usertext=_('Y data')), 0 ) s.add( setting.DatasetOrFloatList( 'xData', 'x', descr=_('Dataset containing x data or list of values'), usertext=_('X data')), 0 ) s.add( setting.ErrorStyle('errorStyle', 'bar', descr=_('Style of error bars to plot'), usertext=_('Error style'), formatting=True) ) s.add( setting.XYPlotLine('PlotLine', descr = _('Plot line settings'), usertext = _('Plot line')), pixmap = 'settings_plotline' ) s.add( setting.Line('MarkerLine', descr = _('Line around the marker settings'), usertext = _('Marker border')), pixmap = 'settings_plotmarkerline' ) s.add( MarkerFillBrush('MarkerFill', descr = _('Marker fill settings'), usertext = _('Marker fill')), pixmap = 'settings_plotmarkerfill' ) s.add( setting.ErrorBarLine('ErrorBarLine', descr = _('Error bar line settings'), usertext = _('Error bar line')), pixmap = 'settings_ploterrorline' ) s.add( setting.PointFill('FillBelow', descr = _('Fill below plot line'), usertext = _('Fill below')), pixmap = 'settings_plotfillbelow' ) s.add( setting.PointFill('FillAbove', descr = _('Fill above plot line'), usertext = _('Fill above')), pixmap = 'settings_plotfillabove' ) s.add( setting.PointLabel('Label', descr = _('Label settings'), usertext=_('Label')), pixmap = 'settings_axislabel' )
def draw(self, parentposn, phelper, outerbounds=None): """Plot the data on a plotter.""" widgetposn = GenericPlotter.draw(self, parentposn, phelper, outerbounds=outerbounds) s = self.settings # exit if hidden if s.hide: return # get data doc = self.document positions = self.getPosns() if s.calculate: # calculate from data values = s.get('values').getData(doc) if values is None: return else: # use manual datasets datasets = [ s.get(x).getData(doc) for x in ('whiskermin', 'whiskermax', 'boxmin', 'boxmax', 'mean', 'median') ] if None in datasets: return # get axes widgets axes = self.parent.getAxes((s.xAxis, s.yAxis)) # return if there are no proper axes if (None in axes or axes[0].settings.direction != 'horizontal' or axes[1].settings.direction != 'vertical'): return clip = self.clipAxesBounds(axes, widgetposn) painter = phelper.painter(self, widgetposn, clip=clip) # get boxes visible along direction of boxes to work out width horz = (s.direction == 'horizontal') plotposns = axes[horz].dataToPlotterCoords(widgetposn, positions) if horz: inplot = (plotposns > widgetposn[1]) & (plotposns < widgetposn[3]) else: inplot = (plotposns > widgetposn[0]) & (plotposns < widgetposn[2]) inplotposn = plotposns[inplot] if inplotposn.shape[0] < 2: if horz: width = (widgetposn[3] - widgetposn[1]) * 0.5 else: width = (widgetposn[2] - widgetposn[0]) * 0.5 else: # use minimum different between points to get width inplotposn.sort() width = N.nanmin(inplotposn[1:] - inplotposn[:-1]) # adjust width width = width * s.fillfraction if s.calculate: # calculated boxes for vals, plotpos in izip(values, plotposns): stats = _Stats() stats.calculate(vals.data, s.whiskermode) self.plotBox(painter, axes, plotpos, widgetposn, width, clip, stats) else: # manually given boxes vals = [d.data for d in datasets] + [plotposns] lens = [len(d) for d in vals] for i in xrange(min(lens)): stats = _Stats() stats.topwhisker = vals[0][i] stats.botwhisker = vals[1][i] stats.botquart = vals[2][i] stats.topquart = vals[3][i] stats.mean = vals[4][i] stats.median = vals[5][i] stats.outliers = N.array([]) self.plotBox(painter, axes, vals[6][i], widgetposn, width, clip, stats)
def addSettings(klass, s): """Construct list of settings.""" GenericPlotter.addSettings(s) s.add( setting.Int( "thinfactor", 1, minval=1, descr="Thin number of markers plotted" " for each datapoint by this factor", usertext="Thin markers", formatting=True, ), 0, ) s.add( setting.DistancePt( "markerSize", "3pt", descr="Size of marker to plot", usertext="Marker size", formatting=True ), 0, ) s.add(setting.Marker("marker", "circle", descr="Type of marker to plot", usertext="Marker", formatting=True), 0) s.add( setting.DatasetOrStr( "labels", "", descr="Dataset or string to label points", usertext="Labels", datatype="text" ), 5, ) s.add( setting.DatasetOrFloatList( "scalePoints", "", descr="Scale size of plotted markers by this dataset or" " list of values", usertext="Scale markers", ), 6, ) s.add( setting.DatasetOrFloatList( "yData", "y", descr="Dataset containing y data or list of values", usertext="Y data" ), 0, ) s.add( setting.DatasetOrFloatList( "xData", "x", descr="Dataset containing x data or list of values", usertext="X data" ), 0, ) s.add( setting.ErrorStyle( "errorStyle", "bar", descr="Style of error bars to plot", usertext="Error style", formatting=True ) ) s.add( setting.XYPlotLine("PlotLine", descr="Plot line settings", usertext="Plot line"), pixmap="settings_plotline" ) s.add( setting.Line("MarkerLine", descr="Line around the marker settings", usertext="Marker border"), pixmap="settings_plotmarkerline", ) s.add( MarkerFillBrush("MarkerFill", descr="Marker fill settings", usertext="Marker fill"), pixmap="settings_plotmarkerfill", ) s.add( setting.ErrorBarLine("ErrorBarLine", descr="Error bar line settings", usertext="Error bar line"), pixmap="settings_ploterrorline", ) s.add( setting.PointFill("FillBelow", descr="Fill below plot line", usertext="Fill below"), pixmap="settings_plotfillbelow", ) s.add( setting.PointFill("FillAbove", descr="Fill above plot line", usertext="Fill above"), pixmap="settings_plotfillabove", ) s.add(setting.PointLabel("Label", descr="Label settings", usertext="Label"), pixmap="settings_axislabel")
def draw(self, parentposn, phelper, outerbounds=None): """Plot the data on a plotter.""" posn = GenericPlotter.draw(self, parentposn, phelper, outerbounds=outerbounds) x1, y1, x2, y2 = posn s = self.settings # exit if hidden if s.hide: return # get data doc = self.document xv = s.get('xData').getData(doc) yv = s.get('yData').getData(doc) text = s.get('labels').getData(doc, checknull=True) scalepoints = s.get('scalePoints').getData(doc) colorpoints = s.Color.get('points').getData(doc) # if a missing dataset, make a fake dataset for the second one # based on a row number if xv and not yv and s.get('yData').isEmpty(): # use index for y data length = xv.data.shape[0] yv = document.DatasetRange(length, (1, length)) elif yv and not xv and s.get('xData').isEmpty(): # use index for x data length = yv.data.shape[0] xv = document.DatasetRange(length, (1, length)) if not xv or not yv: # no valid dataset, so exit return # if text entered, then multiply up to get same number of values # as datapoints if text: length = min(len(xv.data), len(yv.data)) text = text * (length / len(text)) + text[:length % len(text)] # get axes widgets axes = self._fetchAxes() if not axes: # no valid axes, so exit return # clip data within bounds of plotter cliprect = self.clipAxesBounds(axes, posn) painter = phelper.painter(self, posn, clip=cliprect) # loop over chopped up values for xvals, yvals, tvals, ptvals, cvals in ( document.generateValidDatasetParts(xv, yv, text, scalepoints, colorpoints)): #print "Calculating coordinates" # calc plotter coords of x and y points xplotter = axes[0].dataToPlotterCoords(posn, xvals.data) yplotter = axes[1].dataToPlotterCoords(posn, yvals.data) #print "Painting plot line" # plot data line (and/or filling above or below) if not s.PlotLine.hide or not s.FillAbove.hide or not s.FillBelow.hide: if s.PlotLine.bezierJoin and hasqtloops: self._drawBezierLine(painter, xplotter, yplotter, posn, xvals, yvals) else: self._drawPlotLine(painter, xplotter, yplotter, posn, xvals, yvals, cliprect) # shift points if in certain step modes if s.PlotLine.steps != 'off': steps = s.PlotLine.steps if s.PlotLine.steps == 'right-shift-points': xplotter[1:] = 0.5 * (xplotter[:-1] + xplotter[1:]) elif s.PlotLine.steps == 'left-shift-points': xplotter[:-1] = 0.5 * (xplotter[:-1] + xplotter[1:]) #print "Painting error bars" # plot errors bars self._plotErrors(posn, painter, xplotter, yplotter, axes, xvals, yvals, cliprect) # plot the points (we do this last so they are on top) markersize = s.get('markerSize').convert(painter) if not s.MarkerLine.hide or not s.MarkerFill.hide: #print "Painting marker fill" if not s.MarkerFill.hide: # filling for markers painter.setBrush(s.MarkerFill.makeQBrush()) else: # no-filling brush painter.setBrush(qt4.QBrush()) #print "Painting marker lines" if not s.MarkerLine.hide: # edges of markers painter.setPen(s.MarkerLine.makeQPen(painter)) else: # invisible pen painter.setPen(qt4.QPen(qt4.Qt.NoPen)) # thin datapoints as required if s.thinfactor <= 1: xplt, yplt = xplotter, yplotter else: xplt, yplt = (xplotter[::s.thinfactor], yplotter[::s.thinfactor]) # whether to scale markers scaling = colorvals = cmap = None if ptvals: scaling = ptvals.data if s.thinfactor > 1: scaling = scaling[::s.thinfactor] # color point individually if cvals: colorvals = utils.applyScaling(cvals.data, s.Color.scaling, s.Color.min, s.Color.max) if s.thinfactor > 1: colorvals = colorvals[::s.thinfactor] cmap = self.document.getColormap( s.MarkerFill.colorMap, s.MarkerFill.colorMapInvert) # actually plot datapoints utils.plotMarkers(painter, xplt, yplt, s.marker, markersize, scaling=scaling, clip=cliprect, cmap=cmap, colorvals=colorvals) # finally plot any labels if tvals and not s.Label.hide: self.drawLabels(painter, xplotter, yplotter, tvals, markersize)
def addSettings(klass, s): """Construct list of settings.""" GenericPlotter.addSettings(s) s.add( setting.Int('thinfactor', 1, minval=1, descr=_('Thin number of markers plotted' ' for each datapoint by this factor'), usertext=_('Thin markers'), formatting=True), 0 ) s.add( setting.DistancePt('markerSize', '3pt', descr = _('Size of marker to plot'), usertext=_('Marker size'), formatting=True), 0 ) s.add( setting.Marker('marker', 'circle', descr = _('Type of marker to plot'), usertext=_('Marker'), formatting=True), 0 ) s.add( setting.DatasetOrStr('labels', '', descr=_('Dataset or string to label points'), usertext=_('Labels'), datatype='text'), 5 ) s.add( setting.DatasetOrFloatList( 'scalePoints', '', descr = _('Scale size of plotted markers by this dataset or' ' list of values'), usertext=_('Scale markers')), 6 ) s.add( ColorSettings('Color') ) s.add( setting.DatasetOrFloatList( 'yData', 'y', descr=_('Dataset containing y data or list of values'), usertext=_('Y data')), 0 ) s.add( setting.DatasetOrFloatList( 'xData', 'x', descr=_('Dataset containing x data or list of values'), usertext=_('X data')), 0 ) s.add( setting.ErrorStyle('errorStyle', 'bar', descr=_('Style of error bars to plot'), usertext=_('Error style'), formatting=True) ) s.add( setting.XYPlotLine('PlotLine', descr = _('Plot line settings'), usertext = _('Plot line')), pixmap = 'settings_plotline' ) s.add( setting.Line('MarkerLine', descr = _('Line around the marker settings'), usertext = _('Marker border')), pixmap = 'settings_plotmarkerline' ) s.add( MarkerFillBrush('MarkerFill', descr = _('Marker fill settings'), usertext = _('Marker fill')), pixmap = 'settings_plotmarkerfill' ) s.add( setting.ErrorBarLine('ErrorBarLine', descr = _('Error bar line settings'), usertext = _('Error bar line')), pixmap = 'settings_ploterrorline' ) # XXX FillBelow and FillAbove are historical names. The two settings # are now more akin to Fill1 and Fill2 in widgets.nonorthpoint but the # names are allowed to persist for backward compatibility (there's no # equivalent to SettingBackwardCompat for Settings derived classes) s.add( PointFillBelow('FillBelow', descr = _('Fill settings (1)'), usertext = _('Area fill 1')), pixmap = 'settings_plotfillbelow' ) s.add( PointFillAbove('FillAbove', descr = _('Fill settings (2)'), usertext = _('Area fill 2')), pixmap = 'settings_plotfillbelow' ) s.add( setting.PointLabel('Label', descr = _('Label settings'), usertext=_('Label')), pixmap = 'settings_axislabel' )
def addSettings(klass, s): """Construct list of settings.""" GenericPlotter.addSettings(s) # get rid of default key setting s.remove("key") s.add(setting.Strings("keys", ("",), descr="Key text for each dataset", usertext="Key text"), 0) s.add( setting.DatasetOrStr( "labels", "", descr="Dataset or string to label bars", usertext="Labels", datatype="text" ), 5, ) s.add( setting.Choice( "mode", ("grouped", "stacked"), "grouped", descr="Show datasets grouped " "together or as a single bar", usertext="Mode", ), 0, ) s.add( setting.Choice( "direction", ("horizontal", "vertical"), "vertical", descr="Horizontal or vertical bar chart", usertext="Direction", ), 0, ) s.add( setting.Dataset( "posn", "", descr="Dataset containing position of bars" " (optional)", usertext="Positions" ), 0, ) s.add(setting.Datasets("lengths", ("y",), descr="Datasets containing lengths of bars", usertext="Lengths"), 0) s.add( setting.Float( "barfill", 0.75, minval=0.0, maxval=1.0, descr="Filling fraction of bars" " (between 0 and 1)", usertext="Bar fill", formatting=True, ) ) s.add( setting.Float( "groupfill", 0.9, minval=0.0, maxval=1.0, descr="Filling fraction of groups of bars" " (between 0 and 1)", usertext="Group fill", formatting=True, ) ) s.add( setting.Choice( "errorstyle", ("none", "bar", "barends"), "bar", descr="Error bar style to show", usertext="Error style", formatting=True, ) ) s.add(BarFill("BarFill", descr="Bar fill", usertext="Fill"), pixmap="settings_bgfill") s.add(BarLine("BarLine", descr="Bar line", usertext="Line"), pixmap="settings_border") s.add( setting.ErrorBarLine("ErrorBarLine", descr="Error bar line settings", usertext="Error bar line"), pixmap="settings_ploterrorline", )