vectorose.plotting ================== .. py:module:: vectorose.plotting .. autoapi-nested-parse:: Plotting functions for VectoRose. After constructing the various histograms using the classes and functions present in :mod:`.tregenza_sphere`, :mod:`.triangle_sphere` and :mod:`.polar_data`, this module can be used to visualise the results. Classes ------- .. autoapisummary:: vectorose.plotting.CardinalDirection vectorose.plotting.RotationDirection vectorose.plotting.AngularUnits vectorose.plotting.SphereProjection vectorose.plotting.ViewingPlanes vectorose.plotting.SpherePlotter Functions --------- .. autoapisummary:: vectorose.plotting.produce_1d_scalar_histogram vectorose.plotting.produce_polar_histogram_plot vectorose.plotting.produce_phi_theta_polar_histogram_plots vectorose.plotting.produce_labelled_3d_plot vectorose.plotting.produce_3d_triangle_sphere_plot vectorose.plotting.produce_3d_tregenza_sphere_plot vectorose.plotting.construct_uv_sphere_vertices vectorose.plotting.construct_uv_sphere_mesh vectorose.plotting.__update_sphere_viewing_angle vectorose.plotting.animate_sphere_plot vectorose.plotting.construct_confidence_cone vectorose.plotting.produce_3d_confidence_cone_plot Module Contents --------------- .. py:class:: CardinalDirection Bases: :py:obj:`str`, :py:obj:`enum.Enum` Cardinal directions. This string-based enumerated type is useful when preparing 2D polar figures. Members reflect cardinal directions, which may be used to indicate positions on circular (polar) axes. The values are consistent with the Matplotlib convention (see :meth:`matplotlib.projections.polar.PolarAxes.set_theta_zero_location` for details). :Members: * **NORTH** -- Location directly upwards. * **NORTH_WEST** -- Location in the upper left corner. * **WEST** -- Location on the left side. * **SOUTH_WEST** -- Location in the lower left corner. * **SOUTH** -- Location directly downwards. * **SOUTH_EAST** -- Location in the lower right corner. * **EAST** -- Location on the right side. * **NORTH_EAST** -- Location in the upper right corner. .. seealso:: :obj:`matplotlib.projections.polar.PolarAxes.set_theta_zero_location` Set the zero position of a polar plot using one of the member values for this type. .. py:attribute:: NORTH :value: 'N' .. py:attribute:: NORTH_WEST :value: 'NW' .. py:attribute:: WEST :value: 'W' .. py:attribute:: SOUTH_WEST :value: 'SW' .. py:attribute:: SOUTH :value: 'S' .. py:attribute:: SOUTH_EAST :value: 'SE' .. py:attribute:: EAST :value: 'E' .. py:attribute:: NORTH_EAST :value: 'NE' .. py:class:: RotationDirection Bases: :py:obj:`enum.IntEnum` Rotation directions. This integer-based enumerated type represents two-dimensional rotation direction. The convention used is consistent with the Matplotlib documentation (see :meth:matplotlib.projections.polar.PolarAxes.set_theta_direction for details). :Members: * **CLOCKWISE** -- Clockwise, or rightward rotation. * **COUNTER_CLOCKWISE** -- Counter-clockwise, anti-clockwise, or leftward rotation. .. seealso:: :obj:`matplotlib.projections.polar.PolarAxes.set_theta_direction` Set the rotation direction of a polar plot using one of the member values for this type. .. py:attribute:: CLOCKWISE :value: -1 .. py:attribute:: COUNTER_CLOCKWISE :value: 1 .. py:class:: AngularUnits Bases: :py:obj:`enum.Enum` Angular units. This enumerated type represents angular units (degrees or radians). It **does not** provide any implementation for converting from one to the other, as this functionality is already very well included in NumPy. :Members: * **DEGREES** -- Represent angles in degrees (typically in the range 0 to 360 or -180 to +180). * **RADIANS** -- Indicates that angle is in radians (typically in the range 0 to :math:`2\pi` or :math:`-\pi` to :math:`\pi`). .. seealso:: :obj:`numpy.degrees` Convert numeric values from radians into degrees. :obj:`numpy.radians` Convert numeric values from degrees into radians. .. py:attribute:: DEGREES :value: 0 .. py:attribute:: RADIANS :value: 1 .. py:class:: SphereProjection Bases: :py:obj:`enum.Enum` Projection type for 3D figures. Enumerated type representing the projection type for 3D figures. The values of the members are compatible with the Matplotlib 3D axes method :meth:`mpl_toolkits.mplot3d.axes3d.Axes3D.set_proj_type`. :Members: * **ORTHOGRAPHIC** -- Orthographic projection. * **PERSPECTIVE** -- Perspective projection. .. py:attribute:: ORTHOGRAPHIC :value: 'ortho' .. py:attribute:: PERSPECTIVE :value: 'persp' .. py:class:: ViewingPlanes Bases: :py:obj:`str`, :py:obj:`enum.Enum` Built-in viewing angles. Each member represents a viewing plane (or the isometric angle) defined in PyVista. .. seealso:: :obj:`pyvista.Plotter.camera_position` The function used to set the view to one of these planes. .. py:attribute:: XY :value: 'xy' .. py:attribute:: XZ :value: 'xz' .. py:attribute:: YZ :value: 'yz' .. py:attribute:: YX :value: 'yx' .. py:attribute:: ZX :value: 'zx' .. py:attribute:: ZY :value: 'zy' .. py:attribute:: ISO :value: 'iso' .. py:class:: SpherePlotter(sphere_meshes: List[pyvista.PolyData] | pyvista.PolyData, visible_shells: Optional[List[int]] = None, off_screen: bool = None, cmap: str = 'viridis') Produce beautiful, fast 3D sphere plots using PyVista. .. py:attribute:: _sphere_meshes :type: List[pyvista.PolyData] The meshes representing individual shells. .. py:attribute:: _largest_radius :type: float The largest radius of a plotted sphere. .. py:attribute:: _active_shell :type: int The index of the currently-active shell. .. py:attribute:: _visible_shells :type: List[int] The indicies of the shells to plot as visible. .. py:attribute:: _active_shell_opacity :type: float The opacity of the currently active shell. .. py:attribute:: _inactive_shell_opacity :type: float The opacity of the inactive shells. .. py:attribute:: _plotter :type: Optional[pyvista.Plotter] Plotter to use to visualise the spheres. .. py:attribute:: _sphere_actors :type: List[pyvista.Actor] The actors representing the plotted spheres. .. py:attribute:: _phi_axis_actor :type: Optional[pyvista.Actor] The actor representing the semicircular phi axis. .. py:attribute:: _theta_axis_actor :type: Optional[pyvista.Actor] The actor representing the circular theta axis. .. py:attribute:: _point_label_actor :type: Optional[vtk.vtkActor2D] The actor controlling the point labels. .. py:attribute:: _picked_cells :type: List[pyvista.UnstructuredGrid] List of picked cells. .. py:attribute:: _picked_cell_actors :type: Dict[int, pyvista.Actor] Actors for picked faces. .. py:attribute:: _picking_active :type: bool Indicate whether cell picking is active. .. py:attribute:: cmap :type: str The colour map to use when visualising the data. .. py:attribute:: _has_movie_open :type: bool Indicate whether a movie is currently a being manually written. .. py:property:: sphere_meshes :type: List[pyvista.PolyData] Access the wrapped sphere meshes. .. py:property:: phi_axis_visible :type: bool Indicate whether the phi axis is visible. .. py:property:: theta_axis_visible :type: bool Indicate whether the theta axis is visible. .. py:property:: axis_labels_visible :type: bool Indicate whether the axis labels are visible. .. py:property:: sliders_visible :type: bool Indicate whether the sliders are visible. If the plot was created without sliders, this always evaluates to `False`. .. py:property:: scalar_bars_visible :type: bool Indicate whether the scalar bars are visible. If there are no scalar bars, this will always return `False`. .. py:property:: active_shell :type: int Get or set the active shell index. .. warning:: This property describes the **index**, not the shell number. The values provided here are offset by one compared with the slider values. .. py:property:: active_shell_opacity :type: float Get the active shell opacity. Active sphere opacity between 0 (transparent) and 1 (opaque). .. py:property:: inactive_shell_opacity :type: float Get the opacity of the inactive shells. Inactive sphere opacity between 0 (transparent) and 1 (opaque). .. py:property:: radius :type: float Access the sphere radius. .. py:property:: has_produced_plot :type: bool Indicate whether the plot has been produced. .. py:property:: current_phi :type: float Get the phi value under the current view in degrees. .. rubric:: Notes This value makes the most sense if the camera has the origin as the focal point. .. py:property:: current_theta :type: float Get the theta value under the current view in degrees. .. rubric:: Notes This value makes the most sense if the camera has the origin as the focal point. .. py:property:: current_azimuth :type: float Get the current azimuth in degrees between 0 and 360. .. rubric:: Notes This value is *related* to the :attr:`~.current_theta`, but not identical, as it is measured clockwise from the `+x` axis. This value is 90° offset of the :math:`\theta` as defined in **mathematical spherical coordinates**. .. py:property:: current_elevation :type: float Get the current elevation in degrees between 0 and 180. .. rubric:: Notes This value is **the same as** that returned by :attr:`~.current_phi`. .. py:property:: current_roll :type: float Get the current roll in degrees, measured between 0 and 360. .. rubric:: Notes This value is computed by undoing the azimuth and elevation and then measuring the angle that transformed vector and the original camera up vector ``[0, 1, 0]``. .. py:property:: cell_picking_active :type: bool Indicate whether interactive cell picking is active. .. py:property:: picked_cells :type: pandas.DataFrame Get picked face scalar data. :returns: :class:`pandas.DataFrame` -- All cell scalar data for the picked mesh cells. These values can then be used by the :class:`.SphereBase` sphere to extract vectors from the picked cells. If no cells are picked, an empty :class:`pandas.DataFrame` is produced. See **Notes** for full details on the format. .. rubric:: Notes The return :class:`pandas.DataFrame` always contains at least the following keys: * ``index`` - the cell index within the sphere mesh * orientation bin information - sphere-dependent keys providing the orientation bin * ``frequency`` - the frequency value associated with the face * ``shell`` - if multiple shells are present in the data, the shell corresponding to the selected cell (absent if only one shell) Other keys may be present, but these are the ones most important for VectoRose. .. py:property:: has_movie_open :type: bool Indicate whether a movie is currently being manually written. .. py:method:: _get_spherical_coordinates_from_camera() -> numpy.ndarray Get the spherical coordinates for the camera location. :returns: :class:`numpy.ndarray` -- Array of shape ``(3,)`` containing the phi, theta and radius for the camera's position in 3D space. .. rubric:: Notes The values in this function are not recentred if the camera is translated in space. .. py:method:: _update_active_sphere_opacity(new_opacity: float) Update the opacity level of the active sphere. .. py:method:: _update_inactive_sphere_opacity(new_opacity: float) Update the opacity level of the inactive spheres. .. py:method:: _update_active_sphere(new_selected_shell_number: float) Update the active sphere number. .. py:method:: _update_show_axes(show_axes: bool) Update whether the axes are drawn. .. py:method:: pick_cells(cell_indices: pandas.Series | pandas.DataFrame) Pick cells in the plotted sphere or spherical shells. :param cell_indices: Either a :class:`pandas.Series` containing the cell indices in the case of purely directed or oriented data, or a :class:`pandas.DataFrame` containing a column ``shell`` for the magnitude shell and ``index`` for the cell index. .. warning:: If the same cell is provided an even number of times, it will become deselected. Each selection is a toggle. .. py:method:: _pick_cells(cell: pyvista.UnstructuredGrid) Callback when a mesh face is picked. .. py:method:: add_spherical_axes(plot_phi: bool = True, plot_theta: bool = True, phi_increment: int = 30, theta_increment: int = 30, axis_distance_fixed: float = 0.2, axis_distance_relative: float = 1, axis_thickness: float = 0.05) Add spherical axes to the current plotter. :param plot_phi: Indicate that the phi axis is to be plotted. :param plot_theta: Indicate that the theta axis is to be plotted. :param phi_increment: Label increment for the phi values. :param theta_increment: Label increment for the theta values. :param axis_distance_fixed: Fixed distance from the outer shell to the axis. :param axis_distance_relative: Relative distance from the outer shell to the axis. :param axis_thickness: Absolute thickness of the axes. .. py:method:: clear_axes() Clear the plotted axes. .. py:method:: clear_plotter() Clear and remove the current plotter. .. py:method:: clear_picked_cells() Clear the picked cells. .. py:method:: produce_plot(add_sliders: bool = True, series_name: str = 'frequency', min_value: Optional[float] = None, max_value: Optional[float] = None, use_log_scale: bool = False) Produce the 3D visual plot for the current spheres. :param add_sliders: Indicate whether the opacity sliders should be added to the plotting window. :param series_name: Name of the scalars to consider. :param min_value: Optional minimum value for the colour map. :param max_value: Optional maximum value for the colour map. :param use_log_scale: Indicate whether to use a log scale. .. warning:: This function produces the :class:`pyvista.Plotter`. The method :meth:`SpherePlotter.show` must be called to view the plot. If `use_log_scale` is set to `True`, the input scalar data must be greater than zero. .. py:method:: show(*args, **kwargs) Show the plotter window. :param \*args: Arguments to pass to the method :meth:`pyvista.Plotter.show`. :param \*\*kwargs: Keyword arguments to pass to the method :meth:`pyvista.Plotter.show`. :raises AssertionError: If the plot has not yet been produced using the method :meth:`.produce_plot`. .. seealso:: :obj:`pyvista.Plotter.show` Method used to show a PyVista plotter. .. py:method:: close(deep_clean: bool = True) Close the plotting window and clear the associated memory. :param deep_clean: Indicate whether a deep clean of the memory should be performed after closing. .. py:method:: rotate_to_view(phi: Optional[float] = None, theta: Optional[float] = None, use_degrees: bool = True, zoom: Optional[float] = None, focal_depth: Optional[float] = None) Move the camera to focus on a specific orientation. :param phi: The co-latitude to centre on. If `None`, then the value of phi is unchanged. :param theta: The azimuthal angle to centre on. If `None`, then the value of theta is unchanged. :param use_degrees: Indicate whether the angles should be interpreted in degrees. :param zoom: Factor to zoom the view as a floating point value. See :meth:`pyvista.Camera.zoom` for a full explanation. :param focal_depth: Distance between the camera and the focal point. .. seealso:: :obj:`pyvista.Plotter.camera_position` Information about the camera from the plotter, used to compute the orientation angles. :obj:`pyvista.Camera.zoom` Control the camera zoom. .. rubric:: Notes The point of focus of the camera remains at the origin. This method simply changes the position of the camera in space and changes the up direction. .. py:method:: rotate_camera_euler(azimuth: float, elevation: float, roll: float, use_degrees: bool = True) Rotate the camera using specified intrinsic Euler angles. :param azimuth: Angular rotation about the global `Z`-axis, measured counter-clockwise from the positive `X`-axis. :param elevation: Angular tilt about the transformed `X`-axis, measured counter-clockwise from the positive `Z`-axis down. :param roll: Camera rotation about the transformed `Z`-axis, measured counter-clockwise. :param use_degrees: Indicate whether angles should be considered in degrees. .. warning:: Note the definitions of the angles! These don't correspond to the angles :math:`\phi` and :math:`\theta` defined elsewhere. Also, the :attr:`~.current_roll`, :attr:`~.current_azimuth` and :attr:`~.current_elevation` may not match the values passed here due to redundancy. .. rubric:: Notes Before rotating, the view is aligned with the `XY` plane to ensure reproducible behaviour. The camera rotation is applied in the sequence `ZXZ`. First the camera is rotated about the local `Z` axis to set the azimuth. Then, the camera is rotated about the new local `X`-axis to set the correct elevation. Then, the camera is rolled along the new local `Z` axis. Additional information about Euler angles can be found at https://en.wikipedia.org/wiki/Euler_angles. .. py:method:: open_movie_file(filename: str, quality: int = 5, fps: int = 24) Open a movie file to record an animation. :param filename: The destination for the created video. Must end with either ``.mp4`` or ``.gif``. :param quality: Image quality for the video export, between 0 and 10. Ignored for exports as GIF. :param fps: Frame rate, number of frames per second in the exported video. .. warning:: This method only opens the video file. It does not save any of the frames. These must be written using the :meth:`.write_frame` method and then the file must be closed using :meth:`.close_movie`. .. seealso:: :obj:`pyvista.Plotter.open_movie` The wrapped function that actually creates the movie file. :obj:`.write_frame` Add frames to the open movie. :obj:`.close_movie` Close and finalise the current movie. .. py:method:: write_frame() Add a new frame to the current movie. .. warning:: The current plotter must have a movie file that is open. .. py:method:: close_movie() Close the movie currently being written. .. warning:: The current plotter must have a movie file that is open. .. py:method:: produce_rotating_video(filename: str, quality: int = 5, fps: int = 24, zoom_factor: float = 1.0, number_of_frames: int = 36, vertical_shift: Optional[float] = None, hide_sliders: bool = True) Produce a video orbiting around the sphere. Using the current plotter, produce a video orbiting around the visible shell. If there is no current plotter, a new one is produced. :param filename: Movie export filename, with extension provided. :param quality: Video export quality, between 0 and 10. :param fps: Frame rate for the exported video. :param zoom_factor: Factor to zoom when creating the frames. :param number_of_frames: Total number of frames to produce in the video. A higher number results in a smoother animation, but a larger file and longer processing time. :param vertical_shift: Upward shift of the orbital plane with respect to the ground. :param hide_sliders: Indicate whether to hide the sliders when producing the video. .. seealso:: :obj:`pyvista.Plotter.generate_orbital_path` generate the path necessary for the animation. .. rubric:: References This code is based on an example from the PyVista documentation, found at https://docs.pyvista.org/examples/02-plot/orbit. .. py:method:: produce_shells_video(filename: str, quality: int = 5, fps: int = 24, zoom_factor: float = 1.0, inward_direction: bool = True, boomerang: bool = False, azimuth: Optional[float] = None, elevation: Optional[float] = None, hide_sliders: bool = True, add_shell_text: bool = False) Produce a video revealing all shells in a plot. :param filename: Movie export filename, including file extension. :param quality: Video export quality, between 0 and 10. :param fps: Frame rate for the exported video. :param zoom_factor: Factor to zoom when creating the frames. :param inward_direction: Indicate whether the animation should progress from the outermost shell inwards (``True``) or from the innermost shell outwards (``False``). :param boomerang: Indicate whether the animation should have a boomerang effect, where it is symmetric in time. :param azimuth: Camera azimuthal angle in degrees (theta). If not specified, the current plotter's angles are used. :param elevation: Camera elevation angle in degrees (phi). If not specified, the current plotter's angles are used. :param hide_sliders: Indicate whether the sliders should be hidden before producing the video. :param add_shell_text: Indicate whether to show text at the bottom of the screen indicating the shell number. .. py:method:: hide_sliders() Hide the plotter's slider widgets. .. py:method:: show_sliders() Show the plotter's slider widgets. .. py:method:: hide_scalar_bars() Hide the scalar bars. .. py:method:: show_scalar_bars() Show the scalar bars. .. py:method:: show_axes() Show the spherical axes. .. py:method:: hide_axes() Hide the spherical axes. .. py:method:: export_screenshot(filename: str, transparent_background: bool = True, window_size: Optional[tuple[int, int]] = None, scale: Optional[int] = None, hide_sliders: bool = True, hide_scalar_bar: bool = False) Export a screenshot from the plotter. :param filename: Output destination for the screenshot, including file extension. Must be of type PNG, bitmap, JPEG or TIFF. :param transparent_background: Indicate whether the background should be transparent. :param window_size: Desired window size before exporting. :param scale: Factor by which to scale the window before exporting to increase resolution. :param hide_sliders: Indicate whether to hide sliders before exporting. If no sliders have been added to the plot, this option has no effect. :param hide_scalar_bar: Indicate whether to hide the scalar bar when exporting. The scalar bar will be made visible again after exporting. .. seealso:: :obj:`pyvista.Plotter.screenshot` Function wrapped by this function, which actually produces the screenshot. The current function borrows some parameters from this function. .. py:method:: export_graphic(filename: str, title: str, raster: bool = True, painter: bool = True, window_size: Optional[tuple[int, int]] = None, scale: Optional[int] = None, hide_sliders: bool = True, hide_scalar_bar: bool = False) Export a graphic from the plotter. :param filename: Output destination for the graphic, including file extension. Must be of type SVG, PDF, TEX, PS or EPS. :param title: Name of the graphics (see PyVista documentation). :param raster: Indicate whether to write the properties as a raster image (see PyVista documentation). :param painter: Indicate whether to perform a certain painting step (see PyVista documentation). :param window_size: Desired window size before exporting. :param scale: Factor by which to scale the window before exporting to increase resolution. :param hide_sliders: Indicate whether to hide sliders before exporting. If no sliders have been added to the plot, this option has no effect. :param hide_scalar_bar: Indicate whether to hide the scalar bar when exporting. The scalar bar will be made visible again after exporting. .. seealso:: :obj:`pyvista.Plotter.save_graphic` Function wrapped by this function, which actually produces the graphic. The current function borrows some parameters from this function. .. py:method:: set_view_plane(viewing_plane: ViewingPlanes) Set the plotter camera to a predefined viewing angle. .. py:function:: produce_1d_scalar_histogram(counts: pandas.Series | numpy.ndarray, bin_edges: numpy.ndarray, fill: bool = True, ax: Optional[matplotlib.pyplot.Axes] = None, log: bool = False, **kwargs) -> matplotlib.pyplot.Axes Produce a 1D scalar histogram. This function is mostly used to visualise the marginal magnitude histogram. :param counts: The counts in each bin. :param bin_edges: The edges of the bins used to compute the histogram. :param fill: Indicate whether to fill the histogram. If ``False`` then only an outline of the bars is drawn. :param ax: Optional axes on which to plot. If ``None``, then new axes are created. :param log: Indicate whether to use a logarithmic scale for the y-axis. :param \*\*kwargs: Keyword arguments for plotting the histogram. See :func:`matplotlib.axes.Axes.bar` and :class:`matplotlib.patches.Rectangle` for more details. :returns: :class:`matplotlib.axes.Axes` -- The axes containing the histogram plot. .. seealso:: :obj:`matplotlib.pyplot.bar` create a bar plot using provided heights. .. py:function:: produce_polar_histogram_plot(ax: matplotlib.projections.polar.PolarAxes, data: numpy.ndarray, bins: numpy.ndarray, zero_position: CardinalDirection = CardinalDirection.NORTH, rotation_direction: RotationDirection = RotationDirection.CLOCKWISE, plot_title: Optional[str] = None, label_axis: bool = True, axis_ticks: numpy.ndarray = np.arange(0, 360, 30), axis_ticks_unit: AngularUnits = AngularUnits.DEGREES, colour: str = 'C0', max_angle: Optional[float] = None, r_min: float = 0, r_max: Optional[float] = None) -> matplotlib.projections.polar.PolarAxes Produce a 1D polar histogram plot. Produce a 1D polar histogram using the specified data on provided axes. :param ax: Matplotlib :class:`matplotlib.projections.polar.PolarAxes` on which to plot the data. :param data: Histogram data to plot. This should have the same size as ``bins``. :param bins: Lower edge of each histogram bin. :param zero_position: Zero-position on the polar axes, expressed as a member of the enumerated class :class:`CardinalDirection`. :param rotation_direction: Rotation direction indicating how the bin values should increase from the zero-point specified in ``zero_position``, represented as a member of :class:`RotationDirection`. :param plot_title: Optional title of the plot. :param label_axis: Indicate whether the circumferential axis should be labelled. :param axis_ticks: Axis ticks for the histogram. Units specified in ``axis_ticks_unit``. :param axis_ticks_unit: :class:`AngularUnits` indicating what unit should be used for specifying the axis ticks. Default is :attr:`AngularUnits.DEGREES`. :param colour: Histogram bar colour. Must be a valid matplotlib colour [#f1]_. :param max_angle: Maximum angle to represent on the angular axis in **degrees**. Must be between 0 and 360°. If `None`, a complete circle is drawn. :param r_min: Minimum bound along the r axis. If `None`, then set automatically from the data. :param r_max: Maximum bound along the r axis. If `None`, then set automatically from the data. :returns: :class:`matplotlib.projections.polar.PolarAxes` -- The ``PolarAxes`` used for plotting. .. warning:: The axes provided **must** be created using ``projection="Polar"``. The `max_angle` parameter allows for a portion of the circular plot to be drawn. **Any values beyond this maximum will be truncated.** .. seealso:: :obj:`matplotlib.projections.polar.PolarAxes` Polar axes used for plotting the polar histogram. .. rubric:: References .. [#f1] https://matplotlib.org/stable/users/explain/colors/colors.html .. py:function:: produce_phi_theta_polar_histogram_plots(phi_data: pandas.DataFrame, theta_data: pandas.DataFrame, zero_position_2d: CardinalDirection = CardinalDirection.NORTH, rotation_direction: RotationDirection = RotationDirection.CLOCKWISE, use_degrees: bool = True, use_counts: bool = False, plot_title: Optional[str] = None, fig: Optional[matplotlib.pyplot.Figure] = None, r_phi_min: Optional[float] = 0, r_phi_max: Optional[float] = None, r_theta_min: Optional[float] = 0, r_theta_max: Optional[float] = None) -> matplotlib.pyplot.Figure Produce and show the 1D polar phi and theta histograms. This function takes in 2D binned histogram input and shows a 2-panel figure containing the theta and phi polar histograms. :param phi_data: Histogram data for the phi angle. :param theta_data: Histogram data for the theta angle. :param zero_position_2d: The :class:`CardinalDirection` where zero should be placed in the 1D polar histograms (default: North). :param rotation_direction: The :class:`RotationDirection` of increasing angles in the 1D polar histograms (default: clockwise). :param use_degrees: Indicate whether the values are in degrees. If ``True``, values are assumed to be in degrees. Otherwise, radians are assumed. :param use_counts: Indicate whether the bar heights should reflect the counts, as opposed to the frequencies. :param plot_title: Title of the overall plot (optional). :param fig: Figure on which to produce the plots. If `None`, a new figure is created. :param r_phi_min: Minimum r-axis value for the phi plot. If `None`, computed from the data. :param r_phi_max: Maximum r-axis value for the phi plot. If `None`, computed from the data. :param r_theta_min: Minimum r-axis value for the theta plot. If `None`, computed from the data. :param r_theta_max: Maximum r-axis value for the theta plot. If `None`, computed from the data. :returns: :class:`matplotlib.figure.Figure` -- The figure containing the polar histogram plots. .. seealso:: :obj:`produce_polar_histogram_plot` Create 1D polar histograms in isolation from 1D histogram data. .. py:function:: produce_labelled_3d_plot(ax: mpl_toolkits.mplot3d.axes3d.Axes3D, radius: float, limits_factor: float = 1.1, plot_title: Optional[str] = None, sphere_projection: SphereProjection = SphereProjection.ORTHOGRAPHIC, plot_phi_axis: bool = True, plot_theta_axis: bool = True, label_phi_axis: bool = True, label_theta_axis: bool = True, phi_label_positions: numpy.ndarray = np.arange(0, np.pi + 0.01, np.pi / 6), theta_label_positions: numpy.ndarray = np.arange(0, 2 * np.pi, np.pi / 6), phi_axis_colour: str = 'black', theta_axis_colour: str = 'black', hide_cartesian_axes: bool = True, hide_cartesian_axis_labels: bool = False, hide_cartesian_axis_ticks: bool = True, plot_colour_bar: bool = False, minimum_value: Optional[float] = None, maximum_value: Optional[float] = None, colour_map: str = 'viridis', colour_bar_kwargs: Optional[dict[str, Any]] = None, axis_label_factor: float = 1.4, axis_tick_factor: float = 1.6, norm: Optional[matplotlib.colors.Normalize] = None) -> mpl_toolkits.mplot3d.axes3d.Axes3D Modify a 3D Matplotlib plot to label it with spherical axes. Modify existing axes to add spherical phi and theta axes, as well as labels and a colour bar. :param ax: Axes to modify. These must be 3D axes. :param radius: Sphere radius in the 3D plot. This value is multiplied by the `limits_factor` to obtain the radius of the spherical axes. :param limits_factor: Factor used to add padding to the sphere, by default 1.1. The same factor is used along all axes, and is multiplied by the radius of the sphere to define the axis bounds. :param plot_title: Title of the plot produced (optional). :param sphere_projection: Projection used to plot the sphere, by default :attr:`SphereProjection.ORTHOGRAPHIC` :param plot_phi_axis: Indicate whether the phi axis should be plotted in 3D. :param plot_theta_axis: Indicate whether the theta axis should be plotted in 3D. :param label_phi_axis: Indicate whether to label the phi axis. :param label_theta_axis: Indicate whether to label the theta axis. :param phi_label_positions: Indicate angular positions for the labels for phi along its circular axis. :param theta_label_positions: Indicate angular positions for the labels for theta along its circular axis. :param phi_axis_colour: Colour for the phi axis. :param theta_axis_colour: Colour for the theta axis.. :param hide_cartesian_axes: Indicate whether to hide the Cartesian axes, by default True. :param hide_cartesian_axis_labels: Indicate whether to hide the Cartesian axis labels, by default False. This has no effect if `hide_cartesian_axes` is True. :param hide_cartesian_axis_ticks: Indicate whether to hide the Cartesian axis ticks, by default True. :param plot_colour_bar: Indicate whether to plot the colour bar, by default False. :param minimum_value: Minimum data value. Required if plotting the colour bar. :param maximum_value: Maximum data value. Required if plotting the colour bar. :param colour_map: Colour map for the colour bar. :param colour_bar_kwargs: Keyword arguments for the colour bar. :param norm: Normaliser to use for the colour bar (if applicable) :param axis_tick_factor: Multiplicative factor providing the distance from the origin to the plotted axes and axis tick labels, based on the sphere radius. :param axis_label_factor: Multiplicative factor providing the distance from the origin to the plotted axis labels, based on the sphere radius. :returns: :class:`mpl_toolkits.mplot3d.axes3d.Axes3D` -- The same axes as `ax`, with the new elements added. .. py:function:: produce_3d_triangle_sphere_plot(ax: mpl_toolkits.mplot3d.axes3d.Axes3D, sphere: vectorose.triangle_sphere.TriangleSphere, face_counts: pandas.Series, colour_map: str = 'viridis', sphere_alpha: float = 1.0, norm: Optional[matplotlib.pyplot.Normalize] = None, **kwargs: Optional[dict[str, Any]]) -> mpl_toolkits.mplot3d.axes3d.Axes3D Produce a 3D sphere plot based on a triangle mesh. Using the provided axes, plot a sphere with face colours corresponding to the provided values. This plot is generated using Matplotlib. :param ax: Axes on which to plot the sphere. :param sphere: Triangle sphere to plot. :param face_counts: Values assigned to each face in the `sphere`. :param colour_map: Colour map used to colour the sphere, by default "viridis". :param norm: Optional :class:`matplotlib.colors.Normalize` object to use to normalise the colours. :param sphere_alpha: Opacity of the sphere. :param \*\*kwargs: Keyword arguments for the plot labelling. See :func:`.produce_labelled_3d_plot` for options. :returns: :class:`mpl_toolkits.mplot3d.axes3d.Axes3D` -- The axes on which the provided sphere is plotted. .. warning:: The provided axes must have the projection set to 3D using ``projection="3d"``. The histogram data provided must occupy the entire sphere. No manipulations will be performed in this function to get the face colours to match the number of faces. .. seealso:: :obj:`vectorose.triangle_sphere.TriangleSphere` Produce a sphere and histogram labellings to pass to this function. :obj:`.produce_labelled_3d_plot` Label the axes of the 3D plot. :obj:`.produce_3d_tregenza_sphere_plot` Similar function for a Tregenza sphere. .. py:function:: produce_3d_tregenza_sphere_plot(ax: mpl_toolkits.mplot3d.axes3d.Axes3D, tregenza_sphere: vectorose.tregenza_sphere.TregenzaSphere, histogram_data: Optional[pandas.Series] = None, sphere_alpha: float = 1.0, colour_map: str = 'viridis', norm: Optional[matplotlib.pyplot.Normalize] = None, **kwargs) -> mpl_toolkits.mplot3d.axes3d.Axes3D Produce a 3D sphere plot based on a Tregenza sphere. Using the provided axes, plot a Tregenza sphere with face colours corresponding to the provided histogram values. This plot is generated using Matplotlib. :param ax: Axes on which to plot the sphere. :param tregenza_sphere: Tregenza sphere on which to plot the values. :param histogram_data: Histogram data to plot. The length of this list must correspond to the number of rings in the `tregenza_sphere` and the length of each entry must correspond to the respective patch count. :param sphere_alpha: Opacity of the sphere. :param colour_map: Colour map to use when plotting the sphere, by default "viridis". :param norm: Optional :class:`matplotlib.colors.Normalize` object to use to normalise the colours. :param \*\*kwargs: Keyword arguments for the plot labelling. See :func:`.produce_labelled_3d_plot` for options. :returns: :class:`mpl_toolkits.mplot3d.axes3d.Axes3D` -- The axes on which the provided sphere is plotted. .. warning:: The histogram data must have a size matching the provided Tregenza sphere. .. py:function:: construct_uv_sphere_vertices(phi_steps: int = 80, theta_steps: int = 160, radius: float = 1) -> numpy.ndarray Compute the vertices for a UV sphere with rectangular faces. Construct a UV sphere where each ring has the same number of faces. :param phi_steps: Number of faces along the phi axis. :param theta_steps: Number of faces along the theta axis, within a ring. :param radius: Sphere radius. :returns: :class:`numpy.ndarray` -- Array containing the Cartesian coordinates of the sphere vertices in a format to plot using :meth:`Axes3D.plot_surface`. This array will have shape ``(theta_steps + 1, phi_steps + 1, 3)`` where the last axis corresponds to the ``X, Y, Z`` components. .. warning:: This sphere should not be used to plot histograms. It is provided for visualisations that do not involve plotting data on the surface of the sphere. .. rubric:: Notes The coordinates computed using this function can easily be used to plot a sphere using :meth:`Axes3D.plot_surface`. To do so, the X, Y and Z coordinate sheets must be separated by indexing along the last axis. .. py:function:: construct_uv_sphere_mesh(phi_steps: int = 80, theta_steps: int = 160, radius: float = 1) -> pyvista.PolyData Construct a UV sphere mesh. :param phi_steps: Number of phi rings to construct. :param theta_steps: Number of theta bins in each ring. :param radius: Sphere radius. :returns: :class:`pyvista.PolyData` -- Mesh containing the UV sphere. .. py:function:: __update_sphere_viewing_angle(frame: int, sphere_axes: mpl_toolkits.mplot3d.axes3d.Axes3D, angle_increment: int) -> Iterable[mpl_toolkits.mplot3d.axes3d.Axes3D] Update the sphere viewing angle. Updates the sphere viewing angle to be the current angle, with the azimuth increased by an increment. :param frame: The number of the current frame in the animation (required to fit the animation signature, but unused here). :returns: :class:`Iterable` of :class:`mpl_toolkits.mplot3d.axes3d.Axes3D` -- An iterable containing a reference to the 3D sphere axes. .. py:function:: animate_sphere_plot(sphere_figure: matplotlib.figure.Figure, sphere_axes: mpl_toolkits.mplot3d.axes3d.Axes3D, rotation_direction: RotationDirection = RotationDirection.CLOCKWISE, angle_increment: int = 10, animation_delay: int = 250, reset_initial_orientation: bool = True) -> matplotlib.animation.FuncAnimation Animate the sphere plot. Create an animation of the sphere plot rotating about its central axis (i.e., the axis running from the sphere's north pole to its south pole). :param sphere_figure: The :class:`matplotlib.figure.Figure` containing the sphere plot. :param sphere_axes: The :class:`mpl_toolkits.mplot3d.axes3d.Axes3D` containing the sphere plot. These axes **must** be 3D axes. :param rotation_direction: Direction for the **sphere** to rotate. See :class:`RotationDirection` for more information. :param angle_increment: Increment of the angle in **degrees** for the rotation at each frame. This value should be positive. :param animation_delay: Time delay between frames in milliseconds. :param reset_initial_orientation: Indicate whether the sphere should be reset to its original orientation before recording the animation. This argument should be set to ``False`` to allow a custom starting position. :returns: :class:`matplotlib.animation.FuncAnimation` -- The matplotlib animation produced by the sphere rotation. .. warning:: We recommend to hide the polar axis ticks while performing the animation. Otherwise, the result may look odd. .. seealso:: :obj:`matplotlib.animation.FuncAnimation` The class that serves as the basis for the animations created here. :obj:`mpl_toolkits.mplot3d.axes3d.Axes3D.view_init` The method used to update the 3D viewing angle to produce the animations. .. py:function:: construct_confidence_cone(angular_radius: float, number_of_patches: int = 80, mean_orientation: Optional[numpy.ndarray] = None, two_sided_cone: bool = True, use_degrees: bool = False, **kwargs) -> List[mpl_toolkits.mplot3d.art3d.Poly3DCollection] Construct the patches for a confidence cone. Construct the triangular patches for a confidence cone with a specified angular radius, and optionally rotated to a specified mean direction. :param angular_radius: Angular radius for the confidence cone bounds (in radians, unless the parameter `use_degrees` is `True`). :param number_of_patches: Number of patches to construct. Increase for a better approximation to a cone. :param mean_orientation: Mean orientation to rotate the confidence cone, in cartesian coordinates. If `None`, then the cone is not rotated and remains vertically oriented. :param two_sided_cone: Indicate whether the cone should be two-sided. If `True`, two cones will be constructed, radiating from the centre. If `False`, then a single cone is created. :param use_degrees: Indicate whether the provided angular radius is in degrees. :param \*\*kwargs: Keyword arguments for the patch construction. See :class:`~mpl_toolkits.mplot3d.art3d.Poly3DCollection` for details. :returns: :class:`list` of :class:`mpl_toolkits.mplot3d.art3d.Poly3DCollection` -- List of :class:`~mpl_toolkits.mplot3d.art3d.Poly3DCollection` representing each patch of the confidence cone. These patches are triangular. .. py:function:: produce_3d_confidence_cone_plot(ax: mpl_toolkits.mplot3d.axes3d.Axes3D, confidence_cone_patches: List[mpl_toolkits.mplot3d.art3d.Poly3DCollection], sphere_vertices: numpy.ndarray, sphere_radius: float = 1, sphere_alpha: float = 0.5, sphere_colour: str = '#a8a8a8', **kwargs) -> mpl_toolkits.mplot3d.axes3d.Axes3D Produce a 3D confidence cone plot. Using the provided confidence cone patches and sphere vertices, create a plot containing the confidence cone inside a sphere. :param ax: Axes on which to plot. These must be 3D axes. :param confidence_cone_patches: Patches for the confidence cone. :param sphere_vertices: Vertices for the UV sphere. :param sphere_radius: Radius of the sphere. :param sphere_alpha: Sphere opacity level. :param sphere_colour: Colour of the sphere. :param \*\*kwargs: Arguments passed to :func:`produce_labelled_3d_plot` to alter the labelling of the 3D axes. :returns: :class:`mpl_toolkits.mplot3d.axes3d.Axes3D` -- Axes on which the confidence cone has been plotted. .. warning:: The provided axes must have been constructed using a 3D projection, by setting ``projection="3d"``. .. seealso:: :obj:`.construct_confidence_cone` Generate the confidence cone patches. :obj:`.construct_uv_sphere_vertices` Generate vertices for a quad-based sphere.