And with
self.program['position'] = newPos
I get the following error :
File "testVispy.py", line 34, in on_timer
self.program['position'] = newPos
File "/home/chams/.local/lib/python3.6/site-packages/vispy/gloo/program.py", line 409, in __setitem__
vbo.set_data(data)
File "/home/chams/.local/lib/python3.6/site-packages/vispy/gloo/buffer.py", line 381, in set_data
raise RuntimeError("Cannot set data on buffer view.")
RuntimeError: Cannot set data on buffer view.
_pos
:class MyCanvas(app.Canvas):
def __init__(self):
app.Canvas.__init__(self)
self.program = gloo.Program(vertex, fragment, count=2)
self._pos = gloo.VertexBuffer()
self.program['position'] = np.array([[.5, 0], [-.5, 0]], dtype=np.float32)
self.timer = app.Timer("auto", self.on_timer)
self.timer.start()
self.show()
def on_timer(self, event):
totalTime = self.timer.elapsed
x = .5*np.cos(totalTime)
newPos = np.array([(x, 0), (-x, 0)])
self._pos.set_data(newPos.astype(np.float32))
self.program['position'] = self._pos
self.update()
@almarklein @rougier Any memory why gloo.Program
creates a View for each of the buffers? Meaning self.program['position']
is a DataBufferView
when the program is created?
@cgharib Actually if you set the VertexBuffer
in the __init__
and then do self.program['position'] = newPos.astype(np.float32)
then it seems to work. The main problem seems to be that the gloo.Program
creation defaults to creating a View. I'm not exactly sure why the original self.program['position'] =
works as that should be a View too.
Hey. Thanks for all your answers. So here's how I would write it based on @djhoese 's code.
import numpy as np
from vispy import app, gloo
vertex = """
attribute vec2 position;
void main() {
gl_Position = vec4(position, 0., 1.);
}
"""
fragment = """
void main() {
gl_FragColor = vec4(1.,0.,0.,1.);
}
"""
class MyCanvas(app.Canvas):
def __init__(self):
app.Canvas.__init__(self)
self.program = gloo.Program(vertex, fragment, count=2)
self.vertexBuffer = gloo.VertexBuffer(np.array([(.5, 0), (-.5, 0)], dtype=np.float32))
self.program['position'] = self.vertexBuffer
self.timer = app.Timer('auto', self.on_timer)
self.timer.start()
self.show()
def on_draw(self, event):
gloo.clear()
self.program.draw('lines')
def on_timer(self, event):
totalTime = self.timer.elapsed
x = .5*np.cos(totalTime)
newPos = np.array([(x, 0), (-x, 0)], dtype=np.float32)
self.vertexBuffer.set_data(newPos)
self.update()
c = MyCanvas()
app.run()
Does it seem idiomatic to you ? Thanks a lot !
self.program['position'] = newPos
. It feels more future-proof and avoids the possibility of the VertexBuffer being copied inside the Program and your set_data
not having an effect. Hopefully that makes sense. Either way should work so do what feels good to you.
ellipse.transform = STTransform(translate=(0, 0, some_z_shift))
. You may also run into issues with drawing order between the Image and Ellipse where you may need to do something like ellipse.order = -5
, but see if the Z position works well enough first.
Hello guys. I'm developing a software to visualize thickness maps by using PyQt as Desktop Framework, however, I'm experiencing some problems. The central widget is a grid layout with multiple scatter plots, in a sub grid each, When i minimize and maximize the window multiple times the layout tends to collapse, then i get the following error
WARNING: Traceback (most recent call last):
File ".\src\CrushingApp.py", line 324, in <module>
sys.exit(app.exec_())
File "C:\Users\site-packages\vispy\app\backends\_qt.py", line 508, in event
out = super(QtBaseCanvasBackend, self).event(ev)
File "C:\Users\site-packages\vispy\app\backends\_qt.py", line 825, in paintGL
self._vispy_canvas.events.draw(region=None)
File "C:\Users\\site-packages\vispy\util\event.py", line 455, in __call__
self._invoke_callback(cb, event)
File "C:\Users\site-packages\vispy\util\event.py", line 475, in _invoke_callback
self, cb_event=(cb, event))
<< caught exception here: >>
File "C:\Users\site-packages\vispy\util\event.py", line 471, in _invoke_callback
cb(event)
File "C:\Users\site-packages\vispy\scene\canvas.py", line 217, in on_draw
self._draw_scene()
File "C:\Users\site-packages\vispy\scene\canvas.py", line 266, in _draw_scene
self.draw_visual(self.scene)
File "C:\Users\site-packages\vispy\scene\canvas.py", line 304, in draw_visual
self.add_with_artificial_variable(expr)
File "C:\Users\site-packages\vispy\ext\_bundled\cassowary\simplex_solver.py", line 381, in
add_with_artificial_variable
raise RequiredFailure()
vispy.ext._bundled.cassowary.error.RequiredFailure
ERROR: Invoking <bound method SceneCanvas.on_draw of <CanvasMapaEspesores (PyQt5) at 0x149ed69fe08>> for DrawEvent
is there a way to avoi
self.t2 = scene.visuals.Text('Test Text', parent=self.view.scene, color='green')
self.t2.font_size = 14
self.plane = scene.visuals.Plane(
width=1000,
height=300,
parent=self.t2
)
self.plane.transform = vispy.visuals.transforms.STTransform(translate=(0, 0, 0),
scale=(1., 1., 1.)).as_matrix()
def on_mouse_move(self, event):
if event.button == 1 and event.is_dragging:
self.plane.transform.reset()
self.plane.transform.rotate(self.view.camera.azimuth, (0, 0, 1))
self.plane.transform.rotate(90 - self.view.camera.elevation, (0, 1, 0))
self.plane.transform.rotate(self.view.camera.roll, (1, 0, 0))
This is what i tried
import numpy as np
import vispy.scene
from vispy.scene import visuals
from vispy.visuals import text
class CustomCanvas(vispy.scene.SceneCanvas):
def __init__(self):
super(CustomCanvas, self).__init__(keys='interactive', show=True)
self.unfreeze()
self.view = self.central_widget.add_view()
self.xyz_top = None
self.textLabelMax = None
self.backgroundLabelMax = None
self.events.mouse_move.connect(self.on_mouse_move)
self.freeze()
def on_mouse_move(self, event):
if(event.button == 1 and event.is_dragging):
self.backgroundLabelMax.transform.reset()
self.backgroundLabelMax.transform.rotate(self.view.camera.azimuth, (0, 0, 1))
self.backgroundLabelMax.transform.rotate(90 - self.view.camera.elevation, (1, 0, 0))
self.backgroundLabelMax.transform.translate(self.xyz_top)
def draw_cloud_points(self):
pos = np.random.normal(size=(100000, 3), scale=0.2)
# one could stop here for the data generation, the rest is just to make the
# data look more interesting. Copied over from magnify.py
centers = np.random.normal(size=(50, 3))
indexes = np.random.normal(size=100000, loc=centers.shape[0]/2.,
scale=centers.shape[0]/3.)
indexes = np.clip(indexes, 0, centers.shape[0]-1).astype(int)
scales = 10**(np.linspace(-2, 0.5, centers.shape[0]))[indexes][:, np.newaxis]
pos *= scales
pos += centers[indexes]
# create scatter object and fill in the data
scatter = visuals.Markers()
scatter.set_data(pos, edge_color=None, face_color=(1, 1, 1, .5), size=5)
self.view.add(scatter)
# Adding text label at center / top (Z axis)
self.xyz_top = (pos[:,0].max(), pos[:,1].max(), pos[:,2].max())
self.textLabelMax = visuals.Text(pos=self.xyz_top, text="Test_Label_Max", font_size=24, color="white", parent=self.view.scene)
# Adding plane as background for texts
self.backgroundLabelMax = visuals.Plane(width=5, height = 1, color=(1, 0, 0, 0.4), parent=self.view.scene)
self.backgroundLabelMax.transform = vispy.scene.transforms.STTransform(
scale=(1, 1, 1),
translate=self.xyz_top
).as_matrix()
# Adding turntable with ortographic view
self.view.camera = vispy.scene.TurntableCamera(fov=0, azimuth=0, elevation=90, roll=0)
# Auto focus
self.view.camera.set_range()
def main():
custom_canvas = CustomCanvas()
custom_canvas.draw_cloud_points()
if __name__ == '__main__':
import sys
if sys.flags.interactive != 1:
main()
vispy.app.run()
self.backgroundLabelMax.transform.matrix = self.view.camera.transform.matrix
and self.backgroundLabelMax.transform.translate(self.xyz_top)
gets it pretty close...somehow
import numpy as np
import vispy.scene
from vispy.scene import visuals
from vispy.visuals import text
class CustomCanvas(vispy.scene.SceneCanvas):
def __init__(self):
super(CustomCanvas, self).__init__(keys='interactive', show=True)
self.unfreeze()
self.view = self.central_widget.add_view()
self.xyz_top = None
self.textLabelMax = None
self.backgroundLabelMax = None
self.bgScale = [1, 1, 1]
self.events.mouse_move.connect(self.on_mouse_move)
self.events.mouse_wheel.connect(self.on_mouse_wheel)
self.freeze()
def on_mouse_move(self, event):
if(event.button == 1 and event.is_dragging):
self.backgroundLabelMax.transform.reset()
self.backgroundLabelMax.transform.matrix = self.view.camera.transform.matrix
self.backgroundLabelMax.transform.translate(self.xyz_top)
def on_mouse_wheel(self, event):
pass
"""
self.backgroundLabelMax.transform.reset()
delta = event.delta[1]
if(delta < 0):
print(delta)
if self.view.camera.scale_factor >= 30:
self.view.camera.scale_factor = 30
else:
if self.view.camera.scale_factor <= 10:
self.view.camera.scale_factor = 10
self.backgroundLabelMax.transform.matrix = self.view.camera.transform.matrix
self.backgroundLabelMax.transform.scale(self.bgScale)
self.backgroundLabelMax.transform.translate(self.xyz_top)
"""
def draw_cloud_points(self):
pos = np.random.normal(size=(100000, 3), scale=0.2)
# one could stop here for the data generation, the rest is just to make the
# data look more interesting. Copied over from magnify.py
centers = np.random.normal(size=(50, 3))
indexes = np.random.normal(size=100000, loc=centers.shape[0]/2.,
scale=centers.shape[0]/3.)
indexes = np.clip(indexes, 0, centers.shape[0]-1).astype(int)
scales = 10**(np.linspace(-2, 0.5, centers.shape[0]))[indexes][:, np.newaxis]
pos *= scales
pos += centers[indexes]
# create scatter object and fill in the data
scatter = visuals.Markers()
scatter.set_data(pos, edge_color=None, face_color=(1, 1, 1, .5), size=5)
self.view.add(scatter)
# Adding turntable with ortographic view
self.view.camera = vispy.scene.TurntableCamera(fov=0)
# Adding plane as background for texts
self.backgroundLabelMax = visuals.Rectangle(center = (0, 0, 0), width=3.5, height = 1, color=(1, 0, 0, 0.4), radius=0.3, parent=self.view.scene)
# Adding text label at center / top (Z axis)
self.xyz_top = (pos[:,0].max(), pos[:,1].max(), pos[:,2].max())
self.textLabelMax = visuals.Text(pos=(0, 0, 0), text="Test_Label_Max", font_size=18, color="white", parent=self.backgroundLabelMax)
self.backgroundLabelMax.transform = vispy.scene.transforms.STTransform(
scale=(1, 1, 1),
translate=(0, 0, 0)
).as_matrix()
self.backgroundLabelMax.transform.matrix = self.view.camera.transform.matrix
self.backgroundLabelMax.transform.translate(self.xyz_top)
# Auto focus
self.view.camera.set_range()
def main():
custom_canvas = CustomCanvas()
custom_canvas.draw_cloud_points()
if __name__ == '__main__':
import sys
if sys.flags.interactive != 1:
main()
vispy.app.run()
make html
in the doc
directory. Note however that by default it will run all of the gallery examples which can take a long time. There is a way to make it not do that but I don't remember off the top of my head