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
# -*- coding: utf-8 -*-
# vispy: gallery 30
# -----------------------------------------------------------------------------
# Copyright (c) Vispy Development Team. All Rights Reserved.
# Distributed under the (new) BSD License. See LICENSE.txt for more info.
# -----------------------------------------------------------------------------
"""
Draw a SurfacePlot
==================
This example demonstrates the use of the SurfacePlot visual.
"""
import sys
import numpy as np
from vispy import app, scene
from vispy.util.filter import gaussian_filter
canvas = scene.SceneCanvas(keys='interactive', bgcolor='w')
view = canvas.central_widget.add_view()
view.camera = scene.TurntableCamera(up='z', fov=60)
# Simple surface plot example
# x, y values are not specified, so assumed to be 0:50
z = np.random.normal(size=(250, 250), scale=200)
z[100, 100] += 50000
z = gaussian_filter(z, (10, 10))
p1 = scene.visuals.SurfacePlot(z=z, color=(0.3, 0.3, 1, 1), shading='smooth')
p1.transform = scene.transforms.MatrixTransform()
p1.transform.scale([1/249., 1/249., 1/249.])
p1.transform.translate([-0.5, -0.5, 0])
view.add(p1)
xax = scene.Axis(pos=[[-0.5, -0.5], [0.5, -0.5]], tick_direction=(0, -1),
font_size=16, axis_color='k', tick_color='k', text_color='k',
parent=view.scene)
xax.transform = scene.STTransform(translate=(0, 0, -0.2))
yax = scene.Axis(pos=[[-0.5, -0.5], [-0.5, 0.5]], tick_direction=(-1, 0),
font_size=16, axis_color='k', tick_color='k', text_color='k',
parent=view.scene)
yax.transform = scene.STTransform(translate=(0, 0, -0.2))
# Add a 3D axis to keep us oriented
axis = scene.visuals.XYZAxis(parent=view.scene)
if __name__ == '__main__':
canvas.show()
if sys.flags.interactive == 0:
app.run()
@brisvag The above is a sample code from vispy github and these are the results with old and new versions of the library.
@sreenath1994s it seems that the crux of the issue is that the default light direction changed. Not sure why or when; you problem can be easily fixed by changing the light direction to something better. In the example above:
p1.shading_filter.light_dir = 1, 1, 1
this should be close enought to what you had before. If not, play around with the number until you're happy :)