Пример #1
0
    def get_data_range(self, arr=None, preference='cell'):
        """Get the non-NaN min and max of a named scalar array

        Parameters
        ----------
        arr : str, np.ndarray, optional
            The name of the array to get the range. If None, the active scalar
            is used

        preference : str, optional
            When scalars is specified, this is the perfered scalar type to
            search for in the dataset.  Must be either ``'point'``, ``'cell'``,
            or ``'field'``.

        """
        if arr is None:
            # use active scalar array
            _, arr = self.active_scalar_info
        if isinstance(arr, str):
            arr = get_array(self, arr, preference=preference)
        # If array has no tuples return a NaN range
        if arr is None or arr.size == 0 or not np.issubdtype(
                arr.dtype, np.number):
            return (np.nan, np.nan)
        # Use the array range
        return np.nanmin(arr), np.nanmax(arr)
Пример #2
0
    def get_data_range(self, arr=None, preference='row'):
        """Get the non-NaN min and max of a named array.

        Parameters
        ----------
        arr : str, np.ndarray, optional
            The name of the array to get the range. If None, the active scalar
            is used

        preference : str, optional
            When scalars is specified, this is the preferred array type
            to search for in the dataset.  Must be either ``'row'`` or
            ``'field'``.

        """
        if arr is None:
            # use the first array in the row data
            self.GetRowData().GetArrayName(0)
        if isinstance(arr, str):
            arr = get_array(self, arr, preference=preference)
        # If array has no tuples return a NaN range
        if arr is None or arr.size == 0 or not np.issubdtype(
                arr.dtype, np.number):
            return (np.nan, np.nan)
        # Use the array range
        return np.nanmin(arr), np.nanmax(arr)
Пример #3
0
    def get_data_range(self, arr=None, preference='cell'):
        """Get the non-NaN min and max of a named array.

        Parameters
        ----------
        arr : str, np.ndarray, optional
            The name of the array to get the range. If None, the
            active scalars is used.

        preference : str, optional
            When scalars is specified, this is the preferred array type
            to search for in the dataset.  Must be either ``'point'``,
            ``'cell'``, or ``'field'``.

        """
        if arr is None:
            # use active scalars array
            _, arr = self.active_scalars_info
        if isinstance(arr, str):
            name = arr
            # This can return None when an array is not found - expected
            arr = get_array(self, name, preference=preference)
            if arr is None:
                # Raise a value error if fetching the range of an unknown array
                raise ValueError(f'Array `{name}` not present.')
        # If array has no tuples return a NaN range
        if arr is None or arr.size == 0 or not np.issubdtype(
                arr.dtype, np.number):
            return (np.nan, np.nan)
        # Use the array range
        return np.nanmin(arr), np.nanmax(arr)
Пример #4
0
 def get_array(self,
               name: str,
               preference='cell',
               info=False) -> Union[Tuple, np.ndarray]:
     """Search both point, cell and field data for an array."""
     return get_array(self,
                      name,
                      preference=preference,
                      info=info,
                      err=True)
Пример #5
0
 def set_active_vectors(self, name, preference='point'):
     """Finds the vectors by name and appropriately sets it as active"""
     _, field = get_array(self, name, preference=preference, info=True)
     if field == POINT_DATA_FIELD:
         self.GetPointData().SetActiveVectors(name)
     elif field == CELL_DATA_FIELD:
         self.GetCellData().SetActiveVectors(name)
     else:
         raise RuntimeError('Data field ({}) not useable'.format(field))
     self._active_vectors_info = [field, name]
Пример #6
0
 def set_active_scalar(self, name, preference='cell'):
     """Finds the scalar by name and appropriately sets it as active"""
     _, field = get_array(self, name, preference=preference, info=True)
     self._last_active_scalar_name = self.active_scalar_info[1]
     if field == POINT_DATA_FIELD:
         self.GetPointData().SetActiveScalars(name)
     elif field == CELL_DATA_FIELD:
         self.GetCellData().SetActiveScalars(name)
     else:
         raise RuntimeError('Data field ({}) not useable'.format(field))
     self._active_scalar_info = [field, name]
Пример #7
0
 def rename_scalar(self, old_name, new_name, preference='cell'):
     """Changes array name by searching for the array then renaming it"""
     _, field = get_array(self, old_name, preference=preference, info=True)
     if field == POINT_DATA_FIELD:
         self.point_arrays[new_name] = self.point_arrays.pop(old_name)
     elif field == CELL_DATA_FIELD:
         self.cell_arrays[new_name] = self.cell_arrays.pop(old_name)
     elif field == FIELD_DATA_FIELD:
         self.field_arrays[new_name] = self.field_arrays.pop(old_name)
     else:
         raise RuntimeError('Array not found.')
     if self.active_scalar_info[1] == old_name:
         self.set_active_scalar(new_name, preference=field)
