Source code for paramonte.vis.LineScatterPlot

####################################################################################################################################
####################################################################################################################################
####
####   MIT License
####
####   ParaMonte: plain powerful parallel Monte Carlo library.
####
####   Copyright (C) 2012-present, The Computational Data Science Lab
####
####   This file is part of the ParaMonte library.
####
####   Permission is hereby granted, free of charge, to any person obtaining a 
####   copy of this software and associated documentation files (the "Software"), 
####   to deal in the Software without restriction, including without limitation 
####   the rights to use, copy, modify, merge, publish, distribute, sublicense, 
####   and/or sell copies of the Software, and to permit persons to whom the 
####   Software is furnished to do so, subject to the following conditions:
####
####   The above copyright notice and this permission notice shall be 
####   included in all copies or substantial portions of the Software.
####
####   THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, 
####   EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 
####   MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. 
####   IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, 
####   DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR 
####   OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE 
####   OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
####
####   ACKNOWLEDGMENT
####
####   ParaMonte is an honor-ware and its currency is acknowledgment and citations.
####   As per the ParaMonte library license agreement terms, if you use any parts of 
####   this library for any purposes, kindly acknowledge the use of ParaMonte in your 
####   work (education/research/industry/development/...) by citing the ParaMonte 
####   library as described on this page:
####
####       https://github.com/cdslaborg/paramonte/blob/main/ACKNOWLEDGMENT.md
####
####################################################################################################################################
####################################################################################################################################

import numpy as np
import typing as tp
import weakref as wref
import _paramonte as pm
import _pmutils as pmutils
from paramonte.vis.Target import Target
from paramonte.vis._BasePlot import BasePlot

Struct = pmutils.Struct
newline = pmutils.newline

####################################################################################################################################
#### LineScatterPlot class
####################################################################################################################################

