.. DO NOT EDIT. .. THIS FILE WAS AUTOMATICALLY GENERATED BY SPHINX-GALLERY. .. TO MAKE CHANGES, EDIT THE SOURCE PYTHON FILE: .. "auto_examples/plotting/plot_cycle_representatives.py" .. LINE NUMBERS ARE GIVEN BELOW. .. only:: html .. note:: :class: sphx-glr-download-link-note :ref:`Go to the end ` to download the full example code. .. rst-class:: sphx-glr-example-title .. _sphx_glr_auto_examples_plotting_plot_cycle_representatives.py: .. _cycle_representative_strategies_gallery: Strategies for Plotting Cycle Representatives ============================================== This tutorial contains tips that we found helpful when plotting cycle representatives. **Generate x-y-z coordinates for non-Euclidean data** Sometimes data doesn't come with x-y-z coordinates. For example, it might be a graph or hypergraph. Check out the :ref:`vertex_embedding_gallery` gallery for strategies to generate this data. - :ref:`styling_3d_gallery` - use opaque instead of transparent colors **Multiple still frames (different angles, useful for papers and slide presentations)** If you're trying to convey a complex 3D structure to an audience, you might not have the option to use a video. In this case, consider using multiple still frames from different angles. - See :ref:`styling_3d_gallery` for examples on generating multiple subplots in Plotly. - Or for a simpler approach, just rotate the camera manually and take screenshots. **Opaque colors** Opaque colors can make the 3d structure of an object more apparent. - This approach works well with multiple still frames. If you're using multiple frames, then you don't need to see "through" objects as much. - Try varying the colors of your triangles, too, to help distinguish different parts of the object. **Wire frame** Even when plotting 2-dimensional homology classes, sometimes it's as good or better to plot a wire frame instead (meaning just the edges incident to the triangles): - saves computational resources (especially for large complexes) - can be easier to visualize Try toggling the triangles on and off in the plots below to see the difference. .. GENERATED FROM PYTHON SOURCE LINES 56-60 Example ----------------- Here's an example to illustrate some of these strategies. .. GENERATED FROM PYTHON SOURCE LINES 62-69 .. code-block:: Python from networkx import triangles import oat_python as oat import plotly.graph_objects as go import numpy as np .. GENERATED FROM PYTHON SOURCE LINES 70-71 Generate a point cloud with the Stanford dragon and a sphere. .. GENERATED FROM PYTHON SOURCE LINES 71-75 .. code-block:: Python points = oat.point_cloud.stanford_dragon() .. GENERATED FROM PYTHON SOURCE LINES 76-77 Compute the persistent homology of the Vietoris-Rips complex. .. GENERATED FROM PYTHON SOURCE LINES 77-108 .. code-block:: Python # compute the minimum enclosing radius; all homology vanishes above this filtration parameter enclosing = oat.dissimilarity.enclosing_radius_for_points(points) # construct a distance matrix where values over enclosing + 0.0000000001 are removed dissimilarity_matrix = oat.dissimilarity.sparse_matrix_for_points( points = points, max_dissimilarity = enclosing + 0.0000000001, # adding 0.0000000001 avoids problems due to numerical error ) # # format the input to the persistent homology solver # dissimilarity_matrix = oat.dissimilarity.sparse_matrix_for_points( # points = points, # max_dissimilarity = 0.3, # ) # build and factor the boundary matrix decomposition = oat.core.vietoris_rips.BoundaryMatrixDecomposition( dissimilarity_matrix = dissimilarity_matrix, max_homology_dimension = 1, support_fast_column_lookup = True, ) # extract the persistent homology dataframe, including cycle representatives and bounding chains persistent_homology_dataframe \ = decomposition.persistent_homology_dataframe( return_cycle_representatives = True, return_bounding_chains = True, ) .. GENERATED FROM PYTHON SOURCE LINES 109-110 Inspect the largest cycle representatives .. GENERATED FROM PYTHON SOURCE LINES 110-114 .. code-block:: Python persistent_homology_dataframe.nlargest(10, 'num_cycle_simplices') .. raw:: html
dimension interval_length birth_filtration birth_simplex death_filtration death_simplex cycle_representative num_cycle_simplices bounding_chain num_bounding_simplices
id
1091 1 0.011571 0.009357 (377, 971) 0.020929 (614, 863, 971) simplex filtration coefficient 0 (6... 75 simplex filtration coefficient 0... 115.0
1203 1 0.011774 0.011787 (72, 325) 0.023561 (349, 495, 919) simplex filtration coefficient 0 (84... 75 simplex filtration coefficient 0... 123.0
1081 1 0.007711 0.009091 (713, 938) 0.016803 (501, 777, 886) simplex filtration coefficient 0 (45... 66 simplex filtration coefficient 0... 128.0
1090 1 0.009315 0.009327 (836, 970) 0.018642 (135, 944, 977) simplex filtration coefficient 0 (13... 59 simplex filtration coefficient 0... 109.0
1092 1 0.008609 0.009376 (368, 675) 0.017985 (326, 663, 893) simplex filtration coefficient 0 (6... 58 simplex filtration coefficient 0 ... 78.0
1111 1 0.007128 0.009686 (29, 568) 0.016813 (29, 45, 88) simplex filtration coefficient 0 (61... 47 simplex filtration coefficient 0 ... 61.0
1264 1 0.009288 0.014191 (670, 726) 0.023479 (670, 828, 943) simplex filtration coefficient 0 (3... 47 simplex filtration coefficient 0 ... 53.0
1158 1 0.014104 0.010779 (620, 742) 0.024883 (97, 380, 849) simplex filtration coefficient 0 ... 46 simplex filtration coefficient 0 ... 65.0
1088 1 0.008282 0.009269 (230, 925) 0.017551 (186, 216, 774) simplex filtration coefficient 0 (9... 34 simplex filtration coefficient 0 ... 32.0
1214 1 0.010349 0.012231 (264, 495) 0.022580 (264, 394, 718) simplex filtration coefficient 0 (9... 31 simplex filtration coefficient 0 ... 39.0


.. GENERATED FROM PYTHON SOURCE LINES 115-117 The largest cycle representative lies in row 1331 of the persistent homology dataframe. Extract the list of triangles in its bounding chain. .. GENERATED FROM PYTHON SOURCE LINES 117-120 .. code-block:: Python triangles = persistent_homology_dataframe["bounding_chain"][1203]["simplex"].tolist() .. GENERATED FROM PYTHON SOURCE LINES 121-122 Plot the triangles .. GENERATED FROM PYTHON SOURCE LINES 122-130 .. code-block:: Python fig = oat.plot.fig_3d_for_simplices( simplices = triangles, points = points, ) fig.update_layout(template="plotly_dark", height=800) fig .. raw:: html


.. GENERATED FROM PYTHON SOURCE LINES 131-132 Color and shrink the vertices, to help differentiate portions of the object .. GENERATED FROM PYTHON SOURCE LINES 132-136 .. code-block:: Python fig.data[0].marker = dict(color = -points[:,2], colorscale="Peach", size=3) fig .. raw:: html


.. GENERATED FROM PYTHON SOURCE LINES 137-138 Make the triangles opaque, and color them by height. .. GENERATED FROM PYTHON SOURCE LINES 138-153 .. code-block:: Python fig = oat.plot.fig_3d_for_simplices( simplices = triangles, points = points, kwargs_points = dict(marker = dict( size=3, color=-points[:,2], colorscale="Peach")), kwargs_triangles = dict( intensity=[point[2] for point in points], intensitymode="vertex", colorscale="Peach", opacity=1.0, showscale=False, ) ) fig.update_layout(template="plotly_dark", height=800) fig .. raw:: html


.. GENERATED FROM PYTHON SOURCE LINES 154-155 Generate multiple views from different angles .. GENERATED FROM PYTHON SOURCE LINES 155-187 .. code-block:: Python from plotly.subplots import make_subplots # Create a new figure with 3 3D subplots subfig = make_subplots( rows=3, cols=1, specs=[[{'type': 'scene'}], [{'type': 'scene'}], [{'type': 'scene'}]], subplot_titles=["View 1", "View 2", "View 3"], vertical_spacing=0.05 # Adjust this value to control spacing ) # Add the same traces to each subplot for trace in fig.data: subfig.add_trace(trace, row=1, col=1) subfig.add_trace(trace, row=2, col=1) subfig.add_trace(trace, row=3, col=1) # Set different camera angles for each subplot subfig.update_layout( scene=dict( camera=dict(eye=dict(x=0.0, y=1.0, z=1.0))), scene2=dict(camera=dict(eye=dict(x=0.9, y=1.2, z=1.2))), scene3=dict(camera=dict(eye=dict(x=0.7, y=-1.2, z=1.0))), height=700, ) subfig.update_layout( # showlegend = False, height = 1800, width = None, template = "plotly_dark", ) subfig .. raw:: html


.. rst-class:: sphx-glr-timing **Total running time of the script:** (0 minutes 3.285 seconds) .. _sphx_glr_download_auto_examples_plotting_plot_cycle_representatives.py: .. only:: html .. container:: sphx-glr-footer sphx-glr-footer-example .. container:: sphx-glr-download sphx-glr-download-jupyter :download:`Download Jupyter notebook: plot_cycle_representatives.ipynb ` .. container:: sphx-glr-download sphx-glr-download-python :download:`Download Python source code: plot_cycle_representatives.py ` .. container:: sphx-glr-download sphx-glr-download-zip :download:`Download zipped: plot_cycle_representatives.zip ` .. only:: html .. rst-class:: sphx-glr-signature `Gallery generated by Sphinx-Gallery `_