Beispiel #1
0
def map_property(
    prop: np.ndarray,
    colormap: Colormap,
    contrast_limits: Union[None, Tuple[float, float]] = None,
) -> Tuple[np.ndarray, Tuple[float, float]]:
    """Apply a colormap to a property

    Parameters
    ----------
    prop : np.ndarray
        The property to be colormapped
    colormap : vispy.color.Colormap
        The vispy colormap object to apply to the property
    contrast_limits: Union[None, Tuple[float, float]]
        The contrast limits for applying the colormap to the property.
        If a 2-tuple is provided, it should be provided as (lower_bound, upper_bound).
        If None is provided, the contrast limits will be set to (property.min(), property.max()).
        Default value is None.
    """

    if contrast_limits is None:
        contrast_limits = (prop.min(), prop.max())
    normalized_properties = np.interp(prop, contrast_limits, (0, 1))
    mapped_properties = colormap.map(normalized_properties)

    return mapped_properties, contrast_limits
Beispiel #2
0
def test_colormap(name):
    np.random.seed(0)

    cmap = AVAILABLE_COLORMAPS[name]

    # Test can map random 0-1 values
    values = np.random.rand(50)
    colors = cmap.map(values)
    assert colors.shape == (len(values), 4)

    # Create vispy colormap and check current colormaps match vispy
    # colormap
    vispy_cmap = VispyColormap(*cmap)
    vispy_colors = vispy_cmap.map(values)
    np.testing.assert_almost_equal(colors, vispy_colors, decimal=6)
Beispiel #3
0
class Viewer3D(object):
    """
    A class for displaying a 3D model.
    """
    #%%
    scaling = 10  # VisPy rendering very poor when values < 1, so scale up
    __scene = None  # Don't import VisPy unless and until actually needed
    __geometry = None
    __io = None
    __gloo = None

    #%%
    def __init__(self, background='#cfcfef', scaling=20, el_az=None):
        if Viewer3D.__scene is None:
            from vispy import scene, geometry, io, gloo
            Viewer3D.__scene = scene
            Viewer3D.__geometry = geometry
            Viewer3D.__io = io
            Viewer3D.__gloo = gloo

            # Available colormaps in Vispy:
            # autumn, blues, cool, greens, reds, spring, summer, fire, grays, hot, ice, winter, light_blues,
            # orange, viridis, coolwarm, PuGr, GrBu, GrBu_d, RdBu, cubehelix, single_hue, hsl, husl, diverging, RdYeBuCy

            from vispy.color import Colormap
            self.__cmap = Colormap(['blue', 'cyan', 'green', 'yellow', 'red'])

        if el_az is None:
            el = 30
            az = 45
        else:
            el, az = el_az

        self.__canvas = Viewer3D.__scene.SceneCanvas(keys='interactive',
                                                     size=(1200, 900),
                                                     show=True)

        # Set up a viewbox to display the cube with interactive arcball
        self.__view = self.__canvas.central_widget.add_view()
        self.__view.bgcolor = background
        self.__view.camera = Viewer3D.__scene.cameras.turntable.TurntableCamera(
            scale_factor=scaling, elevation=el, azimuth=az)
        self.__view.padding = 5

        Viewer3D.__scene.visuals.XYZAxis(parent=self.__view.scene)

        self.__vertex = None
        self.__vcolor = None

#%%

    def Run(self, smooth=True, save_as=None):
        if self.__vertex is not None:
            data = Viewer3D.__geometry.MeshData(vertices=self.__vertex,
                                                vertex_colors=self.__vcolor)
            if smooth:
                mesh = Viewer3D.__scene.visuals.Mesh(meshdata=data,
                                                     shading='smooth',
                                                     parent=self.__view.scene)
            else:
                mesh = Viewer3D.__scene.visuals.Mesh(meshdata=data,
                                                     parent=self.__view.scene)

        if save_as is None:
            self.__canvas.app.run()
        else:
            image = self.__canvas.render()  # sort-of works, but problematic
            Viewer3D.__io.write_png(save_as, image)

#%%

    def Line(self, vertices, color=None):
        """
        Draws a line in 3D

        Parameters
        ----------
        vertices : numpy.ndarray
            Array of vertices (Nv,3) to draw line through
        color : [r,g,b,a] array
            Color to use for drawing line; optional [default: black]
        """
        if color is None:
            color = 'black'

        Viewer3D.__scene.visuals.Line(pos=(vertices * Viewer3D.scaling),
                                      color=color,
                                      parent=self.__view.scene)

