Example #1
0
    def __init__(self, model, graph, index, parentWidget, *args, **kwargs):
        super(PlotWidget, self).__init__()
        self.model = model
        self.graph = graph
        self.index = index

        self.menu = self.getContextMenu()
        self.setContextMenuPolicy(QtCore.Qt.CustomContextMenu)
        self.customContextMenuRequested.connect(self.contextMenuRequested)
        #  self.connect( self
        #  , SIGNAL("customContextMenuRequested(QPoint)")
        #  , self
        #  , SLOT("contextMenuRequested(QPoint)")
        #  )

        self.canvas = CanvasWidget(self.model, self.graph, self.index)
        self.canvas.setParent(self)
        self.navToolbar = NavigationToolbar(self.canvas, self)
        self.hackNavigationToolbar()
        self.canvas.mpl_connect('pick_event', self.togglePlot)
        layout = QGridLayout()
        layout.addWidget(self.navToolbar, 0, 0)
        layout.addWidget(self.canvas, 1, 0)
        self.setLayout(layout)
        self.pathToLine = defaultdict(set)
        self.lineToDataSource = {}
        self.axesRef = self.canvas.addSubplot(1, 1)
        self.legend = None
        desktop = QApplication.desktop()
        self.setMinimumSize(desktop.screenGeometry().width() // 4,
                            desktop.screenGeometry().height() // 3)
        self.canvas.updateSignal.connect(self.plotAllData)
        self.plotAllData()
Example #2
0
    def __init__(self, model, graph, index, parentWidget, *args, **kwargs):
        super(PlotWidget, self).__init__()
        self.model = model
        self.graph = graph
        self.index = index

        self.menu = self.getContextMenu()
        self.setContextMenuPolicy(QtCore.Qt.CustomContextMenu)
        self.connect( self
                    , SIGNAL("customContextMenuRequested(QPoint)")
                    , self
                    , SLOT("contextMenuRequested(QPoint)")
                    )

        self.canvas = CanvasWidget(self.model, self.graph, self.index)
        self.canvas.setParent(self)
        self.navToolbar = NavigationToolbar(self.canvas, self)
        self.hackNavigationToolbar()
        self.canvas.mpl_connect('pick_event',self.togglePlot)
        layout = QtGui.QGridLayout()
        layout.addWidget(self.navToolbar, 0, 0)
        layout.addWidget(self.canvas, 1, 0)
        self.setLayout(layout)
        self.pathToLine = defaultdict(set)
        self.lineToDataSource = {}
        self.axesRef = self.canvas.addSubplot(1, 1)
        self.legend  = None
        desktop = QtGui.QApplication.desktop()
        self.setMinimumSize(desktop.screenGeometry().width() / 4, desktop.screenGeometry().height() / 3)
        self.canvas.updateSignal.connect(self.plotAllData)
        self.plotAllData()
Example #3
0
class PlotWidget(QWidget):
    """A wrapper over CanvasWidget to handle additional MOOSE-specific
    stuff.

    modelRoot - path to the entire model our plugin is handling

    dataRoot - path to the container of data tables.

    pathToLine - map from moose path to Line2D objects in plot. Can
    one moose table be plotted multiple times? Maybe yes (e.g., when
    you want multiple other tables to be compared with the same data).

    lineToDataSource - map from Line2D objects to moose paths

    """

    widgetClosedSignal = pyqtSignal(object)
    addGraph           = pyqtSignal(object)

    def __init__(self, model, graph, index, parentWidget, *args, **kwargs):
        super(PlotWidget, self).__init__()
        self.model = model
        self.graph = graph
        self.index = index

        self.menu = self.getContextMenu()
        self.setContextMenuPolicy(QtCore.Qt.CustomContextMenu)
        self.connect( self
                    , SIGNAL("customContextMenuRequested(QPoint)")
                    , self
                    , SLOT("contextMenuRequested(QPoint)")
                    )

        self.canvas = CanvasWidget(self.model, self.graph, self.index)
        self.canvas.setParent(self)
        self.navToolbar = NavigationToolbar(self.canvas, self)
        self.hackNavigationToolbar()
        self.canvas.mpl_connect('pick_event',self.togglePlot)
        layout = QtGui.QGridLayout()
        layout.addWidget(self.navToolbar, 0, 0)
        layout.addWidget(self.canvas, 1, 0)
        self.setLayout(layout)
        self.pathToLine = defaultdict(set)
        self.lineToDataSource = {}
        self.axesRef = self.canvas.addSubplot(1, 1)
        self.legend  = None
        desktop = QtGui.QApplication.desktop()
        self.setMinimumSize(desktop.screenGeometry().width() / 4, desktop.screenGeometry().height() / 3)
        self.canvas.updateSignal.connect(self.plotAllData)
        self.plotAllData()

    def hackNavigationToolbar(self):
        # ADD Graph Action
        pixmap = QPixmap(
                os.path.join( config.MOOSE_ICON_DIR, 'add_graph.png' )
                )
        icon   = QIcon(pixmap)
        action  = QAction(icon, "Add a graph", self.navToolbar)
        # self.navToolbar.addAction(action)
        action.triggered.connect( self.addGraph.emit )
        self.navToolbar.insertAction(self.navToolbar.actions()[0], action)

        # Delete Graph Action
        pixmap = QPixmap( os.path.join( config.MOOSE_ICON_DIR,
            "delete_graph.png") )
        icon   = QIcon(pixmap)
        action  = QAction(icon, "Delete this graph", self.navToolbar)
        action.triggered.connect(self.delete)
        self.navToolbar.insertAction(self.navToolbar.actions()[1], action)

        #Toggle Grid Action
        pixmap = QPixmap(
                os.path.join( config.MOOSE_ICON_DIR, "grid.png" )
                )
        icon   = QIcon(pixmap)
        action  = QAction(icon, "Toggle Grid", self.navToolbar)
        action.triggered.connect(self.canvas.toggleGrid)
        self.navToolbar.insertAction(self.navToolbar.actions()[2], action)
        self.navToolbar.insertSeparator(self.navToolbar.actions()[3])


    @property
    def plotAll(self):
        return len(self.pathToLine) == 0

    def toggleLegend(self):
        if self.legend is not None:
            self.legend.set_visible(not self.legend.get_visible())
        self.canvas.draw()

    def getContextMenu(self):
        menu =  QMenu()
        # closeAction      = menu.addAction("Delete")
        exportCsvAction = menu.addAction("Export to CSV")
        exportCsvAction.triggered.connect(self.saveAllCsv)
        toggleLegendAction = menu.addAction("Toggle legend")
        toggleLegendAction.triggered.connect(self.toggleLegend)
        self.removeSubmenu = menu.addMenu("Remove")
        # configureAction.triggered.connect(self.configure)
        # self.connect(,SIGNAL("triggered()"),
        #                 self,SLOT("slotShow500x500()"))
        # self.connect(action1,SIGNAL("triggered()"),
        #                 self,SLOT("slotShow100x100()"))

        return menu

    def deleteGraph(self):
        """ If there is only one graph in the view, please don't delete it """
        print( "Deleting %s " % self.graph.path)
        moose.delete(self.graph.path)

    def delete(self, event):
        """FIXME: The last element should not be deleted """
        _logger.info("Deleting PlotWidget " )
        self.deleteGraph()
        self.close()
        self.widgetClosedSignal.emit(self)

    def configure(self, event):
        print("Displaying configure view!")
        self.plotView.getCentralWidget().show()

    @pyqtSlot(QtCore.QPoint)
    def contextMenuRequested(self,point):
        self.menu.exec_(self.mapToGlobal(point))

    def setModelRoot(self, path):
        self.modelRoot = path

    def setDataRoot(self, path):
        self.dataRoot = path
        #plotAllData()

    def genColorMap(self,tableObject):
        species = tableObject+'/info'
        colormap_file = open(os.path.join(config.settings[config.KEY_COLORMAP_DIR], 'rainbow2.pkl'),'rb')
        self.colorMap = pickle.load(colormap_file)
        colormap_file.close()
        hexchars = "0123456789ABCDEF"
        color = 'white'
        #Genesis model exist the path and color will be set but not xml file so bypassing
        #print "here genColorMap ",moose.exists(species)
        if moose.exists(species):
            color = moose.element(species).getField('color')
            if ((not isinstance(color,(list,tuple)))):
                if color.isdigit():
                    tc = int(color)
                    tc = (tc * 2 )
                    r,g,b = self.colorMap[tc]
                    color = "#"+ hexchars[r / 16] + hexchars[r % 16] + hexchars[g / 16] + hexchars[g % 16] + hexchars[b / 16] + hexchars[b % 16]
            else:
                color = 'white'
        return color

    def removePlot(self, table):
        print(("removePlot =>", table))
        moose.delete(table)
        self.plotAllData()

    def makeRemovePlotAction(self, label, table):
        action = self.removeSubmenu.addAction(label)
        action.triggered.connect(lambda: self.removePlot(table))
        return action

    def plotAllData(self):
        """Plot data from existing tables"""
        self.axesRef.lines = []
        self.pathToLine.clear()
        self.removeSubmenu.clear()
        if self.legend is not None:
            self.legend.set_visible(False)
        path = self.model.path
        modelroot = self.model.path
        time = moose.Clock('/clock').currentTime
        tabList = []
        #for tabId in moose.wildcardFind('%s/##[TYPE=Table]' % (path)):
        #harsha: policy graphs will be under /model/modelName need to change in kkit
        #for tabId in moose.wildcardFind('%s/##[TYPE=Table]' % (modelroot)):

        plotTables = list(moose.wildcardFind(self.graph.path + '/##[TYPE=Table]'))
        plotTables.extend(moose.wildcardFind(self.graph.path + '/##[TYPE=Table2]'))
        if len (plotTables) > 0:
            for tabId in plotTables:
                tab = moose.Table(tabId)
                #print("Table =>", tab)
                line_list=[]
                tableObject = tab.neighbors['requestOut']
                # Not a good way
                #tableObject.msgOut[0]
                if len(tableObject) > 0:

                    # This is the default case: we do not plot the same
                    # table twice. But in special cases we want to have
                    # multiple variations of the same table on different
                    # axes.
                    #
                    #Harsha: Adding color to graph for signalling model, check if given path has cubemesh or cylmesh

                    color = '#FFFFFF'
                    if moose.exists(tableObject[0].path + '/info'):
                        color = getColor(tableObject[0].path + '/info')
                        color = str(color[1].name()).upper()

                    lines = self.pathToLine[tab.path]
                    if len(lines) == 0:
                        #Harsha: pass color for plot if exist and not white else random color
                        #print "tab in plotAllData ",tab, tab.path,tab.name
                        field = tab.path.rpartition(".")[-1]
                        if field.endswith("[0]") or field.endswith("_0_"):
                            field = field[:-3]
                        # label = ( tableObject[0].path.partition(self.model.path + "/model[0]/")[-1]
                        #         + "."
                        #         + field
                        #         )
                        label = ( tableObject[0].path.rpartition("/")[-1]
                                + "."
                                + field
                                )
                        self.makeRemovePlotAction(label, tab)
                        if (color != '#FFFFFF'):
                            newLines = self.addTimeSeries(tab, label=label,color=color)
                        else:
                            newLines = self.addTimeSeries(tab, label=label)
                        self.pathToLine[tab.path].update(newLines)
                        for line in newLines:
                            self.lineToDataSource[line] = PlotDataSource(x='/clock', y=tab.path, z='')
                    else:
                        for line in lines:
                            dataSrc = self.lineToDataSource[line]
                            xSrc = moose.element(dataSrc.x)
                            ySrc = moose.element(dataSrc.y)
                            if isinstance(xSrc, moose.Clock):
                                ts = np.linspace(0, time, len(tab.vector))
                            elif isinstance(xSrc, moose.Table):
                                ts = xSrc.vector.copy()
                            line.set_data(ts, tab.vector.copy())
                    tabList.append(tab)

            # if len(tabList) > 0:
        self.legend = self.canvas.callAxesFn( 'legend'
                                            , loc='upper right'
                                            , prop= {'size' : 10 }
                                            # , bbox_to_anchor=(1.0, 0.5)
                                            , fancybox = True
                                            , shadow=False
                                            , ncol=1
                                            )
        if self.legend is not None:
            self.legend.draggable()
            self.legend.get_frame().set_alpha(0.5)
            self.legend.set_visible(True)


        self.canvas.draw()

            #     # leg = self.canvas.callAxesFn( 'legend'
            #     #                             , loc               ='upper right'
            #     #                             , prop              = {'size' : 10 }
            #     #                             # , bbox_to_anchor    = (0.5, -0.03)
            #     #                              , fancybox          = False
            #     #                             # , shadow            = True
            #     #                             , ncol              = 1
            #     #                             )
            #     # leg.draggable(False)
            #     # print(leg.get_window_extent())
            #             #leg = self.canvas.callAxesFn('legend')
            #             #leg = self.canvas.callAxesFn('legend',loc='upper left', fancybox=True, shadow=True)
            #             #global legend
            #             #legend =leg
            #     for legobj in leg.legendHandles:
            #         legobj.set_linewidth(5.0)
            #         legobj.set_picker(True)
            # else:
            #     print "returning as len tabId is zero ",tabId, " tableObject ",tableObject, " len ",len(tableObject)

    def togglePlot(self, event):
        #print "onclick",event1.artist.get_label()
        #harsha:To workout with double-event-registered on onclick event
        #http://stackoverflow.com/questions/16278358/double-event-registered-on-mouse-click-if-legend-is-outside-axes
        legline = event.artist
        for line in self.axesRef.lines:
            if line.get_label() == event.artist.get_label():
                vis = not line.get_visible()
                line.set_visible(vis)
                if vis:
                    legline.set_alpha(1.0)
                else:
                    legline.set_alpha(0.2)
                break
        self.canvas.draw()

    def addTimeSeries(self, table, *args, **kwargs):
        ts = np.linspace(0, moose.Clock('/clock').currentTime, len(table.vector))
        return self.canvas.plot(ts, table.vector, *args, **kwargs)

    def addRasterPlot(self, eventtable, yoffset=0, *args, **kwargs):
        """Add raster plot of events in eventtable.

        yoffset - offset along Y-axis.
        """
        y = np.ones(len(eventtable.vector)) * yoffset
        return self.canvas.plot(eventtable.vector, y, '|')

    def updatePlots(self):
        for path, lines in list(self.pathToLine.items()):
            element = moose.element(path)
            if isinstance(element, moose.Table2):
                tab = moose.Table2(path)
            else:
                tab = moose.Table(path)
            data = tab.vector
            ts = np.linspace(0, moose.Clock('/clock').currentTime, len(data))
            for line in lines:
                line.set_data(ts, data)
        self.canvas.draw()

    def extendXAxes(self, xlim):
        for axes in list(self.canvas.axes.values()):
            # axes.autoscale(False, axis='x', tight=True)
            axes.set_xlim(right=xlim)
            axes.autoscale_view(tight=True, scalex=True, scaley=True)
        self.canvas.draw()

    def rescalePlots(self):
        """This is to rescale plots at the end of simulation.

        ideally we should set xlim from simtime.
        """
        for axes in list(self.canvas.axes.values()):
            axes.autoscale(True, tight=True)
            axes.relim()
            axes.autoscale_view(tight=True,scalex=True,scaley=True)
        self.canvas.draw()


    def saveCsv(self, line, directory):
        """Save selected plot data in CSV file"""
        src = self.lineToDataSource[line]
        xSrc = moose.element(src.x)
        ySrc = moose.element(src.y)
        y = ySrc.vector.copy()
        if isinstance(xSrc, moose.Clock):
            x = np.linspace(0, xSrc.currentTime, len(y))
        elif isinstance(xSrc, moose.Table):
            x = xSrc.vector.copy()
        nameVec = ySrc.neighbors['requestOut']
        name = moose.element(nameVec[0]).name
        filename = str(directory)+'/'+'%s.csv' %(name)
        np.savetxt(filename, np.vstack((x, y)).transpose())
        print('Saved data from %s and %s in %s' % (xSrc.path, ySrc.path, filename))

    def saveAllCsv(self):
        """Save data for all currently plotted lines"""
        #Harsha: Plots were saved in GUI folder instead provided QFileDialog box to save to
        #user choose
        fileDialog2 = QtGui.QFileDialog(self)
        fileDialog2.setFileMode(QtGui.QFileDialog.Directory)
        fileDialog2.setWindowTitle('Select Directory to save plots')
        fileDialog2.setOptions(QtGui.QFileDialog.ShowDirsOnly)
        fileDialog2.setLabelText(QtGui.QFileDialog.Accept, self.tr("Save"))
        targetPanel = QtGui.QFrame(fileDialog2)
        targetPanel.setLayout(QtGui.QVBoxLayout())
        layout = fileDialog2.layout()
        layout.addWidget(targetPanel)
        if fileDialog2.exec_():
            directory = fileDialog2.directory().path()
            for line in list(self.lineToDataSource.keys()):
                        self.saveCsv(line,directory)


    def getMenus(self):
        if not hasattr(self, '_menus'):
            self._menus = []
            self.plotAllAction = QtGui.QAction('Plot all data', self)
            self.plotAllAction.triggered.connect(self.plotAllData)
            self.plotMenu = QtGui.QMenu('Plot')
            self.plotMenu.addAction(self.plotAllAction)
            self.saveAllCsvAction = QtGui.QAction('Save all data in CSV files', self)
            self.saveAllCsvAction.triggered.connect(self.saveAllCsv)
            self.plotMenu.addAction(self.saveAllCsvAction)
            self._menus.append(self.plotMenu)
        return self._menus
Example #4
0
class PlotWidget(QWidget):
    """A wrapper over CanvasWidget to handle additional MOOSE-specific
    stuff.

    modelRoot - path to the entire model our plugin is handling

    dataRoot - path to the container of data tables.

    pathToLine - map from moose path to Line2D objects in plot. Can
    one moose table be plotted multiple times? Maybe yes (e.g., when
    you want multiple other tables to be compared with the same data).

    lineToDataSource - map from Line2D objects to moose paths

    """

    widgetClosedSignal = pyqtSignal(object)
    addGraph = pyqtSignal(object)

    def __init__(self, model, graph, index, parentWidget, *args, **kwargs):
        super(PlotWidget, self).__init__()
        self.model = model
        self.graph = graph
        self.index = index

        self.menu = self.getContextMenu()
        self.setContextMenuPolicy(QtCore.Qt.CustomContextMenu)
        self.customContextMenuRequested.connect(self.contextMenuRequested)
        #  self.connect( self
        #  , SIGNAL("customContextMenuRequested(QPoint)")
        #  , self
        #  , SLOT("contextMenuRequested(QPoint)")
        #  )

        self.canvas = CanvasWidget(self.model, self.graph, self.index)
        self.canvas.setParent(self)
        self.navToolbar = NavigationToolbar(self.canvas, self)
        self.hackNavigationToolbar()
        self.canvas.mpl_connect('pick_event', self.togglePlot)
        layout = QGridLayout()
        layout.addWidget(self.navToolbar, 0, 0)
        layout.addWidget(self.canvas, 1, 0)
        self.setLayout(layout)
        self.pathToLine = defaultdict(set)
        self.lineToDataSource = {}
        self.axesRef = self.canvas.addSubplot(1, 1)
        self.legend = None
        desktop = QApplication.desktop()
        self.setMinimumSize(desktop.screenGeometry().width() // 4,
                            desktop.screenGeometry().height() // 3)
        self.canvas.updateSignal.connect(self.plotAllData)
        self.plotAllData()

    def hackNavigationToolbar(self):
        # ADD Graph Action
        pixmap = QtGui.QPixmap(
            os.path.join(config.MOOSE_ICON_DIR, 'add_graph.png'))
        icon = QtGui.QIcon(pixmap)
        action = QAction(icon, "Add a graph", self.navToolbar)
        # self.navToolbar.addAction(action)
        action.triggered.connect(self.addGraph.emit)
        self.navToolbar.insertAction(self.navToolbar.actions()[0], action)

        # Delete Graph Action
        pixmap = QtGui.QPixmap(
            os.path.join(config.MOOSE_ICON_DIR, "delete_graph.png"))
        icon = QtGui.QIcon(pixmap)
        action = QAction(icon, "Delete this graph", self.navToolbar)
        action.triggered.connect(self.delete)
        self.navToolbar.insertAction(self.navToolbar.actions()[1], action)

        #Toggle Grid Action
        pixmap = QtGui.QPixmap(os.path.join(config.MOOSE_ICON_DIR, "grid.png"))
        icon = QtGui.QIcon(pixmap)
        action = QAction(icon, "Toggle Grid", self.navToolbar)
        action.triggered.connect(self.canvas.toggleGrid)
        self.navToolbar.insertAction(self.navToolbar.actions()[2], action)
        self.navToolbar.insertSeparator(self.navToolbar.actions()[3])

    @property
    def plotAll(self):
        return len(self.pathToLine) == 0

    def toggleLegend(self):
        if self.legend is not None:
            self.legend.set_visible(not self.legend.get_visible())
        self.canvas.draw()

    def getContextMenu(self):
        menu = QMenu()
        # closeAction      = menu.addAction("Delete")
        exportCsvAction = menu.addAction("Export to CSV")
        exportCsvAction.triggered.connect(self.saveAllCsv)
        toggleLegendAction = menu.addAction("Toggle legend")
        toggleLegendAction.triggered.connect(self.toggleLegend)
        self.removeSubmenu = menu.addMenu("Remove")
        # configureAction.triggered.connect(self.configure)
        # self.connect(,SIGNAL("triggered()"),
        #                 self,SLOT("slotShow500x500()"))
        # self.connect(action1,SIGNAL("triggered()"),
        #                 self,SLOT("slotShow100x100()"))

        return menu

    def deleteGraph(self):
        """ If there is only one graph in the view, please don't delete it """
        print("Deleting %s " % self.graph.path)
        moose.delete(self.graph.path)

    def delete(self, event):
        """FIXME: The last element should not be deleted """
        _logger.info("Deleting PlotWidget ")
        self.deleteGraph()
        self.close()
        self.widgetClosedSignal.emit(self)

    def configure(self, event):
        print("Displaying configure view!")
        self.plotView.getCentralWidget().show()

    @pyqtSlot(QtCore.QPoint)
    def contextMenuRequested(self, point):
        self.menu.exec_(self.mapToGlobal(point))

    def setModelRoot(self, path):
        self.modelRoot = path

    def setDataRoot(self, path):
        self.dataRoot = path
        #plotAllData()

    def genColorMap(self, tableObject):
        species = tableObject + '/info'
        colormap_file = open(
            os.path.join(config.settings[config.KEY_COLORMAP_DIR],
                         'rainbow2.pkl'), 'rb')
        self.colorMap = pickle.load(colormap_file)
        colormap_file.close()
        hexchars = "0123456789ABCDEF"
        color = 'white'
        #Genesis model exist the path and color will be set but not xml file so bypassing
        #print "here genColorMap ",moose.exists(species)
        if moose.exists(species):
            color = moose.element(species).getField('color')
            if ((not isinstance(color, (list, tuple)))):
                if color.isdigit():
                    tc = int(color)
                    tc = (tc * 2)
                    r, g, b = self.colorMap[tc]
                    color = "#" + hexchars[r / 16] + hexchars[
                        r % 16] + hexchars[g / 16] + hexchars[
                            g % 16] + hexchars[b / 16] + hexchars[b % 16]
            else:
                color = 'white'
        return color

    def removePlot(self, table):
        print(("removePlot =>", table))
        moose.delete(table)
        self.plotAllData()

    def makeRemovePlotAction(self, label, table):
        action = self.removeSubmenu.addAction(label)
        action.triggered.connect(lambda: self.removePlot(table))
        return action

    def plotAllData(self):
        """Plot data from existing tables"""
        self.axesRef.lines = []
        self.pathToLine.clear()
        self.removeSubmenu.clear()
        if self.legend is not None:
            self.legend.set_visible(False)
        path = self.model.path
        modelroot = self.model.path
        time = moose.Clock('/clock').currentTime
        tabList = []
        #for tabId in moose.wildcardFind('%s/##[TYPE=Table]' % (path)):
        #harsha: policy graphs will be under /model/modelName need to change in kkit
        #for tabId in moose.wildcardFind('%s/##[TYPE=Table]' % (modelroot)):

        plotTables = list(
            moose.wildcardFind(self.graph.path + '/##[TYPE=Table]'))
        plotTables.extend(
            moose.wildcardFind(self.graph.path + '/##[TYPE=Table2]'))
        if len(plotTables) > 0:
            for tabId in plotTables:
                tab = moose.Table(tabId)
                #print("Table =>", tab)
                line_list = []
                tableObject = tab.neighbors['requestOut']
                # Not a good way
                #tableObject.msgOut[0]
                if len(tableObject) > 0:

                    # This is the default case: we do not plot the same
                    # table twice. But in special cases we want to have
                    # multiple variations of the same table on different
                    # axes.
                    #
                    #Harsha: Adding color to graph for signalling model, check if given path has cubemesh or cylmesh

                    color = '#FFFFFF'
                    if moose.exists(tableObject[0].path + '/info'):
                        color = getColor(tableObject[0].path + '/info')
                        color = str(color[1].name()).upper()

                    lines = self.pathToLine[tab.path]
                    if len(lines) == 0:
                        #Harsha: pass color for plot if exist and not white else random color
                        #print "tab in plotAllData ",tab, tab.path,tab.name
                        field = tab.path.rpartition(".")[-1]
                        if field.endswith("[0]") or field.endswith("_0_"):
                            field = field[:-3]
                        # label = ( tableObject[0].path.partition(self.model.path + "/model[0]/")[-1]
                        #         + "."
                        #         + field
                        #         )
                        label = (tableObject[0].path.rpartition("/")[-1] +
                                 "." + field)
                        self.makeRemovePlotAction(label, tab)
                        if (color != '#FFFFFF'):
                            newLines = self.addTimeSeries(tab,
                                                          label=label,
                                                          color=color)
                        else:
                            newLines = self.addTimeSeries(tab, label=label)
                        self.pathToLine[tab.path].update(newLines)
                        for line in newLines:
                            self.lineToDataSource[line] = PlotDataSource(
                                x='/clock', y=tab.path, z='')
                    else:
                        for line in lines:
                            dataSrc = self.lineToDataSource[line]
                            xSrc = moose.element(dataSrc.x)
                            ySrc = moose.element(dataSrc.y)
                            if isinstance(xSrc, moose.Clock):
                                ts = np.linspace(0, time, len(tab.vector))
                            elif isinstance(xSrc, moose.Table):
                                ts = xSrc.vector.copy()
                            line.set_data(ts, tab.vector.copy())
                    tabList.append(tab)

            # if len(tabList) > 0:
        self.legend = self.canvas.callAxesFn(
            'legend',
            loc='upper right',
            prop={'size': 10}
            # , bbox_to_anchor=(1.0, 0.5)
            ,
            fancybox=True,
            shadow=False,
            ncol=1)
        if self.legend is not None:
            self.legend.draggable()
            self.legend.get_frame().set_alpha(0.5)
            self.legend.set_visible(True)

        self.canvas.draw()

        #     # leg = self.canvas.callAxesFn( 'legend'
        #     #                             , loc               ='upper right'
        #     #                             , prop              = {'size' : 10 }
        #     #                             # , bbox_to_anchor    = (0.5, -0.03)
        #     #                              , fancybox          = False
        #     #                             # , shadow            = True
        #     #                             , ncol              = 1
        #     #                             )
        #     # leg.draggable(False)
        #     # print(leg.get_window_extent())
        #             #leg = self.canvas.callAxesFn('legend')
        #             #leg = self.canvas.callAxesFn('legend',loc='upper left', fancybox=True, shadow=True)
        #             #global legend
        #             #legend =leg
        #     for legobj in leg.legendHandles:
        #         legobj.set_linewidth(5.0)
        #         legobj.set_picker(True)
        # else:
        #     print "returning as len tabId is zero ",tabId, " tableObject ",tableObject, " len ",len(tableObject)

    def togglePlot(self, event):
        #print "onclick",event1.artist.get_label()
        #harsha:To workout with double-event-registered on onclick event
        #http://stackoverflow.com/questions/16278358/double-event-registered-on-mouse-click-if-legend-is-outside-axes
        legline = event.artist
        for line in self.axesRef.lines:
            if line.get_label() == event.artist.get_label():
                vis = not line.get_visible()
                line.set_visible(vis)
                if vis:
                    legline.set_alpha(1.0)
                else:
                    legline.set_alpha(0.2)
                break
        self.canvas.draw()

    def addTimeSeries(self, table, *args, **kwargs):
        ts = np.linspace(0,
                         moose.Clock('/clock').currentTime, len(table.vector))
        return self.canvas.plot(ts, table.vector, *args, **kwargs)

    def addRasterPlot(self, eventtable, yoffset=0, *args, **kwargs):
        """Add raster plot of events in eventtable.

        yoffset - offset along Y-axis.
        """
        y = np.ones(len(eventtable.vector)) * yoffset
        return self.canvas.plot(eventtable.vector, y, '|')

    def updatePlots(self):
        for path, lines in list(self.pathToLine.items()):
            element = moose.element(path)
            if isinstance(element, moose.Table2):
                tab = moose.Table2(path)
            else:
                tab = moose.Table(path)
            data = tab.vector
            ts = np.linspace(0, moose.Clock('/clock').currentTime, len(data))
            for line in lines:
                line.set_data(ts, data)
        self.canvas.draw()

    def extendXAxes(self, xlim):
        for axes in list(self.canvas.axes.values()):
            # axes.autoscale(False, axis='x', tight=True)
            axes.set_xlim(right=xlim)
            axes.autoscale_view(tight=True, scalex=True, scaley=True)
        self.canvas.draw()

    def rescalePlots(self):
        """This is to rescale plots at the end of simulation.

        ideally we should set xlim from simtime.
        """
        for axes in list(self.canvas.axes.values()):
            axes.autoscale(True, tight=True)
            axes.relim()
            axes.autoscale_view(tight=True, scalex=True, scaley=True)
        self.canvas.draw()

    def saveCsv(self, line, directory):
        """Save selected plot data in CSV file"""
        src = self.lineToDataSource[line]
        xSrc = moose.element(src.x)
        ySrc = moose.element(src.y)
        y = ySrc.vector.copy()
        if isinstance(xSrc, moose.Clock):
            x = np.linspace(0, xSrc.currentTime, len(y))
        elif isinstance(xSrc, moose.Table):
            x = xSrc.vector.copy()
        nameVec = ySrc.neighbors['requestOut']
        name = moose.element(nameVec[0]).name
        filename = str(directory) + '/' + '%s.csv' % (name)
        np.savetxt(filename, np.vstack((x, y)).transpose())
        print('Saved data from %s and %s in %s' %
              (xSrc.path, ySrc.path, filename))

    def saveAllCsv(self):
        """Save data for all currently plotted lines"""
        #Harsha: Plots were saved in GUI folder instead provided QFileDialog box to save to
        #user choose
        fileDialog2 = QFileDialog(self)
        fileDialog2.setFileMode(QFileDialog.Directory)
        fileDialog2.setWindowTitle('Select Directory to save plots')
        fileDialog2.setOptions(QFileDialog.ShowDirsOnly)
        fileDialog2.setLabelText(QFileDialog.Accept, self.tr("Save"))
        targetPanel = QFrame(fileDialog2)
        targetPanel.setLayout(QVBoxLayout())
        layout = fileDialog2.layout()
        layout.addWidget(targetPanel)
        if fileDialog2.exec_():
            directory = fileDialog2.directory().path()
            for line in list(self.lineToDataSource.keys()):
                self.saveCsv(line, directory)

    def getMenus(self):
        if not hasattr(self, '_menus'):
            self._menus = []
            self.plotAllAction = QAction('Plot all data', self)
            self.plotAllAction.triggered.connect(self.plotAllData)
            self.plotMenu = QMenu('Plot')
            self.plotMenu.addAction(self.plotAllAction)
            self.saveAllCsvAction = QAction('Save all data in CSV files', self)
            self.saveAllCsvAction.triggered.connect(self.saveAllCsv)
            self.plotMenu.addAction(self.saveAllCsvAction)
            self._menus.append(self.plotMenu)
        return self._menus