I am running into an error with pyqtgraph. I am trying to plot a 3D scatterplot with OpenGL. However, when I run my code, I get a blank plot and this output:
|==============================>>
| Traceback (most recent call last):
| File "C:\Users\T\anaconda3\lib\runpy.py", line 197, in _run_module_as_main
| return _run_code(code, main_globals, None,
| File "C:\Users\T\anaconda3\lib\runpy.py", line 87, in _run_code
| exec(code, run_globals)
| File "C:\Users\T\Anaconda3\Lib\site-packages\spyder_kernels\console\__main__.py", line 23, in <module>
| start.main()
| File "C:\Users\T\Anaconda3\Lib\site-packages\spyder_kernels\console\start.py", line 328, in main
| kernel.start()
| File "C:\Users\T\Anaconda3\Lib\site-packages\ipykernel\kernelapp.py", line 677, in start
| self.io_loop.start()
| File "C:\Users\T\Anaconda3\Lib\site-packages\tornado\platform\asyncio.py", line 199, in start
| self.asyncio_loop.run_forever()
| File "C:\Users\T\anaconda3\lib\asyncio\base_events.py", line 601, in run_forever
| self._run_once()
| File "C:\Users\T\anaconda3\lib\asyncio\base_events.py", line 1905, in _run_once
| handle._run()
| File "C:\Users\T\anaconda3\lib\asyncio\events.py", line 80, in _run
| self._context.run(self._callback, *self._args)
| File "C:\Users\T\Anaconda3\Lib\site-packages\ipykernel\kernelbase.py", line 471, in dispatch_queue
| await self.process_one()
| File "C:\Users\T\Anaconda3\Lib\site-packages\ipykernel\kernelbase.py", line 460, in process_one
| await dispatch(*args)
| File "C:\Users\T\Anaconda3\Lib\site-packages\ipykernel\kernelbase.py", line 367, in dispatch_shell
| await result
| File "C:\Users\T\Anaconda3\Lib\site-packages\ipykernel\kernelbase.py", line 662, in execute_request
| reply_content = await reply_content
| File "C:\Users\T\Anaconda3\Lib\site-packages\ipykernel\ipkernel.py", line 360, in do_execute
| res = shell.run_cell(code, store_history=store_history, silent=silent)
| File "C:\Users\T\Anaconda3\Lib\site-packages\ipykernel\zmqshell.py", line 532, in run_cell
| return super().run_cell(*args, **kwargs)
| File "C:\Users\T\Anaconda3\Lib\site-packages\IPython\core\interactiveshell.py", line 2863, in run_cell
| result = self._run_cell(
| File "C:\Users\T\Anaconda3\Lib\site-packages\IPython\core\interactiveshell.py", line 2909, in _run_cell
| return runner(coro)
| File "C:\Users\T\Anaconda3\Lib\site-packages\IPython\core\async_helpers.py", line 129, in _pseudo_sync_runner
| coro.send(None)
| File "C:\Users\T\Anaconda3\Lib\site-packages\IPython\core\interactiveshell.py", line 3106, in run_cell_async
| has_raised = await self.run_ast_nodes(code_ast.body, cell_name,
| File "C:\Users\T\Anaconda3\Lib\site-packages\IPython\core\interactiveshell.py", line 3309, in run_ast_nodes
| if await self.run_code(code, result, async_=asy):
| File "C:\Users\T\Anaconda3\Lib\site-packages\IPython\core\interactiveshell.py", line 3369, in run_code
| exec(code_obj, self.user_global_ns, self.user_ns)
| File "C:\Users\T\AppData\Local\Temp\ipykernel_23572\2140586109.py", line 1, in <cell line: 1>
| runfile('C:/Users/T/Downloads/pointPloter.py', wdir='C:/Users/T/Downloads')
| File "C:\Users\T\Anaconda3\Lib\site-packages\spyder_kernels\customize\spydercustomize.py", line 577, in runfile
| exec_code(file_code, filename, ns_globals, ns_locals,
| File "C:\Users\T\Anaconda3\Lib\site-packages\spyder_kernels\customize\spydercustomize.py", line 465, in exec_code
| exec(compiled, ns_globals, ns_locals)
| File "C:\Users\T\Downloads\pointPloter.py", line 109, in <module>
| v.animation()
| File "C:\Users\T\Downloads\pointPloter.py", line 103, in animation
| self.start()
| File "C:\Users\T\Downloads\pointPloter.py", line 83, in start
| QtGui.QApplication.instance().exec_()
| File "C:\Users\T\Anaconda3\Lib\site-packages\pyqtgraph\opengl\GLViewWidget.py", line 193, in paintGL
| self.drawItemTree(useItemNames=useItemNames)
| File "C:\Users\T\Anaconda3\Lib\site-packages\pyqtgraph\opengl\GLViewWidget.py", line 233, in drawItemTree
| self.drawItemTree(i, useItemNames=useItemNames)
| File "C:\Users\T\Anaconda3\Lib\site-packages\pyqtgraph\opengl\GLViewWidget.py", line 214, in drawItemTree
| debug.printExc()
| --- exception caught here ---
| File "C:\Users\T\Anaconda3\Lib\site-packages\pyqtgraph\opengl\GLViewWidget.py", line 211, in drawItemTree
| i.paint()
| File "C:\Users\T\Anaconda3\Lib\site-packages\pyqtgraph\opengl\items\GLScatterPlotItem.py", line 152, in paint
| glDrawArrays(GL_POINTS, 0, int(pos.size / pos.shape[-1]))
| AttributeError: 'list' object has no attribute 'size'
|==============================<<
Error while drawing item <pyqtgraph.opengl.items.GLScatterPlotItem.GLScatterPlotItem object at 0x0000026EB461B4C0>.
I see it gives me an attribute error. I tested the code each time I use the size attribute. However, I could not get the code to work. My code is:
# -*- coding: utf-8 -*-
from pyqtgraph.Qt import QtCore, QtGui
import pyqtgraph.opengl as gl
import pyqtgraph as pg
import numpy as np
import sys
import time
import random
class Visualizer(object):
def __init__(self):
self.traces = dict()
self.app = QtGui.QApplication(sys.argv)
self.w = gl.GLViewWidget()
self.w.opts['distance'] = 40
self.w.setWindowTitle('pyqtgraph example: GLLinePlotItem')
self.w.setGeometry(0, 110, 1920, 1080)
self.w.show()
self.listPoints = []
self.listPoints.append(self.PointsObj(0))
self.listPoints.append(self.PointsObj(0))
self.listPoints.append(self.PointsObj(0))
#for obj in self.listPoints:
#print(obj.y)
for idObj, obj in enumerate(self.listPoints):
pts = [obj.x, obj.y, obj.z]
print(pts)
self.traces[idObj] = gl.GLScatterPlotItem(
pos=pts,
color=pg.glColor((0, 6.5)),
size=3,
pxMode=True
)
self.w.addItem(self.traces[idObj])
class PointsObj:
def __init__(self, type):
self.type= type
self.x= random.randint(-10, 10)
self.y= random.randint(-10, 10)
self.z= random.randint(-10, 10)
self.dx= 0
self.dy= 0
self.dz= 0
def start(self):
if (sys.flags.interactive != 1) or not hasattr(QtCore, 'PYQT_VERSION'):
QtGui.QApplication.instance().exec_()
def set_plotdata(self, name, points, color, size):
self.traces[name].setData(pos=points, color=color, size=size)
def update(self):
stime = time.time()
for idObj, obj in enumerate(self.listPoints):
pts = [obj.x + obj.dx, obj.y + obj.dy, obj.z + obj.dz]
self.set_plotdata(
name=idObj, points=pts,
color=pg.glColor((0, 6.5)),
size=3
)
def animation(self):
timer = QtCore.QTimer()
timer.timeout.connect(self.update)
timer.start(10)
self.start()
# Start event loop.
if __name__ == '__main__':
v = Visualizer()
v.animation()
You should pass a np.array
to GLScatterPlotItem
like the following snippet:
self.traces[idObj] = gl.GLScatterPlotItem(
pos=np.array(pts), # <- Here
color=pg.glColor((0, 6.5)),
size=3,
pxMode=True
)