#%%

    def Add(self, triangle, color, uniform=True):
        """
        Adds a triangle to the 3D mesh

        Parameters
        ----------
        triangle : numpy.ndarray
            Array of vertices (3,3) for triangle
        color : [[r,g,b,a],] array
            Array of one or three colors to use for displaying face
        """
        if self.__vertex is None:
            self.__vertex = np.asarray([triangle]) * Viewer3D.scaling
            if len(color) == 1:
                self.__vcolor = np.zeros((1, 3, 4))
                self.__vcolor[0, :] = color[0]
            else:
                self.__vcolor = np.asarray([color])
        else:
            vcoord = np.asarray([triangle]) * Viewer3D.scaling
            if len(color) == 1:
                vcolor = np.zeros((1, 3, 4))
                vcolor[0, :] = color[0]
            else:
                vcolor = np.asarray([color])
            self.__vertex = np.append(self.__vertex, vcoord, axis=0)
            self.__vcolor = np.append(self.__vcolor, vcolor, axis=0)

#%%

    def ColorFromValue(self, c):
        """
        Converts a value in a range to a color

        Parameters
        ----------
        c : numpy.ndarray
            Array of values to map to color

        Returns
        -------
        color : [[r,g,b,a],] array
            mapped color
        """
        return self.__cmap.map(c)

#%%

    def ColorBar(self, description, c_min_max_str):
        """
        Add a colorbar to the plot

        """
        # Overlays a grid to position subviews & widgets:
        grid = self.__canvas.central_widget.add_grid(margin=10)

        if sys.platform == "darwin":
            # On OSX, positioning of text in colorbar is unhelpful; this hackery seems to make it look okay, however
            label = '\n\n ' + description
        else:
            label = description

        cbar = Viewer3D.__scene.widgets.ColorBarWidget(self.__cmap,
                                                       'left',
                                                       clim=c_min_max_str,
                                                       label=label,
                                                       axis_ratio=0.075,
                                                       padding=[0.5, 0.5],
                                                       border_width=1)

        grid.add_widget(cbar, col=0)
        # which centers the colorbar unless we add something else to effectively nudge it to the left:
        view = grid.add_view(col=1, col_span=3)
        view.visible = False
Beispiel #4
0
galaxy_data = load_galaxy_data("../data/vollim_dr7_cbp_102709.fits")

print("Galaxies: ", galaxy_data.shape)
print("Voids: ", voids_tri_x.shape, voids_tri_y.shape, voids_tri_z.shape,
      voids_norm.shape, voids_id.shape)
################################################################################

################################################################################
# Void coloring
#-------------------------------------------------------------------------------
num_voids = len(np.unique(voids_id))

cm = Colormap(
    ['#880000', '#EEEE00', "#008800", '#EE00EE', '#000088', '#EE00EE'])

void_color_vals = cm.map(np.linspace(0, 1.0, num_voids))

print(void_color_vals.shape)

void_colors = np.empty((num_voids, 4), dtype=np.float32)

for idx in range(void_colors.shape[0]):

    void_id = idx

    #print(hole_group)

    void_colors[idx, :] = void_color_vals[void_id]
################################################################################

################################################################################
Beispiel #5
0
print("Holes:", holes_xyz.shape, holes_radii.shape, holes_flags.shape)

################################################################################
#
# VOID COLORING
#
################################################################################

hole_IDs = np.unique(holes_flags)

num_hole_groups = len(hole_IDs)

cm = Colormap(
    ['#880000', '#EEEE00', "#008800", '#EE00EE', '#000088', '#EE00EE'])

hole_color_vals = cm.map(np.linspace(0, 1.0, num_hole_groups))

print(hole_color_vals.shape)

void_hole_colors = np.empty((holes_xyz.shape[0], 4), dtype=np.float32)

for idx in range(void_hole_colors.shape[0]):

    hole_group = holes_flags[idx]

    #print(hole_group)

    void_hole_colors[idx, :] = hole_color_vals[
        hole_group - 1]  # uhg you used 1-based indexing WHY? :D

################################################################################