Пример #8
0
 def rename_array(self, old_name: str, new_name: str, preference='cell'):
     """Change array name by searching for the array then renaming it."""
     _, field = get_array(self, old_name, preference=preference, info=True)
     was_active = False
     if self.active_scalars_name == old_name:
         was_active = True
     if field == FieldAssociation.POINT:
         self.point_arrays[new_name] = self.point_arrays.pop(old_name)
     elif field == FieldAssociation.CELL:
         self.cell_arrays[new_name] = self.cell_arrays.pop(old_name)
     elif field == FieldAssociation.NONE:
         self.field_arrays[new_name] = self.field_arrays.pop(old_name)
     else:
         raise KeyError(f'Array with name {old_name} not found.')
     if was_active:
         self.set_active_scalars(new_name, preference=field)
Пример #9
0
 def set_active_vectors(self, name, preference='point'):
     """Finds the vectors by name and appropriately sets it as active
     To deactivate any active scalars, pass ``None`` as the ``name``.
     """
     if name is None:
         self.GetCellData().SetActiveVectors(None)
         self.GetPointData().SetActiveVectors(None)
         return
     _, field = get_array(self, name, preference=preference, info=True)
     if field == POINT_DATA_FIELD:
         self.GetPointData().SetActiveVectors(name)
     elif field == CELL_DATA_FIELD:
         self.GetCellData().SetActiveVectors(name)
     else:
         raise RuntimeError('Data field ({}) not useable'.format(field))
     self._active_vectors_info = [field, name]
Пример #10
0
 def get_data_range(self, name):
     """Gets the min/max of a scalar given its name across all blocks"""
     mini, maxi = np.inf, -np.inf
     for i in range(self.n_blocks):
         data = self[i]
         if data is None:
             continue
         # get the scalar if availble
         arr = get_array(data, name)
         if arr is None or not np.issubdtype(arr.dtype, np.number):
             continue
         tmi, tma = np.nanmin(arr), np.nanmax(arr)
         if tmi < mini:
             mini = tmi
         if tma > maxi:
             maxi = tma
     return mini, maxi
Пример #11
0
    def set_active_vectors(self, name, preference='point'):
        """Find the vectors by name and appropriately sets it as active.

        To deactivate any active scalars, pass ``None`` as the ``name``.

        """
        if name is None:
            self.GetCellData().SetActiveVectors(None)
            self.GetPointData().SetActiveVectors(None)
            return
        _, field = get_array(self, name, preference=preference, info=True)
        if field == FieldAssociation.POINT:
            self.GetPointData().SetActiveVectors(name)
        elif field == FieldAssociation.CELL:
            self.GetCellData().SetActiveVectors(name)
        else:
            raise ValueError(f'Data field ({field}) not usable')
        self._active_vectors_info = ActiveArrayInfo(field, name)
Пример #12
0
    def set_active_tensors(self, name: str, preference='point'):
        """Find the tensors by name and appropriately sets it as active.

        To deactivate any active tensors, pass ``None`` as the ``name``.
        """
        if name is None:
            self.GetCellData().SetActiveTensors(None)
            self.GetPointData().SetActiveTensors(None)
            field = FieldAssociation.POINT
        else:
            _, field = get_array(self, name, preference=preference, info=True)
            if field == FieldAssociation.POINT:
                ret = self.GetPointData().SetActiveTensors(name)
            elif field == FieldAssociation.CELL:
                ret = self.GetCellData().SetActiveTensors(name)
            else:
                raise ValueError(f'Data field ({field}) not usable')

            if ret < 0:
                raise ValueError(f'Data field ({field}) could not be set as the active tensors')

        self._active_tensors_info = ActiveArrayInfo(field, name)
Пример #13
0
def test_get_array():
    grid = pyvista.UnstructuredGrid(ex.hexbeamfile)
    # add array to both point/cell data with same name
    carr = np.random.rand(grid.n_cells)
    grid._add_cell_array(carr, 'test_data')
    parr = np.random.rand(grid.n_points)
    grid._add_point_array(parr, 'test_data')
    # add other data
    oarr = np.random.rand(grid.n_points)
    grid._add_point_array(oarr, 'other')
    farr = np.random.rand(grid.n_points * grid.n_cells)
    grid._add_field_array(farr, 'field_data')
    assert np.allclose(
        carr, utilities.get_array(grid, 'test_data', preference='cell'))
    assert np.allclose(
        parr, utilities.get_array(grid, 'test_data', preference='point'))
    assert np.allclose(oarr, utilities.get_array(grid, 'other'))
    assert utilities.get_array(grid, 'foo') is None
    assert utilities.get_array(grid, 'test_data', preference='field') is None
    assert np.allclose(
        farr, utilities.get_array(grid, 'field_data', preference='field'))
