Viewbox configuration with Time on X-axis (Live update without changing the scale on X-aixs)

1,105 views
Skip to first unread message

Zaim

unread,
Aug 28, 2016, 9:42:54 PM8/28/16
to pyqtgraph
I have been using a software(RTK) for plotting GPS data and is very used to it. Now I needed few more options in plotting so decided to use pyqtgraph to create my own live plots. I am little bit familiar with pyqtgraph but haven't used it thoroughly and kinda stuck now.

Screen shot of software (RTK) :


You can see the Time on Xaxis, As the plot move forward the Scale on the X-axis remain same but the time labelling changes. The old points move out of the screen from the left side. If we want to change time scale on X-axis, we can right click on graph pressed and move mouse sideways to change scaling but the overall function remain the same i.e. live plotting keeps on plotting to right and latest points will always be in the view range. see below for the image.

 
So in short I want to achieve 02 things:
1. Time scaling to be constant on X-axis and at same time live plotting adding new points on the right side pushing old points to left giving the effect of moving x-axis.
2. Ability to change the scale of X-axis with right click without killing the auto updating i.e. live plotting adding new points on the right side pushing old points to left giving the effect of moving x-axis

I have been able to create time axis with 3000 data points. With auto update/scale enabled, the points got added to right and X-axis re-scaled every-time to accommodate new points. When I get all the 3000 points the scaling become constant and the graph looks more to my liking.

    now with more points:



The issue is whenever I click on the graph for zoom,scaling etc. the autoscale got cancelled and i have to re-enable it. Also I don't want all 3000 points to be shown all the time, which mean I need some constant scaling as used by RTK software.

in short want to add:
1. X-axis fixed scaling. (for both cases i.e. whether I have 3000 points or not)
2. I can change scale on x-axis by right click and moving sideways but that also kills the update and I have to re-enable it.

CODE RELATED TO CREATING PLOT:

EPOCH       = datetime(2016, 1, 1, 0, 0) # starting point of date
TS_MULT_us  = 1e3 

def int2dt(ts, ts_mult=TS_MULT_us):
    """Convert seconds value into datatime struct which can be used for x-axis labeeling"""
    return(datetime.utcfromtimestamp(float(ts)/ts_mult))

class CAxisTime(pg.AxisItem):
    """Over riding the tickString method by extending the class"""
    # @param[in] values List of time.
    # @param[in] scale Not used.
    # @param[in] spacing Not used.
    def tickStrings(self, values, scale, spacing):
      """Generate the string labeeling of X-axis from the seconds value of Y-axis"""
      # sending a list of values in format "HH:MM:SS.SS" generated from Total seconds.      
      return [(int2dt(value).strftime("%H:%M:%S.%f"))[:-4] for value in values]


class GraphWindow(QMainWindow):
    def __init__(self,data,time,data_points, parent= None):
        ''' initialization of variables'''
        QMainWindow.__init__(self,parent)        
        self.layer            = ''
        self.layer_info       = ''
        self.enabled          = False
        self.gw_comm          = GraphWindowCommunication()
        self.connection       = False
        self.layer_set        = []
        self.layer_set_vector = []
        self.data             = data
        self.time             = time        
        self.dd               = True
        self.data_points      = data_points
        self.buffer           = deque(maxlen=10)
        for x in range (1,10):
          self.buffer.appendleft(x)
              self.setupGui() 
 
    def setupGui(self):
        """Creating GUI plot window"""
        frame                    = QFrame(self)
        self.setCentralWidget(frame)
        self.grid_layout        = QGridLayout(frame)
        self.value_display      = QLineEdit()        
        self.stackedWidget      = QStackedWidget()
        pg.setConfigOption('background', 'w')
        pg.setConfigOption('foreground', 'k')
        self.axis               = CAxisTime(orientation='bottom')
        self.pqg_plot_widget    = pg.PlotWidget(title="Altitude (datapoints = "+str(self.data_points)+" )",axisItems={'bottom': self.axis},left="Y-axis (meters)",bottom= "Time ")
        self.pqg_plot_item      = self.pqg_plot_widget.getPlotItem()
        self.pqg_plot_viewbox   = self.pqg_plot_widget.getViewBox()
        self.pqg_plot_viewbox.setMouseMode(pg.ViewBox.PanMode)        
        self.pqg_plot_item.showGrid(x = True, y = True, alpha = 0.3)
        self.pqg_plot_item.showAxis('bottom',True)
        self.pqg_plot_item_data = self.pqg_plot_item.plot(pen=(211,211,211),symbolPen='w',symbolSize=5,symbolBrush=(0,0,255))
        self.stackedWidget.addWidget(self.pqg_plot_widget)
        self.grid_layout.addWidget(self.value_display)
        self.grid_layout.addWidget(self.stackedWidget)
        self.value_display.setMinimumWidth(250)        
        self.pqg_plot_item_data.setData(self.data)
        self.setWindowTitle('Altitude')
        self.timer = QTimer()
        self.timer.timeout.connect(self.update)
        self.timer.start(1000)

    def update(self):
        """Update every Minute """
        self.pqg_plot_item_data.setData(y=list(self.data),x=list(self.time))
        self.value_display.setText("Current Altitude = "+str(self.data[-1]))


Just to add, I am using pyqtgraph in QGIS software. 

Zaim

unread,
Aug 29, 2016, 10:17:24 PM8/29/16
to pyqtgraph

Ok I have worked out how to keep the x-axis time spacing constant by using setRange(). So now whether I have 1 sample or 3000 samples view range remain constant.
def update(self):
        """Update every Minute """
        self.pqg_plot_item_data.setData(y=list(self.data),x=list(self.time))
    self.pqg_plot_viewbox.setRange(xRange=(self.time[-1]-1000*20,self.time[-1]))  # approx 20 sec range
    self.value_display.setText("Current Altitude = "+str(self.data[-1]))



The issue remain is:

1. How to notify the plot if I change the range by right clicking and dragging side ways. Currently the graph is being updated every second and hence any right click dragging is lost due to every-second update. If I can know the change in range on x-axis, I can update the x-axis with new range.
Reply all
Reply to author
Forward
0 new messages