def plotValuePairs(self, timeseries, pairs, isLowerTriangular=False, **kwargs): """ Constructs plots of values of column pairs for a single timeseries. Parameters --------- timeseries: NamedTimeseries #@expand """ numPlot = len(pairs) if isLowerTriangular: options = TimeseriesPlotter._mkPlotOptionsLowerTriangular( timeseries, numPlot, **kwargs) else: options = TimeseriesPlotter._mkPlotOptionsMatrix(timeseries, maxCol=numPlot, **kwargs) if options.marker is None: options.marker = DEFAULT_MARKER layout = self._mkManager(options, numPlot, isLowerTriangular=isLowerTriangular) options.xlabel = NULL_STR baseOptions = copy.deepcopy(options) for plotIdx, pair in enumerate(pairs): options = copy.deepcopy(baseOptions) xVar = pair[0] yVar = pair[1] ax = layout.getAxis(plotIdx) statement = StatementManager(ax.scatter) statement.addPosarg(timeseries[xVar]) statement.addPosarg(timeseries[yVar]) if isLowerTriangular: if layout.isLastRow(plotIdx): options.xlabel = xVar else: options.title = NULL_STR options.xticklabels = [] if layout.isFirstColumn(plotIdx): options.ylabel = yVar else: options.ylabel = NULL_STR options.yticklabels = [] else: # Matrix plot options.xlabel = NULL_STR options.ylabel = NULL_STR options.title = "%s v. %s" % (xVar, yVar) options.do(ax, statement=statement, plotIdx=plotIdx) if self.isPlot: plt.show()
def plotHistograms(self, timeseries, **kwargs): """ Constructs a matrix of histographs for timeseries values. Parameters --------- timeseries: NamedTimeseries #@expand """ options = TimeseriesPlotter._mkPlotOptionsMatrix(timeseries, **kwargs) numPlot = len(options.columns) layout = self._mkManager(options, numPlot) baseOptions = copy.deepcopy(options) for plotIdx, column in enumerate(options.columns): options = copy.deepcopy(baseOptions) ax = layout.getAxis(plotIdx) if layout.isFirstColumn(plotIdx): options.ylabel = "density" if not layout.isFirstColumn(plotIdx): options.ylabel = NULL_STR if layout.isLastRow(plotIdx): options.xlabel = "value" else: options.xlabel = NULL_STR # Matrix plot options.title = column statement = StatementManager(ax.hist) statement.addPosarg(timeseries[column]) statement.addKwargs(density=True) if options.bins is not None: statement.addKwargs(bins=options.bins) options.do(ax, statement=statement, plotIdx=plotIdx) if self.isPlot: plt.show()
def mkBand(ts, variable, plotIdx, lineIdx): initialStatement = StatementManager(ax.fill_between) statement = mkStatement(ax, initialStatement, timeseries1, variable) statement.addPosarg(ts[variable]) statement.addKwargs(alpha=0.2) options.do(ax, statement=statement, plotIdx=plotIdx, lineIdx=lineIdx)
def setLineAttribute(ax, name: str, statement: StatementManager = None, **kwargs): """ Updates the statement for the line being plotted. """ if statement is None: return if "Axes.plot" in str(statement.func): # Some options are not alloed for line plots if name in [MARKER, MARKERSIZE]: return value = self.get(name, **kwargs) if value is not None: if name in AX_STATEMENT_KW.keys(): dct = {AX_STATEMENT_KW[name]: value} else: dct = {name: value} statement.addKwargs(**dct)
def mkStatement(ax, statement:StatementManager, timeseries:NamedTimeseries, variable:str): """ Creates a plotting statement. Parameters ---------- ax: plotting axes initialStatement: statement if initialized timeseries: what to plot variable: variable to plot Returns ------- StatementManager """ times, values = self._adjustSeriesForNan( timeseries[TIME], timeseries[variable]) statement.addPosarg(times) statement.addPosarg(values) return statement
def plotAutoCorrelations(self, timeseries:NamedTimeseries, **kwargs:dict): """ Plots autocorrelations for a timeseries. Uses the Barlet bound to estimate confidence intervals. Parameters ---------- #@expand """ # Structure the plots baseOptions, layout = self._mkAutocorrelation(timeseries, isLowerTriangular=False, **kwargs) lags, lower_line, upper_line = self._mkAutocorrelationErrorBounds(timeseries) baseOptions.set(po.SUPTITLE, "Autocorrelations") for plotIdx, column in enumerate(baseOptions.columns): options = copy.deepcopy(baseOptions) ax = layout.getAxis(plotIdx) if not layout.isFirstColumn(plotIdx): options.ylabel = NULL_STR if not layout.isLastRow(plotIdx): options.xlabel = NULL_STR # Matrix plot lineIdx = 0 options.title = column statement = StatementManager(ax.acorr) statement.addPosarg(timeseries[column]) statement.addKwargs(maxlags=MAX_LAGS) options.do(ax, statement=statement, plotIdx=plotIdx, lineIdx=lineIdx) # self._addConfidenceLines(ax, lags, [lower_line, upper_line], options, lineIdx, plotIdx=plotIdx) if self.isPlot: plt.show()
def setFigPlotAttribute(ax, name: str, **kwargs): value = self.__getattribute__(name) if value is not None: func = eval("ax.set_%s" % name) statement = StatementManager(func) statement.addPosarg(self.get(name, **kwargs)) statement.execute()
def _addConfidenceLines(self, ax, xline, lines, options, startLineIdx, **kwargs): lineIdx = startLineIdx for line in lines: lineIdx += 1 statement = StatementManager(ax.plot) statement.addPosarg(xline) statement.addPosarg(line) options.do(ax, statement=statement, lineIdx=lineIdx, **kwargs)
def testPositional(self): if IGNORE_TEST: return def test(): result = manager.execute() self.assertEqual(result, sum(POS_VALUES)) # manager = StatementManager(function) manager.addPosarg(POS_VALUES[0]) manager.addPosarg(POS_VALUES[1]) test() # manager = StatementManager(function) manager.addPosargs(POS_VALUES) test()
def plotCrossCorrelations(self, timeseries:NamedTimeseries, **kwargs:dict): """ Constructs pairs of cross correlation plots. Uses the Barlet bound to estimate confidence intervals. Parameters ---------- #@expand """ if po.COLUMNS in kwargs.keys(): numCol = len(po.COLUMNS) else: numCol = len(timeseries.colnames) numPlot = int((numCol**2 - numCol)/2) baseOptions, layout = self._mkAutocorrelation(timeseries, numPlot=numPlot, isLowerTriangular=True, **kwargs) # Construct the plot pairs pairs = [] columns = list(baseOptions.columns) for col1 in baseOptions.columns: columns.remove(col1) for col2 in columns: pairs.append((col1, col2)) lags, lower_line, upper_line = self._mkAutocorrelationErrorBounds( timeseries) baseOptions.set(po.SUPTITLE, "Cross Correlations") # Do the plots for plotIdx, pair in enumerate(pairs): options = copy.deepcopy(baseOptions) xVar = pair[0] yVar = pair[1] options.set(po.TITLE, "%s, %s" % (xVar, yVar)) ax = layout.getAxis(plotIdx) if layout.isLastRow(plotIdx): options.xlabel = "lag" else: options.xticklabels = [] if layout.isFirstColumn(plotIdx): options.ylabel = "corr" else: options.ylabel = NULL_STR options.yticklabels = [] # Matrix plot lineIdx = 0 statement = StatementManager(ax.xcorr) statement.addPosarg(timeseries[xVar]) statement.addPosarg(timeseries[yVar]) statement.addKwargs(maxlags=MAX_LAGS) options.do(ax, statement=statement, plotIdx=plotIdx, lineIdx=lineIdx) self._addConfidenceLines(ax, lags, [lower_line, upper_line], options, lineIdx, plotIdx=plotIdx) if self.isPlot: plt.show()
def multiPlot(ax:plt.Axes, timeseries:NamedTimeseries, options:po.PlotOptions, plotIdx:int): if plotIdx == IDX_PLOT2: timeseries = options.timeseries2 for lineIdx, col in enumerate(timeseries.colnames): if isinstance(options.marker, list): marker = options.marker[lineIdx] else: marker = options.marker if marker is None: statement = StatementManager(ax.plot) else: statement = StatementManager(ax.scatter) times, values = self._adjustSeriesForNan( timeseries[TIME], timeseries[col]) statement.addPosarg(times) statement.addPosarg(values) options.legend = timeseries.colnames options.do(ax, statement=statement, plotIdx=plotIdx, lineIdx=lineIdx)
def testKeyword(self): if IGNORE_TEST: return def test(is_with=True): if is_with: manager.addPosargs(POS_VALUES) expected = 2 * sum(POS_VALUES) else: expected = sum(POS_VALUES) result = manager.execute() self.assertEqual(result, expected) # manager = StatementManager(function) manager.addKwargs(**KW_DCT) test() # manager = StatementManager(function) manager.addKwargs(c=sum(POS_VALUES)) test()
def plotTimeSingle(self, timeseries1:NamedTimeseries, meanTS:NamedTimeseries=None, stdTS:NamedTimeseries=None, bandLowTS:NamedTimeseries=None, bandHighTS:NamedTimeseries=None, ax_spec=None, position=None, **kwargs): """ Constructs plots of single columns, possibly with a second timeseries. Parameters --------- timeseries1: timeseries to plot meanTS: mean values of timeseries to plot stdTS: standard deviations of meanTS (same times) bandLowTS: timeseries that describes the lower band for timeseries1 bandhighTS: timeseries that describes the higher band for timeseries1 ax_spec: Optionally specified axis for all lines position: (int, int) - position of ax_spec #@expand Example ------- plotter = TimeseriesPlotter() plotter.plotTimeSingle(timeseries) """ options = self._mkPlotOptionsMatrix(timeseries1, **kwargs) # Adjust rows and columns numPlot = len(options.columns) # Number of plots if po.NUM_COL in kwargs.keys(): options.numRow = int(np.ceil(numPlot/options.numCol)) else: options.numCol = int(np.ceil(numPlot/options.numRow)) options.set(po.XLABEL, TIME) # Create the LayoutManager if ax_spec is None: layout = self._mkManager(options, numPlot) else: layout = None # def mkStatement(ax, statement:StatementManager, timeseries:NamedTimeseries, variable:str): """ Creates a plotting statement. Parameters ---------- ax: plotting axes initialStatement: statement if initialized timeseries: what to plot variable: variable to plot Returns ------- StatementManager """ times, values = self._adjustSeriesForNan( timeseries[TIME], timeseries[variable]) statement.addPosarg(times) statement.addPosarg(values) return statement # def isFirstColumn(plotIdx): if layout is not None: return layout.isFirstColumn(plotIdx) else: if position is not None: return position[1] == 0 else: return True # def isLastRow(plotIdx): if layout is not None: return layout.isLastRow(plotIdx) else: if po.NUM_ROW in kwargs.keys(): numRow = kwargs[po.NUM_ROW] else: return True if position is None: return True return position[0] + 1 == numRow # def mkBand(ts, variable, plotIdx, lineIdx): initialStatement = StatementManager(ax.fill_between) statement = mkStatement(ax, initialStatement, timeseries1, variable) statement.addPosarg(ts[variable]) statement.addKwargs(alpha=0.2) options.do(ax, statement=statement, plotIdx=plotIdx, lineIdx=lineIdx) # # Construct the plots baseOptions = copy.deepcopy(options) for plotIdx, variable in enumerate(options.columns): if ax_spec is None: ax = layout.getAxis(plotIdx) else: ax = ax_spec options = copy.deepcopy(baseOptions) #ax = axes[row, col] options.set(po.YLABEL, "concentration") options.set(po.TITLE, variable) if not isFirstColumn(plotIdx): options.ylabel = NULL_STR options.set(po.YLABEL, "", isOverride=True) if not isLastRow(plotIdx): options.set(po.XLABEL, "", isOverride=True) # Construct the plot lineIdx = 0 initialStatement = StatementManager(ax.plot) statement = mkStatement(ax, initialStatement, timeseries1, variable) options.do(ax, statement=statement, plotIdx=plotIdx, lineIdx=lineIdx) legends = [] if options.timeseries2 is not None: lineIdx = 1 initialStatement = StatementManager(ax.plot) if options.marker is not None: if len(options.marker) > 1: if options.marker[lineIdx] is not None: initialStatement = StatementManager(ax.scatter) elif options.marker is not None: initialStatement = StatementManager(ax.scatter) statement = mkStatement(ax, initialStatement, options.timeseries2, variable) legends = [LABEL1, LABEL2] options.lengends = legends options.do(ax, statement=statement, plotIdx=plotIdx, lineIdx=lineIdx) if meanTS is not None: if stdTS is None: stdTS = meanTS.copy(isInitialize=True) lineIdx = 2 initialStatement = StatementManager(ax.scatter) statement = mkStatement(ax, initialStatement, meanTS, variable) options.marker = "^" statement.addKwargs(facecolors="none") options.do(ax, statement=statement, plotIdx=plotIdx, lineIdx=lineIdx) # initialStatement = StatementManager(ax.errorbar) statement = mkStatement(ax, initialStatement, meanTS, variable) statement.addKwargs(yerr=stdTS[variable]) statement.addKwargs(linestyle="none") legends.append("Bootstrap mean") options.lengends = legends options.do(ax, statement=statement, plotIdx=plotIdx, lineIdx=lineIdx) if bandLowTS is not None: lineIdx = 0 mkBand(bandLowTS, variable, plotIdx, lineIdx) if bandHighTS is not None: lineIdx = 0 mkBand(bandHighTS, variable, plotIdx, lineIdx) if self.isPlot: plt.show()
def do(self, ax, statement: StatementManager = None, **kwargs): """ Enacts options taking into account the scope of the option. Note that options related to NUM_ROW, NUM_COL are handled elsewhere. Parameters ---------- ax: Matplotlib.Axes statement: StatementManager kwargs: dict arguments for get """ def setLineAttribute(ax, name: str, statement: StatementManager = None, **kwargs): """ Updates the statement for the line being plotted. """ if statement is None: return if "Axes.plot" in str(statement.func): # Some options are not alloed for line plots if name in [MARKER, MARKERSIZE]: return value = self.get(name, **kwargs) if value is not None: if name in AX_STATEMENT_KW.keys(): dct = {AX_STATEMENT_KW[name]: value} else: dct = {name: value} statement.addKwargs(**dct) # def setFigPlotAttribute(ax, name: str, **kwargs): value = self.__getattribute__(name) if value is not None: func = eval("ax.set_%s" % name) statement = StatementManager(func) statement.addPosarg(self.get(name, **kwargs)) statement.execute() # Attributes processed by this method names = [ ALPHA, COLOR, LINESTYLE, MARKER, MARKERSIZE, XLABEL, YLABEL, XLIM, XTICKLABELS, YLIM, YTICKLABELS ] for name in names: kwarg = KWARG_DCT[name] if kwarg.scope == ExKwarg.LINE: setLineAttribute(ax, name, statement=statement, **kwargs) else: setFigPlotAttribute(ax, name, **kwargs) if statement is not None: statement.execute() # Other attributes if self.title is not None: title = self.get(TITLE, **kwargs) titlePosition = self.get(TITLE_POSITION, **kwargs) titleFontsize = self.get(TITLE_FONTSIZE, **kwargs) statement = StatementManager(ax.set_title) statement.addPosarg(title) if self.titlePosition is not None: statement.addKwargs(x=titlePosition[0]) statement.addKwargs(y=titlePosition[1]) statement.addKwargs(transform=ax.transAxes) if self.titleFontsize is not None: statement.addKwargs(fontsize=titleFontsize) statement.execute() value = self.__getattribute__(SUBPLOT_WIDTH_SPACE) if value is not None: plt.subplots_adjust(wspace=value) if self.legend is not None: ax.legend(self.legend) if self.suptitle is not None: plt.suptitle(self.suptitle)
def setUp(self): self.manager = StatementManager(function)