Source code for optimeed.visualize.graphs.graphVisual

from .traceVisual import TraceVisual
from .pyqtgraphRedefine import myLegend, myAxis
from .pyqtgraph import TextItem
from optimeed.core.tools import printIfShown, SHOW_WARNING
from PyQt5 import QtGui
from optimeed.core.color_palette import default_palette


[docs]class GraphVisual: """Provide an interface to a graph. A graph contains traces.""" def __init__(self, theWidgetGraphVisual): """ :param theWidgetGraphVisual: :class:`~optimeed.visualize.gui.widgets.widget_graphs_visual.widget_graphs_visual` """ self.theWidgetGraphVisual = theWidgetGraphVisual self.traceVisuals = dict() self.theWGPlot = self.theWidgetGraphVisual.canvasWidget.addPlot(axisItems={'bottom': myAxis(orientation='bottom'), 'left': myAxis(orientation='left')}) # Class PLOT ITEM # self.theWGPlot.disableAutoRange() self.theWGPlot.legend = myLegend(is_light=self.theWidgetGraphVisual.is_light) self.theWGPlot.legend.setParentItem(self.theWGPlot.vb) self.theWGPlot.showGrid(x=True, y=True) self.set_fontTicks(11) self.palette = default_palette # Set font label if self.theWidgetGraphVisual.is_light: label_color = '#000' else: label_color = '#FFF' self.labelStyle = None self.set_fontLabel(12, label_color)
[docs] def set_fontTicks(self, fontSize, fontname=None): """ Set font of the ticks :param fontSize: Size of the font :param fontname: Name of the font """ font = QtGui.QFont() font.setPointSizeF(fontSize) if fontname is not None: font.setFamily(fontname) self.theWGPlot.getAxis("bottom").tickFont = font self.theWGPlot.getAxis("left").tickFont = font
[docs] def set_numberTicks(self, number, axis): """ Set the number of ticks to be displayed :param number: Number of ticks for the axis :param axis: Axis (string, "bottom", "left", "right", "top") :return: """ self.theWGPlot.getAxis(axis).set_number_ticks(number)
[docs] def set_fontLabel(self, fontSize, color='#000', fontname=None): """Set font of the axis labels :param fontSize: font size :param color: color in hexadecimal (str) :param fontname: name of the font""" self.labelStyle = {'font-size': str(fontSize) + 'pt', 'color': color, "font-family": fontname}
[docs] def get_legend(self) -> myLegend: """ Get the legend""" return self.theWGPlot.legend
[docs] def get_axis(self, axis) -> myAxis: """ Get the axis :param axis: Axis (string, "bottom", "left", "right", "top") :return: axis object """ return self.theWGPlot.getAxis(axis)
[docs] def set_fontLegend(self, font_size, font_color, fontname=None): self.get_legend().set_font(font_size, font_color, fontname)
[docs] def set_label_pos(self, orientation, x_offset=0, y_offset=0): self.theWGPlot.getAxis(orientation).set_label_pos(orientation, x_offset, y_offset)
[docs] def set_color_palette(self, palette): self.palette = palette self.apply_palette()
[docs] def apply_palette(self): numb_color_to_set = len(self.get_all_traces()) theColors = self.palette(numb_color_to_set) for i, trace in enumerate(self.get_all_traces().values()): if trace.get_color() is None: trace.set_color(theColors[i])
[docs] def hide_axes(self): self.theWGPlot.showGrid(x=False, y=False) self.theWGPlot.getAxis("bottom").hide() self.theWGPlot.getAxis("left").hide()
[docs] def add_feature(self, theFeature): """To add any pyqtgraph item to the graph""" self.theWGPlot.addItem(theFeature)
[docs] def add_text(self, theStr, pos_x, pos_y, color=None, font=None): """Convenient function to create and add a TextItem (see pyqtgraph doc) to the current graph :param theStr: text as string :param pos_x: x_coordinate as float :param pos_y: y_coordinate as float :param color: color of the text (tuple or hex) :param font: QFont for the text """ if font is None: font = QtGui.QFont("Arial", 10) if color is None: if self.theWidgetGraphVisual.is_light: color = '#000' else: color = '#FFF' color = QtGui myText = TextItem(theStr, color=color) myText.setPos(pos_x, pos_y) myText.setFont(font) myText.setParentItem(self.theWGPlot.vb) self.add_feature(myText)
[docs] def remove_feature(self, theFeature): """To remove any pyqtgraph item from the graph""" self.theWGPlot.removeItem(theFeature)
[docs] def add_data(self, idGraph, theData): theTrace = TraceVisual(theData, self.theWGPlot, highlight_last=self.theWidgetGraphVisual.highlight_last) self.add_trace(idGraph, theTrace) if len(self.traceVisuals) <= 1: self.set_graph_properties(theTrace)
[docs] def set_graph_properties(self, theTrace): """This function is automatically called on creation of the graph""" self.theWGPlot.setLabel('bottom', text=theTrace.theData.get_x_label(), **self.labelStyle) self.theWGPlot.setLabel('left', text=theTrace.theData.get_y_label(), **self.labelStyle) self.set_lims(theTrace.theData.get_xlim(), theTrace.theData.get_ylim())
[docs] def set_lims(self, xlim, ylim): """Set limits of the graphs, xlim or ylim = [val_low, val_high]. Or None.""" # if xlim is not None: # self.theWGPlot.setLimits(xMin=xlim[0], xMax=xlim[1]) # if ylim is not None: # self.theWGPlot.setLimits(yMin=ylim[0], yMax=ylim[1]) # if xlim is not None or ylim is not None: self.theWGPlot.setRange(xRange=xlim, yRange=ylim)
# self.theWGPlot.setAutoVisible(x=xlim is None, y=ylim is None)
[docs] def add_trace(self, idTrace, theTrace): """Add a :class:`~optimeed.visualize.gui.widgets.graphsVisualWidget.TraceVisual.TraceVisual` to the graph, with index idTrace""" self.traceVisuals[idTrace] = theTrace theTrace.thePlotItem.sigPointsClicked.connect(self.theWidgetGraphVisual.on_click) # Connect the function "on click"
[docs] def set_legend(self): """Set default legend options (color and font)""" if self.theWidgetGraphVisual.is_light: legend_color = '#111' else: legend_color = '#DDD' self.set_fontLegend(10, legend_color)
[docs] def set_title(self, titleName, **kwargs): """Set title of the graph :param titleName: title to set """ self.theWGPlot.setTitle(title=titleName, **kwargs)
[docs] def get_trace(self, idTrace) -> TraceVisual: """Return the :class:`~optimeed.visualize.gui.widgets.graphsVisualWidget.TraceVisual.TraceVisual` correspondong to the index idTrace""" return self.traceVisuals[idTrace]
[docs] def get_all_traces(self): """Return a dictionary {idtrace: :class:`~optimeed.visualize.gui.widgets.graphsVisualWidget.TraceVisual.TraceVisual`}.""" return self.traceVisuals
[docs] def delete_trace(self, idTrace): """Delete the trace of index idTrace""" try: self.theWGPlot.removeItem(self.traceVisuals[idTrace].thePlotItem) self.traceVisuals.pop(idTrace) # self.signal_must_update.emit() except KeyError: printIfShown("Trace already deleted", SHOW_WARNING)
[docs] def delete(self): """Delete the graph""" self.theWGPlot.deleteLater() self.theWidgetGraphVisual.canvasWidget.centralWidget.layout.removeItem(self.theWGPlot)
[docs] def linkXToGraph(self, graph): """Link the axis of the current graph to an other :class:`GraphVisual`""" self.theWGPlot.setXLink(graph.theWGPlot)
[docs] def update(self): """Update the traces contained in the graph""" for trace in self.get_all_traces().values(): self.set_graph_properties(trace) trace.signal_must_update.emit()
[docs] def fast_update(self): """Same as :meth:`~GraphVisual.update` but faster. This is NOT thread safe (cannot be called a second time before finishing operation)""" for trace in self.get_all_traces().values(): trace.updateTrace()
[docs] def axis_equal(self): self.theWGPlot.vb.setAspectLocked(True)
[docs] def log_mode(self, x=False, y=False): self.theWGPlot.setLogMode(x, y)
[docs] def grid_off(self): """Turn off grid""" self.theWGPlot.showGrid(x=False, y=False)