[docs]class LineScatterPlot(BasePlot): """ This is the LineScatterPlot class for generating instances of line or scatter plots or the combination of the two in two or three dimensions based on the visualization tools of the ``matplotlib`` and ``seaborn`` Python libraries. **Usage** First generate an object of this class by optionally passing the following parameters described below. Then call the ``make()`` method. The generated object is also callable with the same input parameters as the object's constructor. **Parameters** plotType A string indicating the name of the plot to be constructed. dataFrame (optional) A pandas dataFrame whose data will be plotted. methodName (optional) The name of the ParaMonte sample requesting the BasePlot. reportEnabled (optional) A boolean whose value indicates whether guidelines should be printed in the standard output. resetPlot (optional) A function that resets the properties of the plot as desired from outside. If provided, a pointer to this function will be saved for future internal usage. **Attributes** xcolumns An attribute that determines the columns of dataFrame to be visualized as the X-axis. It can have three forms: 1. A list of column indices in dataFrame. 2. A list of column names in dataFrame.columns. 3. A ``range(start,stop,step)`` of column indices. Examples: 1. ``xcolumns = [0,1,4,3]`` 2. ``xcolumns = ["SampleLogFunc","SampleVariable1"]`` 3. ``xcolumns = range(17,7,-2)`` The default behavior includes all columns of the dataFrame. ycolumns An attribute that determines the columns of dataFrame to be visualized as the Y-axis. It can have three forms: 1. A list of column indices in dataFrame. 2. A list of column names in dataFrame.columns. 3. A ``range(start,stop,step)`` of column indices. Examples: 1. ``ycolumns = [0,1,4,3]`` 2. ``ycolumns = ["SampleLogFunc","SampleVariable1"]`` 3. ``ycolumns = range(17,7,-2)`` The default behavior includes all columns of the dataFrame. zcolumns (exists only in 3D plot objects) An attribute that determines the columns of dataFrame to be visualized as the Z-axis. It can have three forms: 1. A list of column indices in dataFrame. 2. A list of column names in dataFrame.columns. 3. A ``range(start,stop,step)`` of column indices. Examples: 1. ``zcolumns = [0,1,4,3]`` 2. ``zcolumns = ["SampleLogFunc","SampleVariable1"]`` 3. ``zcolumns = range(17,7,-2)`` The default behavior includes all columns of the dataFrame. ccolumns An attribute that determines the columns of dataFrame to be used for color mapping. It can have three forms: 1. A list of column indices in dataFrame. 2. A list of column names in dataFrame.columns. 3. A ``range(start,stop,step)`` of column indices. Examples: 1. ``ccolumns = [0,1,4,3]`` 2. ``ccolumns = ["SampleLogFunc","SampleVariable1"]`` 3. ``ccolumns = range(17,7,-2)`` If ``ccolumns`` is set to ``None``, then no color-mapping will be made. If it is set to an empty list ``[]``, then the values from the ``rows`` attribute will be used for color-mapping. rows An attribute that determines the rows of dataFrame to be visualized. It can be either: 1. A ``range(start,stop,step)``, or, 2. A list of row indices in dataFrame.index. Examples: 1. ``rows = range(17,7,-2)`` 2. ``rows = [i for i in range(7,17)]`` The default behavior includes all rows of the dataFrame. plot (exists only for line or lineScatter plots in 2D and 3D) A structure with two attributes: enabled A boolean indicating whether a call to the ``plot()`` function of the matplotlib library should be made or not. kws A structure whose components are directly passed as keyword arguments to the ``plot()`` function. Example usage: .. code-block:: python plot.enabled = True plot.kws.linewidth = 1 **NOTE** If a desired property is missing among the ``kws`` attributes, simply add the field and its value to the component. scatter (exists only for scatter / lineScatter plots in 2D and 3D) A structure with two attributes: enabled A boolean indicating whether a call to the ``scatter()`` function of the matplotlib library should be made or not. kws A structure whose components are directly passed as keyword arguments to the ``scatter()`` function. Example usage: .. code-block:: python scatter.enabled = True scatter.kws.s = 2 **NOTE** If a desired property is missing among the ``kws`` attributes, simply add the field and its value to the component. lineCollection (exists only for 2D / 3D line / lineScatter plots) A structure with two attributes: enabled A boolean indicating whether a call to the ``LineCollection()`` class of the matplotlib library should be made or not. This will result in line plots that are color-mapped. kws A structure whose components are directly passed as keyword arguments to the ``LineCollection()`` class of matplotlib library. Example usage: .. code-block:: python lineCollection.enabled = True lineCollection.kws.linewidth = 1 **NOTE** If a desired property is missing among the ``kws`` attributes, simply add the field and its value to the component. set A structure with two attributes: enabled A boolean indicating whether a call to the ``set()`` function of the seaborn library should be made or not. kws A structure whose components are directly passed as keyword arguments to the ``set()`` function. Example usage: .. code-block:: python set.kws.style = "darkgrid" **NOTE** If a desired property is missing among the ``kws`` attributes, simply add the field and its value to the component. axes (available only in 1D and 2D plots) A structure with one attribute: kws A structure whose components are directly passed as keyword arguments to the ``gca()`` function of the matplotlib library. Example usage: .. code-block:: python axes.kws.facecolor = "w" **NOTE** If a desired property is missing among the ``kws`` attributes, simply add the field and its value to the component. axes3d (available only in 3D plots) A structure with one attribute: kws A structure whose components are directly passed as keyword arguments to the ``Axes3D()`` function of the matplotlib library. Example usage: .. code-block:: python axes3d.kws.facecolor = "w" **NOTE** If a desired property is missing among the ``kws`` attributes, simply add the field and its value to the component. figure A structure with two attributes: enabled A boolean indicating whether a call to the ``figure()`` function of the matplotlib library should be made or not. If a call is made, a new figure will be generated. Otherwise, the current active figure will be used. kws A structure whose components are directly passed as keyword arguments to the ``figure()`` function. Example usage: .. code-block:: python figure.kws.facecolor = "w" **NOTE** If a desired property is missing among the ``kws`` attributes, simply add the field and its value to the component. colorbar (exists only for plots that require colorbar) A structure with two attributes: enabled A boolean indicating whether a call to the ``colorbar()`` function of the matplotlib library should be made or not. If a call is made, a new figure will be generated. Otherwise, the current active figure will be used. kws A structure whose components are directly passed as keyword arguments to the ``colorbar()`` function of the matplotlib library. **NOTE** If a desired property is missing among the ``kws`` attributes, simply add the field and its value to the component. A colorbar will be added to a plot only if a color-mappings is requested in the plot. legend (may not exist for some types of plots) A structure with two attributes: enabled A boolean indicating whether a call to the ``legend()`` function of the matplotlib library should be made or not. If a call is made, a new figure will be generated. Otherwise, the current active figure will be used. kws A structure whose components are directly passed as keyword arguments to the ``legend()`` function. Example usage: .. code-block:: python legend.kws.labels = ["Variable1", "Variable2"] **NOTE** If a desired property is missing among the ``kws`` attributes, simply add the field and its value to the component. A legend will be added to a plot only if no color-mappings are requested in the plot. currentFig A structure whose attributes are the outputs of various plotting tools used to make the current figure. These include the handle to the current figure, the handle to the current axes in the plot, the handle to the colorbar (if any exists), and other Python plotting tools used to make to generate the figure. target (available only in 1D and 2D plot objects) A callable object of the ParaMonte library's ``Target`` class which can be used to add target point or lines to the current active plot. **Returns** An object of class ``LineScatterPlot``. --------------------------------------------------------------------------- """ ################################################################################################################################ #### __init__ ################################################################################################################################ def __init__( self , plotType # : str , dataFrame = None # : tp.Optional[ pd.DataFrame ] = None , methodName = "ParaMonte" # : tp.Optional[ str ] = "ParaMonte" , reportEnabled = True # : tp.Optional[ bool ] = True , resetPlot = None ): super().__init__( plotType = plotType , dataFrame = dataFrame , methodName = methodName , reportEnabled = reportEnabled , resetPlot = resetPlot ) self._reset() if resetPlot is None: self._resetPlot = self._reset self._progress.note() ################################################################################################################################ #### _reset ################################################################################################################################
[docs] def _reset(self): super()._reset() self._indexOffset = 1 self.xcolumns = None self.ycolumns = None self.ccolumns = [] # indicates the use of default column for colormap. To turn off self._xlabel = None self._ylabel = None self._zlabel = None self._xlimit = None self._ylimit = None self._zlimit = None self._xscale = None self._yscale = None self._zscale = None if not self._type.is3d: self.target = Target() if self._type.isLine: self.plot = Struct() self.plot.enabled = False self.plot.kws = Struct() self.lineCollection = Struct() self.lineCollection.kws = Struct() self.lineCollection.enabled = True if self._type.isScatter: self.scatter = Struct() self.scatter.enabled = True self.scatter.kws = Struct() if self._type.is3d: self.zcolumns = [] self.colorbar = Struct() self.colorbar.kws = Struct() if (self._type.isScatter and self.ccolumns is not None) or (self._type.isLine and self.lineCollection.enabled): self.colorbar.enabled = True else: self.colorbar.enabled = False self._isdryrun = True self.make() self._isdryrun = False
################################################################################################################################ #### __call__ ################################################################################################################################
[docs] def __call__( self , reself : tp.Optional[ bool ] = False , **kwargs ): """ Call the ``make()`` method of the current instance of the class. **Parameters** Any arguments that can be passed to the ``make()`` method of the plot object. **Returns** Any return value from the ``make()`` method of the plot object. """ return self.make(reself, **kwargs)
################################################################################################################################ #### make ################################################################################################################################
[docs] def make( self , reself : tp.Optional[ bool ] = False , **kwargs ): """ Generate a line/scatter plot from the selected columns of the object's dataframe. **Parameters** reself A logical variable. If ``True``, an instance of the object will be returned to the calling routine upon exit. The default value is ``False``. **Returns** The object self if ``reself = True`` otherwise, ``None``. However, this method causes side-effects by manipulating the existing attributes of the object. """ for key in kwargs.keys(): if hasattr(self,key): setattr(self, key, kwargs[key]) elif key=="dataFrame": setattr( self, "_dfref", wref.ref(kwargs[key]) ) else: raise Exception ( "Unrecognized input '"+key+"' class attribute detected." + newline + self._getDocString() ) # set what to plot cEnabled = self.ccolumns is not None from collections.abc import Iterable if self.ccolumns is not None and not isinstance(self.ccolumns, Iterable): self.ccolumns = [self.ccolumns] # if no colormap, then if self._type.isLine and not cEnabled: self.plot.enabled = True ############################################################################################################################ #### scatter plot properties ############################################################################################################################ if self._type.isScatter: if isinstance(self.scatter.kws,Struct): if "s" not in vars(self.scatter.kws).keys(): self.scatter.kws.s = 2 if "c" not in vars(self.scatter.kws).keys(): self.scatter.kws.c = None if "cmap" not in vars(self.scatter.kws).keys() or self.scatter.kws.cmap is None: self.scatter.kws.cmap = "autumn" if "alpha" not in vars(self.scatter.kws).keys(): self.scatter.kws.alpha = 1 if "edgecolors" not in vars(self.scatter.kws).keys(): self.scatter.kws.edgecolors = None if "zorder" not in vars(self.scatter.kws).keys(): self.scatter.kws.zorder = 2 if not cEnabled: self.scatter.kws.cmap = None else: raise Exception ( "The scatter.kws component of the current LineScatterPlot object must" + newline + "be an object of class Struct(), essentially a structure with components" + newline + "whose names are the input arguments to the scatter() function of the" + newline + "matplotlib library." + newline + self._getDocString() ) ############################################################################################################################ #### line plot properties ############################################################################################################################ if self._type.isLine: if isinstance(self.plot.kws,Struct): if "linewidth" in vars(self.plot.kws).keys(): if self.plot.kws.linewidth==0: self.plot.kws.linewidth = 1 else: self.plot.kws.linewidth = 1 if "zorder" not in vars(self.plot.kws).keys(): self.plot.kws.zorder = 1 else: raise Exception ( "The plot.kws component of the current LineScatterPlot object must" + newline + "be an object of class Struct(), essentially a structure with components" + newline + "whose names are the input arguments to the plot() function of the" + newline + "matplotlib library." + newline + self._getDocString() ) if isinstance(self.lineCollection.kws, Struct): if "cmap" not in vars(self.lineCollection.kws).keys() or self.lineCollection.kws.cmap is None: self.lineCollection.kws.cmap = "autumn" if "alpha" not in vars(self.lineCollection.kws).keys(): self.lineCollection.kws.alpha = 1 if "linewidth" not in vars(self.lineCollection.kws).keys(): self.lineCollection.kws.linewidth = 1 else: objectType = "LineCollection" if self._type.is3d: objectType = "Line3DCollection" raise Exception ( "The lineCollection.kws component of the current LineScatterPlot object must" + newline + "be an object of class Struct(), essentially a structure with components" + newline + "whose names are the input arguments to the " + objectType + "() class of the" + newline + "matplotlib library." + newline + self._getDocString() ) ############################################################################################################################ #### legend properties ############################################################################################################################ if self.legend.enabled: if not isinstance(self.legend.kws,Struct): raise Exception ( "The legend.kws component of the current LineScatterPlot object must" + newline + "be an object of class Struct(), essentially a structure with components" + newline + "whose names are the input arguments to the legend() function of the" + newline + "matplotlib library." + newline + self._getDocString() ) ############################################################################################################################ #### figure properties ############################################################################################################################ if self.figure.enabled: if isinstance(self.figure.kws, Struct): if "dpi" not in vars(self.figure.kws).keys(): self.figure.kws.dpi = 150 if "facecolor" not in vars(self.figure.kws).keys(): self.figure.kws.facecolor = "w" if "edgecolor" not in vars(self.figure.kws).keys(): self.figure.kws.edgecolor = "w" else: raise Exception ( "The figure.kws component of the current LineScatterPlot object must" + newline + "be an object of class Struct(), essentially a structure with components" + newline + "whose names are the input arguments to the figure() function of the" + newline + "matplotlib library." + newline + self._getDocString() ) ############################################################################################################################ ############################################################################################################################ if self._isdryrun: return ############################################################################################################################ ############################################################################################################################ from matplotlib import pyplot as plt from matplotlib.collections import LineCollection if self._type.is3d: from mpl_toolkits.mplot3d.art3d import Line3DCollection plt.ion() # turn on the interactive mode. Used to detach the figure from the command line in ipython ############################################################################################################################ #### generate figure and axes if needed ############################################################################################################################ self._constructBasePlot() ############################################################################################################################ #### check data type ############################################################################################################################ self._checkDataType() ############################################################################################################################ #### check rows presence. This must be checked here, because it depends on the integrity of the in input dataFrame. ############################################################################################################################ if self.rows is None: self.rows = range(len(self._dfref().index)) ############################################################################################################################ #### check columns presence. This must be checked here, because it depends on the integrity of the in input dataFrame. ############################################################################################################################ if self.xcolumns is None: lgxicol = 0 xcolindex = [] xcolnames = ["Count"] if self._type.isScatter : self.scatter._xvalues = np.array( self._dfref().index[self.rows] + self._indexOffset ).flatten() if self._type.isLine : self.plot._xvalues = np.array( self._dfref().index[self.rows] + self._indexOffset ).flatten() else: xcolnames, xcolindex = pm.dfutils.getColNamesIndex(self._dfref().columns,self.xcolumns) if self.ycolumns is None: lgyicol = 0 ycolindex = [] ycolnames = ["Count"] if self._type.isScatter : self.scatter._yvalues = np.array( self._dfref().index[self.rows] + self._indexOffset ).flatten() if self._type.isLine : self.plot._yvalues = np.array( self._dfref().index[self.rows] + self._indexOffset ).flatten() else: ycolnames, ycolindex = pm.dfutils.getColNamesIndex(self._dfref().columns,self.ycolumns) if self._type.is3d: if self.zcolumns is None: lgzicol = 0 zcolindex = [] zcolnames = ["Count"] if self._type.isScatter : self.scatter._zvalues = np.array( self._dfref().index[self.rows] + self._indexOffset ).flatten() if self._type.isLine : self.plot._zvalues = np.array( self._dfref().index[self.rows] + self._indexOffset ).flatten() else: zcolnames, zcolindex = pm.dfutils.getColNamesIndex(self._dfref().columns, self.zcolumns) ############################################################################################################################ #### set colormap data ############################################################################################################################ if cEnabled: if len(self.ccolumns)==0: ccolindex = [] ccolnames = ["Count"] if self._type.isScatter : self.scatter.kws.c = np.array( self._dfref().index[self.rows] + self._indexOffset ).flatten() if self._type.isLine : cdata = np.array( self._dfref().index[self.rows] + self._indexOffset ).flatten() else: ccolnames, ccolindex = pm.dfutils.getColNamesIndex(self._dfref().columns,self.ccolumns) else: ccolindex = [] ccolnames = [] #self.scatter.kws.c = None ############################################################################################################################ #### check the consistency of the lengths ############################################################################################################################ xcolindexlen = len(xcolindex) ycolindexlen = len(ycolindex) ccolindexlen = len(ccolindex) maxLenColumns = np.max ( [ xcolindexlen , ycolindexlen , ccolindexlen ] ) if xcolindexlen!=maxLenColumns and xcolindexlen>1: raise Exception("length of xcolumns must be either 1 or equal to the lengths of ycolumns or ccolumns.") if ycolindexlen!=maxLenColumns and ycolindexlen>1: raise Exception("length of ycolumns must be either 1 or equal to the lengths of xcolumns or ccolumns.") if ccolindexlen!=maxLenColumns and ccolindexlen>1: raise Exception("length of ccolumns must be either 1 or equal to the lengths of xcolumns or ycolumns.") if self._type.is3d: zcolindexlen = len(zcolindex) if zcolindexlen!=maxLenColumns and zcolindexlen>1: raise Exception("length of zcolumns must be either 1 or equal to the lengths of xcolumns or ycolumns.") ############################################################################################################################ #### assign data in case of single column assignments ############################################################################################################################ if xcolindexlen==1: lgxicol = 0 if self._type.isScatter : self.scatter._xvalues = self._dfref().iloc[self.rows,xcolindex].values.flatten() if self._type.isLine : self.plot._xvalues = self._dfref().iloc[self.rows,xcolindex].values.flatten() if ycolindexlen==1: lgyicol = 0 if self._type.isScatter : self.scatter._yvalues = self._dfref().iloc[self.rows,ycolindex].values.flatten() if self._type.isLine : self.plot._yvalues = self._dfref().iloc[self.rows,ycolindex].values.flatten() if self._type.is3d: if zcolindexlen==1: lgzicol = 0 if self._type.isScatter : self.scatter._zvalues = self._dfref().iloc[self.rows,zcolindex].values.flatten() if self._type.isLine : self.plot._zvalues = self._dfref().iloc[self.rows,zcolindex].values.flatten() if cEnabled: if ccolindexlen==1: if self._type.isScatter : self.scatter.kws.c = self._dfref().iloc[self.rows,ccolindex].values.flatten() if self._type.isLine : cdata = self._dfref().iloc[self.rows,ccolindex].values.flatten() ############################################################################################################################ #### add line/scatter plot ############################################################################################################################ if self.legend.enabled: self.legend._labels = [] if self._type.isScatter and self.scatter.enabled: self.currentFig.scatterList = [] if self._type.isLine: if self.plot.enabled: self.currentFig.plotList = [] if cEnabled and self.lineCollection.enabled: self.currentFig.lineCollectionList = [] self.currentFig.plotList = [] for i in range(maxLenColumns): if xcolindexlen>1: lgxicol = i if self._type.isScatter : self.scatter._xvalues = self._dfref().iloc[self.rows,xcolindex[i]].values.flatten() if self._type.isLine : self.plot._xvalues = self._dfref().iloc[self.rows,xcolindex[i]].values.flatten() if ycolindexlen>1: lgyicol = i if self._type.isScatter : self.scatter._yvalues = self._dfref().iloc[self.rows,ycolindex[i]].values.flatten() if self._type.isLine : self.plot._yvalues = self._dfref().iloc[self.rows,ycolindex[i]].values.flatten() if cEnabled: if ccolindexlen>1: if self._type.isScatter : self.scatter.kws.c = self._dfref().iloc[self.rows,ccolindex[i]].values.flatten() if self._type.isLine : cdata = self._dfref().iloc[self.rows,ccolindex[i]].values.flatten() if self.legend.enabled: if xcolindexlen<2 and ycolindexlen>1: self.legend._labels.append(ycolnames[lgyicol]) elif xcolindexlen>1 and ycolindexlen<2: self.legend._labels.append(xcolnames[lgxicol]) else: self.legend._labels.append( xcolnames[lgxicol] + "-" + ycolnames[lgyicol] ) if self._type.is3d: if zcolindexlen>1: lgzicol = i if self._type.isScatter : self.scatter._zvalues = self._dfref().iloc[self.rows,zcolindex[i]].values.flatten() if self._type.isLine : self.plot._zvalues = self._dfref().iloc[self.rows,zcolindex[i]].values.flatten() if self.legend.enabled: if zcolindexlen>1: self.legend._labels[-1] += "-" + zcolnames[lgzicol] ######################################################################################################################## #### add scatter plot ######################################################################################################################## if self._type.isScatter and self.scatter.enabled: if self._type.is3d: self.currentFig.scatterList.append( self.currentFig.axes.scatter( self.scatter._xvalues , self.scatter._yvalues , self.scatter._zvalues , **vars(self.scatter.kws) ) ) else: self.currentFig.scatterList.append( self.currentFig.axes.scatter( self.scatter._xvalues , self.scatter._yvalues , **vars(self.scatter.kws) ) ) ######################################################################################################################## #### add line plot ######################################################################################################################## if self._type.isLine: if self.plot.enabled: if self._type.is3d: self.currentFig.plotList.append ( self.currentFig.axes.plot ( self.plot._xvalues , self.plot._yvalues , self.plot._zvalues , **vars(self.plot.kws) ) ) else: self.currentFig.plotList.append ( self.currentFig.axes.plot ( self.plot._xvalues , self.plot._yvalues , **vars(self.plot.kws) ) ) if cEnabled and self.lineCollection.enabled: self.lineCollection.kws.norm = norm = plt.Normalize(cdata.min(), cdata.max()) if self._type.is3d: # properly and automatically set the axes limits via plot() self.currentFig.plotList.append ( self.currentFig.axes.plot ( self.plot._xvalues , self.plot._yvalues , self.plot._zvalues , linewidth = 0 ) ) # now add the lineCollection points = np.array([self.plot._xvalues, self.plot._yvalues, self.plot._zvalues]).T.reshape(-1, 1, 3) segments = np.concatenate([points[:-1], points[1:]], axis=1) lineCollection = Line3DCollection( segments, **vars(self.lineCollection.kws) ) else: # properly and automatically set the axes limits via plot() self.currentFig.plotList.append ( self.currentFig.axes.plot ( self.plot._xvalues , self.plot._yvalues , linewidth = 0 ) ) # now add the lineCollection points = np.array([self.plot._xvalues, self.plot._yvalues]).T.reshape(-1, 1, 2) segments = np.concatenate([points[:-1], points[1:]], axis=1) lineCollection = LineCollection( segments, **vars(self.lineCollection.kws) ) lineCollection.set_array(cdata) #lineCollection.set_linewidth(0.5) #lineCollection.set_solid_capstyle("round") self.currentFig.lineCollectionList.append( self.currentFig.axes.add_collection(lineCollection) ) ############################################################################################################################ #### add colorbar ############################################################################################################################ cbarEnabled = cEnabled and self.colorbar.enabled and (ccolindexlen<2) # and (not hasattr(self.currentFig,"colorbar")) if cbarEnabled: self.colorbar.kws.mappable = None if self._type.isLine and self.lineCollection.enabled: self.colorbar.kws.mappable = self.currentFig.lineCollectionList[0] elif self._type.isScatter and self.scatter.enabled: self.colorbar.kws.mappable = self.currentFig.scatterList[0] if self.colorbar.kws.mappable is not None: self.colorbar.kws.ax = self.currentFig.axes self.currentFig.colorbar = self.currentFig.figure.colorbar( **vars(self.colorbar.kws) ) self.currentFig.colorbar.set_label( label = ", ".join(ccolnames) ) ############################################################################################################################ #### set axes scales ############################################################################################################################ if self._xscale is not None: self.currentFig.axes.set_xscale(self._xscale) if self._yscale is not None: self.currentFig.axes.set_yscale(self._yscale) if self._zscale is not None and self._type.is3d: self.currentFig.axes.set_zscale(self._zscale) ############################################################################################################################ #### set axes limits ############################################################################################################################ if self._xlimit is not None: currentLim = list(self.currentFig.axes.get_xlim()) if self._xlimit[0] is not None: currentLim[0] = self._xlimit[0] if self._xlimit[1] is not None: currentLim[1] = self._xlimit[1] self.currentFig.axes.set_xlim(currentLim) if self._ylimit is not None: currentLim = list(self.currentFig.axes.get_ylim()) if self._ylimit[0] is not None: currentLim[0] = self._ylimit[0] if self._ylimit[1] is not None: currentLim[1] = self._ylimit[1] self.currentFig.axes.set_ylim(currentLim) if self._zlimit is not None and self._type.is3d: currentLim = list(self.currentFig.axes.get_zlim()) if self._zlimit[0] is not None: currentLim[0] = self._zlimit[0] if self._zlimit[1] is not None: currentLim[1] = self._zlimit[1] self.currentFig.axes.set_zlim(currentLim) ############################################################################################################################ #### add axes labels ############################################################################################################################ if self._xlabel is None: if xcolindexlen>1: self.currentFig.axes.set_xlabel("Variable Values") else: self.currentFig.axes.set_xlabel(xcolnames[0]) else: self.currentFig.axes.set_xlabel(self._xlabel) if self._ylabel is None: if ycolindexlen>1: self.currentFig.axes.set_ylabel("Variable Values") else: self.currentFig.axes.set_ylabel(ycolnames[0]) else: self.currentFig.axes.set_ylabel(self._ylabel) if self._type.is3d: if self._zlabel is None: if zcolindexlen>1: self.currentFig.axes.set_zlabel("Variable Values") else: self.currentFig.axes.set_zlabel(zcolnames[0]) else: self.currentFig.axes.set_zlabel(self._zlabel) ############################################################################################################################ #### set legend and other BasePlot properties ############################################################################################################################ self._finalizeBasePlot() if not self._type.is3d: self.target.currentFig.axes = self.currentFig.axes ############################################################################################################################ if reself: return self
################################################################################################################################ #### _getDocString ################################################################################################################################
[docs] def _getDocString(self): docString = newline \ + "Here is the help information on the LineScatterPlot class:" + newline \ + newline \ + self.__doc__ \ + newline \ + "Here is the help information on the parent BasePlot class:" + newline \ + newline \ + super().__doc__ return docString
################################################################################################################################ #### helpme ################################################################################################################################
[docs] def helpme(self, topic=None): """ Print the documentation for the input string topic. If the topic does not exist, the documentation for the object will be printed. **Parameters** topic (optional) A string containing the name of the object for which help is needed. **Returns** None **Example** .. code-block:: python :linenos: helpme() helpme("make") helpme("helpme") helpme("getLogLinSpace") """ try: exec("print(self."+topic+".__doc__)") except: print(self._getDocString()) return None
################################################################################################################################