Пример #14
0
    def add_mesh_isovalue(self,
                          mesh,
                          scalars=None,
                          compute_normals=False,
                          compute_gradients=False,
                          compute_scalars=True,
                          preference='point',
                          title=None,
                          pointa=(.4, .9),
                          pointb=(.9, .9),
                          widget_color=None,
                          **kwargs):
        """Create a contour of a mesh with a slider.

        Add a mesh to the scene with a slider widget that is used to
        contour at an isovalue of the *point* data on the mesh interactively.

        The isovalue mesh is saved to the ``.isovalue_meshes`` attribute on
        the plotter.

        Parameters
        ----------
        mesh : pyvista.Common
            The input dataset to add to the scene and contour

        scalars : str
            The string name of the scalars on the mesh to threshold and display

        kwargs : dict
            All additional keyword arguments are passed to ``add_mesh`` to
            control how the mesh is displayed.

        """
        if isinstance(mesh, pyvista.MultiBlock):
            raise TypeError(
                'MultiBlock datasets are not supported for this widget.')
        name = kwargs.get('name', str(hex(id(mesh))))
        # set the array to contour on
        if mesh.n_arrays < 1:
            raise AssertionError(
                'Input dataset for the contour filter must have data arrays.')
        if scalars is None:
            field, scalars = mesh.active_scalars_info
        else:
            _, field = get_array(mesh,
                                 scalars,
                                 preference=preference,
                                 info=True)
        # NOTE: only point data is allowed? well cells works but seems buggy?
        if field != pyvista.POINT_DATA_FIELD:
            raise AssertionError(
                'Contour filter only works on Point data. Array ({}) is in the Cell data.'
                .format(scalars))

        rng = mesh.get_data_range(scalars)
        kwargs.setdefault('clim', kwargs.pop('rng', rng))
        if title is None:
            title = scalars

        alg = vtk.vtkContourFilter()
        alg.SetInputDataObject(mesh)
        alg.SetComputeNormals(compute_normals)
        alg.SetComputeGradients(compute_gradients)
        alg.SetComputeScalars(compute_scalars)
        alg.SetInputArrayToProcess(0, 0, 0, field, scalars)
        alg.SetNumberOfContours(1)  # Only one contour level

        self.add_mesh(mesh.outline(), name=name + "outline", opacity=0.0)

        if not hasattr(self, "isovalue_meshes"):
            self.isovalue_meshes = []
        isovalue_mesh = pyvista.wrap(alg.GetOutput())
        self.isovalue_meshes.append(isovalue_mesh)

        def callback(value):
            alg.SetValue(0, value)
            alg.Update()
            isovalue_mesh.shallow_copy(alg.GetOutput())

        self.add_slider_widget(callback=callback,
                               rng=rng,
                               title=title,
                               color=widget_color,
                               pointa=pointa,
                               pointb=pointb)

        kwargs.setdefault("reset_camera", False)
        actor = self.add_mesh(isovalue_mesh, scalars=scalars, **kwargs)

        return actor
Пример #15
0
    def add_mesh_threshold(self,
                           mesh,
                           scalars=None,
                           invert=False,
                           widget_color=None,
                           preference='cell',
                           title=None,
                           pointa=(.4, .9),
                           pointb=(.9, .9),
                           continuous=False,
                           **kwargs):
        """Apply a threshold on a mesh with a slider.

        Add a mesh to the scene with a slider widget that is used to
        threshold the mesh interactively.

        The threshold mesh is saved to the ``.threshold_meshes`` attribute on
        the plotter.

        Parameters
        ----------
        mesh : pyvista.Common
            The input dataset to add to the scene and threshold

        scalars : str
            The string name of the scalars on the mesh to threshold and display

        invert : bool
            Invert/flip the threshold

        kwargs : dict
            All additional keyword arguments are passed to ``add_mesh`` to
            control how the mesh is displayed.

        """
        if isinstance(mesh, pyvista.MultiBlock):
            raise TypeError(
                'MultiBlock datasets are not supported for threshold widget.')
        name = kwargs.get('name', str(hex(id(mesh))))
        if scalars is None:
            field, scalars = mesh.active_scalars_info
        arr, field = get_array(mesh, scalars, preference=preference, info=True)
        if arr is None:
            raise AssertionError('No arrays present to threshold.')
        rng = mesh.get_data_range(scalars)
        kwargs.setdefault('clim', kwargs.pop('rng', rng))
        if title is None:
            title = scalars

        self.add_mesh(mesh.outline(), name=name + "outline", opacity=0.0)

        alg = vtk.vtkThreshold()
        alg.SetInputDataObject(mesh)
        alg.SetInputArrayToProcess(
            0, 0, 0, field,
            scalars)  # args: (idx, port, connection, field, name)
        alg.SetUseContinuousCellRange(continuous)

        if not hasattr(self, "threshold_meshes"):
            self.threshold_meshes = []
        threshold_mesh = pyvista.wrap(alg.GetOutput())
        self.threshold_meshes.append(threshold_mesh)

        def callback(value):
            if invert:
                alg.ThresholdByLower(value)
            else:
                alg.ThresholdByUpper(value)
            alg.Update()
            threshold_mesh.shallow_copy(alg.GetOutput())

        self.add_slider_widget(callback=callback,
                               rng=rng,
                               title=title,
                               color=widget_color,
                               pointa=pointa,
                               pointb=pointb)

        kwargs.setdefault("reset_camera", False)
        actor = self.add_mesh(threshold_mesh, scalars=scalars, **kwargs)

        return actor
Пример #16
0
 def get_array(self, name, preference='cell', info=False):
     """Search both point, cell and field data for an array."""
     return get_array(self, name, preference=preference, info=info)