def test_color_interpretation(): """Test basic color interpretation API""" # test useful ways of single color init r = ColorArray('r') print(r) # test repr r2 = ColorArray(r) assert_equal(r, r2) r2.rgb = 0, 0, 0 assert_equal(r2, ColorArray('black')) assert_equal(r, ColorArray('r')) # modifying new one preserves old assert_equal(r, r.copy()) assert_equal(r, ColorArray('#ff0000')) assert_equal(r, ColorArray('#FF0000FF')) assert_equal(r, ColorArray('red')) assert_equal(r, ColorArray('red', alpha=1.0)) assert_equal(ColorArray((1, 0, 0, 0.1)), ColorArray('red', alpha=0.1)) assert_array_equal(r.rgb.ravel(), (1., 0., 0.)) assert_array_equal(r.rgba.ravel(), (1., 0., 0., 1.)) assert_array_equal(r.RGBA.ravel(), (255, 0, 0, 255)) # handling multiple colors rgb = ColorArray(list('rgb')) print(rgb) # multi repr assert_array_equal(rgb, ColorArray(np.eye(3))) # complex/annoying case rgb = ColorArray(['r', (0, 1, 0), '#0000ffff']) assert_array_equal(rgb, ColorArray(np.eye(3))) assert_raises(RuntimeError, ColorArray, ['r', np.eye(3)]) # can't nest # getting/setting properties r = ColorArray('#ffff') assert_equal(r, ColorArray('white')) r = ColorArray('#ff000000') assert_true('turquoise' in get_color_names()) # make sure our JSON loaded assert_equal(r.alpha, 0) r.alpha = 1.0 assert_equal(r, ColorArray('r')) r.alpha = 0 r.rgb = (1, 0, 0) assert_equal(r.alpha, 0) assert_equal(r.hex, ['#ff0000']) r.alpha = 1 r.hex = '00ff00' assert_equal(r, ColorArray('g')) assert_array_equal(r.rgb.ravel(), (0., 1., 0.)) r.RGB = 255, 0, 0 assert_equal(r, ColorArray('r')) assert_array_equal(r.RGB.ravel(), (255, 0, 0)) r.RGBA = 255, 0, 0, 0 assert_equal(r, ColorArray('r', alpha=0)) w = ColorArray() w.rgb = ColorArray('r').rgb + ColorArray('g').rgb + ColorArray('b').rgb assert_equal(w, ColorArray('white')) w = ColorArray('white') assert_equal(w, w.darker().lighter()) assert_equal(w, w.darker(0.1).darker(-0.1)) w2 = w.darker() assert_true(w != w2) w.darker(copy=False) assert_equal(w, w2) with use_log_level('warning', record=True, print_msg=False) as w: w = ColorArray('white') w.value = 2 assert_equal(len(w), 1) assert_equal(w, ColorArray('white')) # warnings and errors assert_raises(ValueError, ColorArray, '#ffii00') # non-hex assert_raises(ValueError, ColorArray, '#ff000') # too short assert_raises(ValueError, ColorArray, [0, 0]) # not enough vals assert_raises(ValueError, ColorArray, [2, 0, 0]) # val > 1 assert_raises(ValueError, ColorArray, [-1, 0, 0]) # val < 0 c = ColorArray([2., 0., 0.], clip=True) # val > 1 assert_true(np.all(c.rgb <= 1)) c = ColorArray([-1., 0., 0.], clip=True) # val < 0 assert_true(np.all(c.rgb >= 0)) # make sure our color dict works for key in get_color_names(): assert_true(ColorArray(key)) assert_raises(ValueError, ColorArray, 'foo') # unknown color error _color_dict = get_color_dict() assert isinstance(_color_dict, dict) assert set(_color_dict.keys()) == set(get_color_names())
def handle_nested_colors(colors) -> ColorArray: """In case of an array-like container holding colors, unpack it.""" colors_as_rbga = np.ones((len(colors), 4), dtype=np.float32) for idx, color in enumerate(colors): colors_as_rbga[idx] = _color_switch[type(color)](color) return ColorArray(colors_as_rbga)
def test_color_conversion(): """Test color conversions""" # HSV # test known values test = ColorArray() for key in hsv_dict: c = ColorArray(key) test.hsv = hsv_dict[key] assert_allclose(c.RGB, test.RGB, atol=1) test.value = 0 assert_equal(test.value, 0) assert_equal(test, ColorArray('black')) c = ColorArray('black') assert_array_equal(c.hsv.ravel(), (0, 0, 0)) rng = np.random.RandomState(0) for _ in range(50): hsv = rng.rand(3) hsv[0] *= 360 hsv[1] = hsv[1] * 0.99 + 0.01 # avoid ugly boundary effects hsv[2] = hsv[2] * 0.99 + 0.01 c.hsv = hsv assert_allclose(c.hsv.ravel(), hsv, rtol=1e-4, atol=1e-4) # Lab test = ColorArray() for key in lab_dict: c = ColorArray(key) test.lab = lab_dict[key] assert_allclose(c.rgba, test.rgba, atol=1e-4, rtol=1e-4) assert_allclose(test.lab.ravel(), lab_dict[key], atol=1e-4, rtol=1e-4) for _ in range(50): # boundaries can have ugly rounding errors in some parameters rgb = (rng.rand(3)[np.newaxis, :] * 0.9 + 0.05) c.rgb = rgb lab = c.lab c.lab = lab assert_allclose(c.lab, lab, atol=1e-4, rtol=1e-4) assert_allclose(c.rgb, rgb, atol=1e-4, rtol=1e-4)
def __init__(self, segments, radii=1.0, color='purple', tube_points=8, shading='smooth', vertex_colors=None, face_colors=None, use_normals=True, mode='triangles'): vertices = np.empty((0, 3), dtype=np.float) indices = np.empty((0, 3), dtype=np.uint32) if not isinstance(radii, collections.Iterable): radii = [[radii] * len(points) for points in segments] for points, radius in zip(segments, radii): # Need to make sure points are floats points = np.array(points).astype(float) if use_normals: tangents, normals, binormals = _frenet_frames(points) else: tangents = normals = binormals = np.ones((len(points), 3)) n_segments = len(points) - 1 if not isinstance(radius, collections.Iterable): radius = [radius] * len(points) radius = np.array(radius) # Vertices for each point on the circle verts = np.repeat(points, tube_points, axis=0) v = np.arange(tube_points, dtype=np.float) / tube_points * 2 * np.pi all_cx = (radius * -1. * np.tile(np.cos(v), points.shape[0]).reshape( (tube_points, points.shape[0]), order='F')).T cx_norm = (all_cx[:, :, np.newaxis] * normals[:, np.newaxis, :]).reshape(verts.shape) all_cy = (radius * np.tile(np.sin(v), points.shape[0]).reshape( (tube_points, points.shape[0]), order='F')).T cy_norm = (all_cy[:, :, np.newaxis] * binormals[:, np.newaxis, :]).reshape(verts.shape) verts = verts + cx_norm + cy_norm """ # get the positions of each vertex grid = np.zeros((len(points), tube_points, 3)) for i in range(len(points)): pos = points[i] if use_normals: normal = normals[i] binormal = binormals[i] else: normal = binormal = 1 r = radius[i] # Add a vertex for each point on the circle v = np.arange(tube_points, dtype=np.float) / tube_points * 2 * np.pi cx = -1. * r * np.cos(v) cy = r * np.sin(v) grid[i] = (pos + cx[:, np.newaxis] * normal + cy[:, np.newaxis] * binormal) """ # Generate indices for the first segment ix = np.arange(0, tube_points) # Repeat indices n_segments-times ix = np.tile(ix, n_segments) # Offset indices by number segments and tube points offsets = np.repeat((np.arange(0, n_segments)) * tube_points, tube_points) ix += offsets # Turn indices into faces ix_a = ix ix_b = ix + tube_points ix_c = ix_b.reshape((n_segments, tube_points)) ix_c = np.append(ix_c[:, 1:], ix_c[:, [0]], axis=1) ix_c = ix_c.ravel() ix_d = ix_a.reshape((n_segments, tube_points)) ix_d = np.append(ix_d[:, 1:], ix_d[:, [0]], axis=1) ix_d = ix_d.ravel() faces1 = np.concatenate((ix_a, ix_b, ix_d), axis=0).reshape( (n_segments * tube_points, 3), order='F') faces2 = np.concatenate((ix_b, ix_c, ix_d), axis=0).reshape( (n_segments * tube_points, 3), order='F') faces = np.append(faces1, faces2, axis=0) # Offset faces against already existing vertices faces += vertices.shape[0] # Get vertices from grid #this_vertices = grid.reshape(grid.shape[0] * grid.shape[1], 3) this_vertices = verts # Add vertices and faces to total collection vertices = np.append(vertices, this_vertices, axis=0) indices = np.append(indices, faces, axis=0) color = ColorArray(color) if vertex_colors is None: vertex_colors = np.resize(color.rgba, (vertices.shape[0], 4)) MeshVisual.__init__(self, vertices, indices, vertex_colors=vertex_colors, face_colors=face_colors, shading=shading, mode=mode)
flyCam.scale_factor = 100000 flyCam.center = (99, 99, 99) cam1 = scene.cameras.MagnifyCamera() cam2 = scene.cameras.ArcballCamera(fov=90.0, distance=250) view.camera = flyCam scatter = visuals.Markers(parent=view.scene) scatter.antialias = 1 #scatter.set_data(pos=pos, edge_color=(0.7,0.3,0.4,0.8), face_color=(0.7,0.3,0.4,0.8), size=8) scatter.set_data(pos=pos, face_color=colors, size=8) #scatter.set_data(pos=puntosRuta, edge_color=(0.0, 0.0, 0.0, 1.0), face_color=(0.9, 0.9, 0.9, 1.0), size=15) scatter.set_gl_state(depth_test=True, blend=True, blend_func=('src_alpha', 'one_minus_src_alpha')) # Add axes axis = visuals.XYZAxis(parent=view.scene) #print(vispy.color.get_colormap) r = ColorArray('red') #map = vispy.color.Colormap(r) #newAxis = visuals.ColorBar(parent=view.scene, size=10000, cmap=r, orientation='bottom') if __name__ == '__main__' and sys.flags.interactive == 0: canvas.app.run()
def __init__(self, points, radius=1.0, closed=False, color='purple', tube_points=8, shading='smooth', vertex_colors=None, face_colors=None, mode='triangles'): points = np.array(points) tangents, normals, binormals = _frenet_frames(points, closed) segments = len(points) - 1 if not isinstance(radius, collections.Iterable): radius = [radius] * len(points) # get the positions of each vertex grid = np.zeros((len(points), tube_points, 3)) for i in range(len(points)): pos = points[i] normal = normals[i] binormal = binormals[i] r = radius[i] # Add a vertex for each point on the circle v = np.arange(tube_points, dtype=np.float) / tube_points * 2 * np.pi cx = -1. * r * np.cos(v) cy = r * np.sin(v) grid[i] = (pos + cx[:, np.newaxis] * normal + cy[:, np.newaxis] * binormal) # construct the mesh indices = [] for i in range(segments): for j in range(tube_points): ip = (i + 1) % segments if closed else i + 1 jp = (j + 1) % tube_points index_a = i * tube_points + j index_b = ip * tube_points + j index_c = ip * tube_points + jp index_d = i * tube_points + jp indices.append([index_a, index_b, index_d]) indices.append([index_b, index_c, index_d]) vertices = grid.reshape(grid.shape[0] * grid.shape[1], 3) color = ColorArray(color) if vertex_colors is None: point_colors = np.resize(color.rgba, (len(points), 4)) vertex_colors = np.repeat(point_colors, tube_points, axis=0) indices = np.array(indices, dtype=np.uint32) MeshVisual.__init__(self, vertices, indices, vertex_colors=vertex_colors, face_colors=face_colors, shading=shading, mode=mode)
self.a, self.b = np.matrix(origin), np.matrix(mat) self._logainvb = logm(self.a.I * self.b) def __call__(self, t): return np.real(self.a * expm(t * self._logainvb)) # Load the Iris dataset and normalize. iris = load_iris() position = iris['data'].astype(np.float32) n, ndim = position.shape position -= position.mean() position /= np.abs(position).max() v_position = position * .75 v_color = ColorArray(['orange', 'magenta', 'darkblue']) v_color = v_color.rgb[iris['group'], :].astype(np.float32) v_color *= np.random.uniform(.5, 1.5, (n, 3)) v_color = np.clip(v_color, 0, 1) v_size = np.random.uniform(2, 12, (n, 1)).astype(np.float32) VERT_SHADER = """ #version 120 attribute vec4 a_position; attribute vec3 a_color; attribute float a_size; uniform vec2 u_pan; uniform vec2 u_scale; uniform vec4 u_vec1; uniform vec4 u_vec2;
def zbow_2d_plot(self, parent, scale, color, update=False, highlight_cells=None, highlight_color=False): new_window_position = parent.pos() if parent.was_closed: parent.show() if update: options = self.h_view_2d.camera.get_state() # get scale data: scale_list = ['custom', 'default', 'linear'] if scale == 0: scale_data = self.custom_ternary.values elif scale == 1: scale_data = self.default_ternary.values elif scale == 2: scale_data = self.linear_ternary.values else: scale_data = self.custom_ternary.values # get color data:color_list = ['custom', 'default', 'cluster color', 'linear'] if color == 0: color_data = self.custom_transformed.values elif color == 1: color_data = self.default_transformed[['RFP', 'YFP', 'CFP']].values elif color == 2: if self.tab_cluster_data.empty: color_data = helper.distinguishable_colors(1) else: pseudo_color = helper.distinguishable_colors( self.tab_cluster_data['id'].count()) pseudo_color[self.noise_cluster_idx] = "#646464" color_data = [None] * scale_data.shape[0] for i in range(0, scale_data.shape[0]): color_data[i] = pseudo_color[self.cluster_data_idx[i]] elif color == 3: color_data = self.linear_transformed[['RFP', 'YFP', 'CFP']].values elif color == 4: color_data = np.empty([ self.custom_transformed.shape[0], self.custom_transformed.shape[1] ]) color_data[:] = 0.8 # grey for non-highlighted cells highlight_cells = pd.Series(highlight_cells, name='bools') if highlight_color: color_data[highlight_cells, :] = [0.2, 0.2, 0.2] else: color_data[highlight_cells, :] = self.custom_transformed[[ 'RFP', 'YFP', 'CFP' ]][highlight_cells.values].values if not update: # build your visuals scatter = scene.visuals.create_visual_node(visuals.MarkersVisual) # build canvas self.h_canvas_2d = scene.SceneCanvas( title='zbow 2D ternary plot', keys='interactive', show=True, bgcolor=Color([1, 1, 1, 1]), ) parent.setCentralWidget(self.h_canvas_2d.native) # Add a ViewBox to let the user zoom/rotate if not update: self.h_view_2d = self.h_canvas_2d.central_widget.add_view() self.h_view_2d.camera = 'panzoom' self.h_view_2d.camera.set_range(x=(-0.2, 1.2), y=(-0.2, 1.2)) # if update: # self.h_view_2d = self.h_canvas_2d.central_widget.add_view() # self.h_view_2d.camera = 'panzoom' # self.h_view_2d.camera.set_state(options) # else: # self.h_view_2d = self.h_canvas_2d.central_widget.add_view() # self.h_view_2d.camera = 'panzoom' self.h_scatter_2d = scatter(parent=self.h_view_2d.scene) # p1.set_gl_state('translucent', blend=True, depth_test=True) self.h_scatter_2d.set_gl_state('translucent', blend=True, depth_test=False) # plot 2D ternary axis bottom_axis = scene.Axis(parent=self.h_view_2d.scene, pos=[[0, 0], [1, 0]], tick_direction=(0, 1), font_size=12, axis_color='k', tick_color='k', tick_font_size=0, axis_width=3, axis_label='', axis_label_margin=20, axis_font_size=18) right_axis = scene.Axis(parent=self.h_view_2d.scene, pos=[[1, 0], [0.5, 1]], tick_direction=(-1, -1), font_size=12, axis_color='k', tick_color='k', tick_font_size=0, axis_width=3, axis_label='', axis_label_margin=20, axis_font_size=18) left_axis = scene.Axis(parent=self.h_view_2d.scene, pos=[[0, 0], [0.5, 1]], tick_direction=(1, -1), font_size=12, axis_color='k', tick_color='k', tick_font_size=0, axis_width=3, axis_label='', axis_label_margin=20, axis_font_size=18) cell_color = ColorArray(color=color_data, alpha=1) # @BUG I want to use a different alpha here, but Vispy has a bug where you can see through the main canvas with alpha self.h_scatter_2d.set_data(pos=scale_data, symbol='o', size=5, edge_width=0, face_color=cell_color) # if not update: # self.h_scatter_2d.symbol = visuals.marker_types[10] if not update: parent.move(new_window_position.x(), new_window_position.y()) parent.show()
def zbow_3d_plot(self, parent, scale, color, update=False, highlight_cells=None, highlight_color=False): if parent.was_closed: parent.show() new_window_position = parent.pos() if update: options = self.h_view_3d.camera.get_state() # get scale data: scale_list = ['custom', 'default', 'linear'] if scale == 0: scale_data = self.custom_transformed.values elif scale == 1: scale_data = self.default_transformed[['RFP', 'YFP', 'CFP']].values elif scale == 2: scale_data = self.linear_transformed[['RFP', 'YFP', 'CFP']].values else: scale_data = self.custom_transformed.values # get color data:color_list = ['custom', 'default', 'cluster color', 'linear'] if color == 0: color_data = self.custom_transformed.values elif color == 1: color_data = self.default_transformed[['RFP', 'YFP', 'CFP']].values elif color == 2: if self.tab_cluster_data.empty: color_data = helper.distinguishable_colors(1) else: pseudo_color = helper.distinguishable_colors( self.tab_cluster_data['id'].count()) pseudo_color[self.noise_cluster_idx] = "#646464" color_data = [None] * scale_data.shape[0] for i in range(0, scale_data.shape[0]): color_data[i] = pseudo_color[self.cluster_data_idx[i]] elif color == 3: color_data = self.linear_transformed[['RFP', 'YFP', 'CFP']].values elif color == 4: color_data = np.empty([ self.custom_transformed.shape[0], self.custom_transformed.shape[1] ]) color_data[:] = 0.3 # grey for non-highlighted cells highlight_cells = pd.Series(highlight_cells, name='bools') if highlight_color: color_data[highlight_cells, :] = [0.9, 0.9, 0.9] else: color_data[highlight_cells, :] = self.custom_transformed[[ 'RFP', 'YFP', 'CFP' ]][highlight_cells.values].values if not update: # build your visuals scatter = scene.visuals.create_visual_node(visuals.MarkersVisual) # build initial canvas if one doesn't exist self.h_canvas_3d = scene.SceneCanvas( title='zbow 3D scatter plot', keys='interactive', show=True, bgcolor=Color([0, 0, 0, 1]), ) parent.setCentralWidget(self.h_canvas_3d.native) # Add a ViewBox to let the user zoom/rotate default_options = { 'fov': 5, 'distance': 25, 'elevation': 30, 'azimuth': 130, 'scale_factor': 3.0 } self.h_view_3d = self.h_canvas_3d.central_widget.add_view() self.h_view_3d.camera = 'turntable' self.h_view_3d.camera.fov = default_options['fov'] self.h_view_3d.camera.distance = default_options['distance'] self.h_view_3d.camera.elevation = default_options['elevation'] self.h_view_3d.camera.azimuth = default_options['azimuth'] self.h_view_3d.camera.scale_factor = default_options[ 'scale_factor'] # if update: # self.h_view_3d = self.h_canvas_3d.central_widget.add_view() # self.h_view_3d.camera = 'turntable' # self.h_view_3d.camera.set_state(options) # # else: # self.h_view_3d = self.h_canvas_3d.central_widget.add_view() # self.h_view_3d.camera = 'turntable' # self.h_view_3d.camera.fov = default_options['fov'] # self.h_view_3d.camera.distance = default_options['distance'] # self.h_view_3d.camera.elevation = default_options['elevation'] # self.h_view_3d.camera.azimuth = default_options['azimuth'] # self.h_view_3d.camera.scale_factor = default_options['scale_factor'] # plot 3D RGB axis scene.visuals.XYZAxis(parent=self.h_view_3d.scene) # this isn't supported, apparently # x_axis = scene.Axis(parent=self.h_view_3d.scene, pos=[[0, 0, 0], [1, 0, 0]], # font_size=12, axis_color='k', tick_color='k', text_color='r', # axis_width=3) # # y_axis = scene.Axis(parent=self.h_view_3d.scene, pos=[[0, 0, 0], [0, 1, 0]], # font_size=12, axis_color='k', tick_color='k', text_color='g', # axis_width=3) # # left_axis = scene.Axis(parent=self.h_view_3d.scene, pos=[[0, 0, 0], [0, 0, 1]], tick_direction=(1, -1), # font_size=12, axis_color='k', tick_color='k', text_color='b', # axis_width=3) self.h_scatter_3d = scatter(parent=self.h_view_3d.scene) self.h_scatter_3d.set_gl_state('translucent') # h_scatter.set_gl_state(blend=False, depth_test=True) cell_color = ColorArray(color=color_data, alpha=1) # @BUG I want to use a different alpha here, but Vispy has a bug where you can see through the main canvas with alpha self.h_scatter_3d.set_data(pos=scale_data, symbol='o', size=5, edge_width=0, face_color=cell_color) # h_scatter.symbol = visuals.marker_types[10] if not update: parent.move(new_window_position.x(), new_window_position.y()) parent.show()
def plotpointclouddata(self): """Method that allows to Visualize the Point Cloud data and explore the landscape in fly mode using Vispy Keys to Navigating in Landscape: -> moving right <- moving left up moving forward down moving backwards f moving upward in z dimension c moving downward in z dimension j changing view towards left k changing view towards right i changing view upwards k changing view downwards """ # Creating a visual node which allows to display points it inherits from the class Visuals.MarkersVisual # allowing to disply data points Scatter3D = vispy.scene.visuals.create_visual_node( vispy.visuals.MarkersVisual) # Create a SceneCanvas to display the scene canvas = vispy.scene.SceneCanvas(keys='interactive', show=True) # Create a new ViewBox view = canvas.central_widget.add_view() print("ViewBox created") # Define settings for view view.camera = 'fly' # 'Explore mode: 'fly' = flightsimulator, 'turntable' = rotating around a fixed point view.camera.fov = 80 # Field of view view.camera.distance = 20 # Initial distance from origin view.camera.scale_factor = 20 # "thruster speed" for mode fly colors = np.array( [1, 1, 1, 1] ) # Creating array containing the colors for the labels in size (4, 1) pos = np.c_[self.datax, self.datay, self.dataz] # np array containing the data points if len( self.labels ) == 0: # Check if labels have already been created, if not plot every point as white print( "For showing clusters, first apply the data clustering method") colors = ColorArray(color=(1, 1, 1, 1)) else: unique_labels = set( self.labels ) # Get the number of unique labels with the set function colormap = ScanObject.__getcolormap( self, unique_labels) # get the colormap from the helper function for label in self.labels: colors = np.vstack( (colors, colormap[label] )) # associate a color to each point using the colormap print("Colors associated") colors = np.delete( colors, 0, axis=0 ) # delete the first dummy entry defining the form of the array colors = ColorArray( colors ) # color array creating different color formats such as RGB # Define plot p1 = Scatter3D(parent=view.scene) # Define the set of Open GL state params to use when drawing p1.set_gl_state('translucent', blend=True, depth_test=True) # Set the data and define options for it p1.set_data(pos, face_color=colors, size=3.5, edge_width=0.1, edge_color=None) # Show the XYZ Axis xis = vispy.scene.visuals.XYZAxis(parent=view.scene) # Start plotting vispy.app.run()
def set_data(self, pos=None, wind=None, trig=True, size=50., antialias=1., edge_width=1., edge_color='black', face_color='white'): """ Set the data used to display this visual. Parameters ---------- pos : array The array of locations to display each windbarb. wind : array The array of wind vector components to display each windbarb. in m/s. For knots divide by two. trig : bool True - wind contains (mag, ang) False - wind contains (u, v) defaults to True size : float or array The windbarb size in px. antialias : float The antialiased area (in pixels). edge_width : float | None The width of the windbarb outline in pixels. edge_color : Color | ColorArray The color used to draw each symbol outline. face_color : Color | ColorArray The color used to draw each symbol interior. """ assert (isinstance(pos, np.ndarray) and pos.ndim == 2 and pos.shape[1] in (2, 3)) assert (isinstance(wind, np.ndarray) and pos.ndim == 2 and pos.shape[1] == 2) if edge_width < 0: raise ValueError('edge_width cannot be negative') # since the windbarb starts in the fragment center, # we need to multiply by 2 for correct length size *= 2 edge_color = ColorArray(edge_color).rgba if len(edge_color) == 1: edge_color = edge_color[0] face_color = ColorArray(face_color).rgba if len(face_color) == 1: face_color = face_color[0] n = len(pos) data = np.zeros(n, dtype=[('a_position', np.float32, 3), ('a_wind', np.float32, 2), ('a_trig', np.float32, 0), ('a_fg_color', np.float32, 4), ('a_bg_color', np.float32, 4), ('a_size', np.float32, 1), ('a_edgewidth', np.float32, 1)]) data['a_fg_color'] = edge_color data['a_bg_color'] = face_color data['a_edgewidth'] = edge_width data['a_position'][:, :pos.shape[1]] = pos data['a_wind'][:, :wind.shape[1]] = wind if trig: data['a_trig'] = 1. else: data['a_trig'] = 0. data['a_size'] = size self.shared_program['u_antialias'] = antialias self._data = data self._vbo.set_data(data) self.shared_program.bind(self._vbo) self.update()
def set_data(self, pos=None, symbol='o', size=10., edge_width=1., edge_width_rel=None, edge_color='black', face_color='white', scaling=False): """Set the data used to display this visual. Parameters ---------- pos : array The array of locations to display each symbol. symbol : str The style of symbol to draw (see Notes). size : float or array The symbol size in px. edge_width : float | None The width of the symbol outline in pixels. edge_width_rel : float | None The width as a fraction of marker size. Exactly one of `edge_width` and `edge_width_rel` must be supplied. edge_color : Color | ColorArray The color used to draw each symbol outline. face_color : Color | ColorArray The color used to draw each symbol interior. scaling : bool If set to True, marker scales when rezooming. Notes ----- Allowed style strings are: disc, arrow, ring, clobber, square, diamond, vbar, hbar, cross, tailed_arrow, x, triangle_up, triangle_down, and star. """ assert (isinstance(pos, np.ndarray) and pos.ndim == 2 and pos.shape[1] in (2, 3)) if (edge_width is not None) + (edge_width_rel is not None) != 1: raise ValueError('exactly one of edge_width and edge_width_rel ' 'must be non-None') if edge_width is not None: if edge_width < 0: raise ValueError('edge_width cannot be negative') else: if edge_width_rel < 0: raise ValueError('edge_width_rel cannot be negative') self.symbol = symbol self.scaling = scaling edge_color = ColorArray(edge_color).rgba if len(edge_color) == 1: edge_color = edge_color[0] face_color = ColorArray(face_color).rgba if len(face_color) == 1: face_color = face_color[0] n = len(pos) data = np.zeros(n, dtype=[('a_position', np.float32, 3), ('a_fg_color', np.float32, 4), ('a_bg_color', np.float32, 4), ('a_size', np.float32, 1), ('a_edgewidth', np.float32, 1)]) data['a_fg_color'] = edge_color data['a_bg_color'] = face_color if edge_width is not None: data['a_edgewidth'] = edge_width else: data['a_edgewidth'] = size * edge_width_rel data['a_position'][:, :pos.shape[1]] = pos data['a_size'] = size self.shared_program['u_antialias'] = self.antialias # XXX make prop self._data = data self._vbo.set_data(data) self.shared_program.bind(self._vbo) self.update()