1+ import io
2+ import sys
13from typing import Dict , List , Union
24
5+ from IPython .display import Image , display
36from mat3ra .made .material import Material
47from mat3ra .made .tools .analyze .interface import ZSLMatchHolder
58from mat3ra .made .tools .analyze .rdf import RadialDistributionFunction
69from mat3ra .utils .jupyterlite .plot import plot_distribution_function , scatter_plot_2d
10+ from matplotlib import pyplot as plt
711
812
913def plot_strain_vs_area (matches : List ["ZSLMatchHolder" ], settings : Dict [str , Union [str , int ]]) -> None :
@@ -60,8 +64,8 @@ def plot_twisted_interface_solutions(interfaces: List["Material"]) -> None:
6064
6165 x_values .append (angle )
6266 y_values .append (size )
63- hover_texts .append (f"Interface { i + 1 } <br>Angle: { angle :.2f} °<br>Atoms: { size } <br>" )
64- trace_names .append (f"Interface { i + 1 } " )
67+ hover_texts .append (f"Interface { i + 1 } <br>Angle: { angle :.2f} °<br>Atoms: { size } <br>" )
68+ trace_names .append (f"Interface { i + 1 } " )
6569
6670 plot_settings = {"x_title" : "Twist Angle (°)" , "y_title" : "Number of Atoms" , "title" : "Twisted Interface Solutions" }
6771
@@ -73,7 +77,20 @@ def plot_rdf(material: "Material", cutoff: float = 10.0, bin_size: float = 0.1)
7377 """
7478 Plot RDF for a material.
7579 """
80+ is_pyodide = sys .platform == "emscripten"
81+ if is_pyodide :
82+ # This is needed so that plt is adjusted before import to work in Pyodide environment
83+ plt .switch_backend ("Agg" )
84+
7685 rdf = RadialDistributionFunction .from_material (material , cutoff = cutoff , bin_size = bin_size )
7786 plot_distribution_function (
7887 rdf .bin_centers , rdf .rdf , xlabel = "Distance (Å)" , ylabel = "g(r)" , title = "Radial Distribution Function (RDF)"
7988 )
89+
90+ if is_pyodide :
91+ # Necessary to display the plot in Pyodide environment
92+ buf = io .BytesIO ()
93+ plt .savefig (buf , format = "png" )
94+ buf .seek (0 )
95+ display (Image (buf .read ()))
96+ plt .close ()
0 commit comments