Question

Can some one help me on how do I create a two axis plots w.r.t time using pyqtgraph. For example plot velocity versus torque against time i.e. time is x axis and is moving and velocity is plotted against torque as a function of time.

from pyqtgraph.Qt import QtGui, QtCore
import numpy as np
import pyqtgraph as pg
from pyqtgraph.ptime import time
from numpy import *
from socket import *
import time

app = QtGui.QApplication([])

x = [0,1,2,3,4,5,6,7,8,9];
y = [0,2,4,6,8,10,12,16,18,20];

pg.mkQApp()
pw = pg.PlotWidget()
pw.show()

for i in range(1,20):
    p1 = pw.plotItem
    p2 = pg.ViewBox()
    p1.showAxis('right')
    p1.scene().addItem(p2)
    p2.setGeometry(p1.vb.sceneBoundingRect())
    p1.getAxis('right').linkToView(p2)
    p2.setXLink(p1)
    x.append(i)
    y.append(i*2)
    p1.plot(x)
    #time.sleep(1)    
    p2.addItem(p1.plot(y, pen='b'))
    #time.sleep(1)
Was it helpful?

Solution

Based on the discussion in this forum for this question, the below code snippet is what we were looking for and now is satifying our requirement. This is just a sample code which will be eventually modified and integrated to the intended application. Once again I appreciate the discussion in this forum which helped us in arriving at the right solution.

from pyqtgraph.Qt import QtGui, QtCore
import numpy as np
import pyqtgraph as pg
from pyqtgraph.ptime import time
from numpy import *
from socket import *
import time

app = QtGui.QApplication([])

plot_x = [0,1,2,3,4,5,6,7,8,9];
plot_y = [0,2,4,6,8,10,12,14,16,18];

loopcount = 0;

pg.mkQApp()
pw = pg.PlotWidget()
pw.show()
p1 = pw.plotItem
p2 = pg.ViewBox()
p1.showAxis('right')
p1.scene().addItem(p2)
p2.setGeometry(p1.vb.sceneBoundingRect())
p1.getAxis('right').linkToView(p2)
p2.setXLink(p1)

def update():
    global pw, pg, loopcount, plot_x, plot_y, p1, p2

    p1.setXRange(loopcount*10, loopcount*10+100)
    p2.setXRange(loopcount*10, loopcount*10+100)

    p1.plot(plot_x)
    p2.addItem(p1.plot(plot_y, pen='b'))

    loopcount = loopcount + 1

    for update in range(loopcount*10, loopcount*10+100):
        plot_x.append(update*loopcount)
        plot_y.append(update*loopcount*2)

timer = QtCore.QTimer()
timer.timeout.connect(update)
timer.start(50)

Improved code based on Luke's comment

from pyqtgraph.Qt import QtGui, QtCore
import numpy as np
import pyqtgraph as pg
from pyqtgraph.ptime import time
from numpy import *
from socket import *
import time

app = QtGui.QApplication([])

plot_param1 = [0,2,4,6,8,10,12,14,16,18];
plot_param2 = [0,3,6,9,12,15,18,21,24,27];

samplesize = 10;
samples     = range(0,samplesize)
framecount = 0;

pg.mkQApp()
pw = pg.PlotWidget()
pw.show()
p1 = pw.plotItem
p2 = pg.ViewBox()
p1.showAxis('right')
p1.scene().addItem(p2)
p2.setGeometry(p1.vb.sceneBoundingRect())
p1.getAxis('right').linkToView(p2)
p2.setXLink(p1)

def update():
    global pw, pg, framecount, plot_param1, plot_param2, p1, p2, samples, samplesize

    p1.plot(samples, plot_param1)
    p2.addItem(p1.plot(samples, plot_param2, pen='b'))

    pw.autoRange()

    p1.setXRange(framecount*samplesize, framecount*samplesize+samplesize)
    p2.setXRange(framecount*samplesize, framecount*samplesize+samplesize)

    if framecount == 0:
        flushloop = samplesize
    else:
        flushloop = samplesize+1

    for flush in range(1,flushloop):
        plot_param1.pop(0)
        plot_param2.pop(0)
        samples.pop(0)

    # below code is to prepare for next sample
    framecount = framecount + 1

    for update in range(framecount*samplesize, framecount*samplesize+samplesize):
        plot_param1.append(update*framecount*2)
        plot_param2.append(update*framecount*3)
        samples.append(update)

timer = QtCore.QTimer()
timer.timeout.connect(update)
timer.start(50)

OTHER TIPS

What about something like this?

from pyqtgraph.Qt import QtGui, QtCore
import numpy as np
import pyqtgraph as pg
pg.setConfigOptions(antialias=True)
pg.setConfigOption('background', '#c7c7c7')
pg.setConfigOption('foreground', '#000000')
from pyqtgraph.ptime import time
app = QtGui.QApplication([])

p = pg.plot()
p.setXRange(0,10)
p.setYRange(-10,10)
p.setWindowTitle('Current-Voltage')
p.setLabel('bottom', 'Bias', units='V', **{'font-size':'20pt'})
p.getAxis('bottom').setPen(pg.mkPen(color='#000000', width=3))
p.setLabel('left', 'Current', units='A',
            color='#c4380d', **{'font-size':'20pt'})
p.getAxis('left').setPen(pg.mkPen(color='#c4380d', width=3))
curve = p.plot(x=[], y=[], pen=pg.mkPen(color='#c4380d'))
p.showAxis('right')
p.setLabel('right', 'Dynamic Resistance', units="<font>&Omega;</font>",
            color='#025b94', **{'font-size':'20pt'})
p.getAxis('right').setPen(pg.mkPen(color='#025b94', width=3))

p2 = pg.ViewBox()
p.scene().addItem(p2)
p.getAxis('right').linkToView(p2)
p2.setXLink(p)
p2.setYRange(-10,10)

curve2 = pg.PlotCurveItem(pen=pg.mkPen(color='#025b94', width=1))
p2.addItem(curve2)

def updateViews():
    global p2
    p2.setGeometry(p.getViewBox().sceneBoundingRect())
    p2.linkedViewChanged(p.getViewBox(), p2.XAxis)

updateViews()
p.getViewBox().sigResized.connect(updateViews)

x = np.arange(0, 10.01,0.01)
data = 5+np.sin(30*x)
data2 = -5+np.cos(30*x)
ptr = 0
lastTime = time()
fps = None

def update():
    global p, x, curve, data, curve2, data2, ptr, lastTime, fps
    if ptr < len(x):
        curve.setData(x=x[:ptr], y=data[:ptr])
        curve2.setData(x=x[:ptr], y=data2[:ptr])
        ptr += 1
        now = time()
        dt = now - lastTime
        lastTime = now
        if fps is None:
            fps = 1.0/dt
        else:
            s = np.clip(dt*3., 0, 1)
            fps = fps * (1-s) + (1.0/dt) * s
        p.setTitle('%0.2f fps' % fps)
    else:
        ptr = 0
    app.processEvents()  ## force complete redraw for every plot.  Try commenting out to see if a different in speed occurs.
timer = QtCore.QTimer()
timer.timeout.connect(update)
timer.start(0)



## Start Qt event loop unless running in interactive mode.
if __name__ == '__main__':
    import sys
    if (sys.flags.interactive != 1) or not hasattr(QtCore, 'PYQT_VERSION'):
        QtGui.QApplication.instance().exec_()
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top