Jupyter notebooks¶
Chemiscope can be used as a widget in Jupyter notebooks, that should work in
both Jupyter classic and JupyterLab. The widget can be created in default
mode (showing both a structure and a map panel), or used to display only
structures or only properties.
Once created, it is possible to interact with the widget using a traitlet interface, modeled after Jupyter widgets.
Creating a chemiscope widget¶
- chemiscope.show(structures=None, *, properties=None, metadata=None, environments=None, shapes=None, settings=None, mode='default', warning_timeout=10000, cache_structures=True, frames=None, meta=None)¶
Show the dataset defined by the given
structuresandproperties(optionallymetadata,environmentsandshapesas well) using an embedded chemiscope visualizer inside a Jupyter notebook. These parameters have the same meaning as in thechemiscope.create_input()function.The
modekeyword also allows overriding the default two-panels visualization to show only a structure panel (mode = "structure") or the map panel (mode = "map"). These modes also make it possible to view a dataset for which properties (or structures) are not available. The widget displays warning messages, that disappear after the specifiedwarning_timeout(in ms). Set to a negative value to disable warnings, and to zero to make them persistent.cache_structuresis a flag determining whether to cache structure data on the Python side to reduce the JScript memory footprint.When inside a jupyter notebook, the returned object will create a new chemiscope visualizer displaying the dataset. The object exposes a
settingstraitlet, that allows to modify the visualization options (possibly even linking the parameters to another widget). Printing the value of thesettingsproperty is also a good way to see a full list of the available options.The returned object also have a
savefunction that can be used to save the dataset to a.jsonor.json.gzfile to load it in the main website later. The visualization options will be those used in the active widget, so this is also a good way to tweak the appearance of the visualization before saving it.import chemiscope from sklearn.decomposition import PCA import ase.io pca = PCA(n_components=3) structures = ase.io.read(...) properties = { "PCA": pca.fit_transform(some_data), } widget = chemiscope.show(structures, properties) # display the dataset in a chemiscope visualizer inside the notebook widget # ... # NB: due to how traitlet work, you should always set the value of # the `settings` property. Only the properties that are explicitly # indicated will be modified. widget.settings = {"map": {"symbol": "tag"}} widget.settings["map"]["symbol"] = "tag" # << does nothing! # Save the file for later use widget.save("dataset.json")
- chemiscope.show_input(path, *, settings=None, mode='default', warning_timeout=10000, cache_structures=True)¶
Loads and shows the chemiscope input in
path.If
pathends with.gz, the file is loaded as a gzip compressed JSON string. Ifpathis a file-like object, it is read as JSON input.- Parameters:
path (str | Path | file-like) – load the chemiscope input from this path or file-like object
settings (dict) – override the default settings in the input
mode (str) – widget mode, either
default,structureormap.warning_timeout (float) – timeout (in ms) for warnings. Set to a negative value to disable warnings, and to zero to make them persistent.
cache_structures (bool) – whether to cache structure data on the Python side to reduce the JScript memory footprint
import chemiscope widget = chemiscope.show_input("dataset.json") # or with open("dataset.json", "r") as f: widget = chemiscope.show_input(f)
Widget properties and methods¶
The widget object returned by chemiscope.show() provides traitlets to
interact with the visualization state programmatically. For more information
on using traitlets and widget events (like observe), please refer to
the ipywidgets documentation.
- settings¶
A dictionary containing the current visualization settings. This traitlet is synchronized between Python and the JavaScript frontend. You can update it to change visualization options (e.g. map ranges, structure representation).
By changing the
pinnedsetting, you can control the number of viewers shown in the grid, as well as which structures are displayed in each viewer.# Enable space filling representation for the active viewer widget.settings = {"structure": [{"spaceFilling": True}]} # Set up 4 viewers with the specified structures widget.settings = {"pinned": [0, 1, 12, 5]
- selected_ids¶
A dictionary describing the currently selected structure or environment. It contains a
structureindex and optionally anatomindex to indicate the active environment.# Select the structure with index 3 and the environment 8 widget.selected_ids = {"structure": 3, "atom": 8}
- active_viewer¶
An integer indicating the index of the currently active viewer in the grid (0-based).
Saving the dataset and settings as a standalone file¶
The “save” method allows exporting the current state of the widget
as a standalone JSON file that can be opened in the web app
(or loaded with chemiscope.show_input()).
- ChemiscopeWidgetBase.save(path)¶
Save the dataset displayed by this widget as JSON to the given
path. Ifpathends with.gz, the file is written as gzip compressed JSON string.- Parameters:
path (str) – where to save the dataset.
Exporting images¶
The chemiscope widget provides methods to capture snapshots of the map and structure panels programmatically. These methods are asynchronous, as they require communication with the browser’s JavaScript engine to render and capture the data.
There are two types of methods: save_* methods, which write the image data
directly to a file given the path, and get_* methods, which return the raw
image bytes (PNG formatted).
Note
These methods return asyncio.Future objects. Depending on the environment,
you may be able to await directly in a cell to wait for the
result. If await hangs in your environment, you can use
catch the get_* return value, and then in a separate cell get .result()
to access the actual return value.
Basic usage example:
# Cell 1: Create and display the widget
import chemiscope
widget = chemiscope.show(structures, properties)
widget
# Cell 2: Save a snapshot of the current map to a file
widget.save_map_image("current_map.png")
# Cell 3: Capture structure image data as raw PNG bytes
img_future = widget.get_structure_image()
# Display image
from IPython.display import Image
img_data = img_future.result()
display(Image(img_data))
Capturing sequences¶
You can also capture a sequence of structure snapshots (e.g., for a trajectory
animation). The indices parameter can be a list of structure indices or
a list of dictionaries specifying both structure and atom indices.
An optional settings parameter allows applying specific visualization
settings to each frame.
indices = [0, 10, 20]
paths = ["frame_0.png", "frame_10.png", "frame_20.png"]
# Capture and save a sequence of frames
widget.save_structure_sequence(indices, paths)
- ChemiscopeWidgetBase.save_map_image(path)¶
Save a snapshot of the map to a file.
This method starts a background task to save the image. You can
awaitit if you need to ensure the file is written before proceeding.widget.save_map_image("map.png")
- Parameters:
path (str) – Path where the image will be saved.
- Returns:
A Future that resolves when the file is written.
- ChemiscopeWidgetBase.save_structure_image(path)¶
Save a snapshot of the active structure viewer to a file.
This method starts a background task to save the image. You can
awaitit if you need to ensure the file is written before proceeding.widget.save_structure_image("structure.png")
- Parameters:
path (str) – Path where the image will be saved.
- Returns:
A Future that resolves when the file is written.
- ChemiscopeWidgetBase.get_map_image()¶
Request a snapshot of the map. Returns a Future that resolves to the image data (PNG formatted).
This method is asynchronous. In a Jupyter notebook, you should
awaitit to get the data.# Get raw image data data = await widget.get_map_image() # Display it from IPython.display import Image display(Image(data))
- Returns:
A Future that resolves to the image data as bytes.
- ChemiscopeWidgetBase.get_structure_image()¶
Request a snapshot of the active structure viewer. Returns a Future that resolves to the image data (PNG formatted).
This method is asynchronous. In a Jupyter notebook, you should
awaitit to get the data.data = await widget.get_structure_image()
- Returns:
A Future that resolves to the image data as bytes.
- ChemiscopeWidgetBase.save_structure_sequence(indices, paths, settings=None)¶
Save a sequence of structure snapshots to files.
This method acts as a wrapper around
get_structure_sequence()and writes the results to files.indices = [0, 10, 20] paths = ["frame_0.png", "frame_10.png", "frame_20.png"] await widget.save_structure_sequence(indices, paths)
- Parameters:
indices (list) – List of indices (int or dict) to render.
paths (list) – List of file paths where images will be saved. Must match length of
indices.settings (list) – Optional list of settings dicts to apply to each frame.
- Returns:
A Future that resolves when all files are written.
- ChemiscopeWidgetBase.get_structure_sequence(indices, settings=None)¶
Request a sequence of structure snapshots. Returns a Future that resolves to a list of image data (PNG formatted).
This allows rendering multiple frames efficiently without blocking the UI. The sequence is processed in the browser.
The
indiceslist can contain integers (structure index) or dictionaries specifyingstructureandatomindices (for environments).The
settingslist, if provided, must have the same length asindices. Each element is a dictionary of structure settings (e.g.{"spaceFilling": True}) to apply for that specific frame.indices = [0, 1, 2] settings = [{"spaceFilling": True}, {}, {"spaceFilling": False}] data_list = await widget.get_structure_sequence(indices, settings)
- Parameters:
indices (list) – List of indices (int or dict) to render.
settings (list) – Optional list of settings dicts to apply for each frame.
- Returns:
A Future that resolves to a list of image data bytes.
Dataset exploration¶
- chemiscope.explore(structures=None, featurizer=None, properties=None, environments=None, settings=None, mode='default', write_input=None, *, frames=None)¶
Automatically generate an interactive Chemiscope visualization of atomic structures.
This function creates a low-dimensional representation of the input
structuresand displays them using a Chemiscope widget. It supports automatic featurization with PETMADFeaturizer or a custom featurization function.The default
PETMADFeaturizercomputes PET-MAD features from the structures and projects them into the 3D MAD latent space.If available, all properties are extracted automatically from the structures.
If one does not specify a
featurizer(or sets it as aNone), only properties will be displayed on the map visualizer panel, as long as there are at least two of them.Overall, the visualization can include: properties extracted from the structures, additional user-provided properties, features from either the built-in PET-MAD featurizer, with dimensionality reduction, or a custom user-provided featurization functions.
- Parameters:
structures (list) – list of structures
featurizer – either string specifying a featurizer version (currently only ‘pet-mad-1.0’), a custom callable function, or None. Used to compute features and perform dimensionality reduction on the
structures. For automatic default option, usepet-mad-1.0. The callable should takestructuresas the first argument andenvironmentsas the second argument. The return value must be a features array of shape(n_structures, n_features)ifenvironmentsisNone, or(n_environments, n_features)otherwise.properties (dict) – optional. Additional properties to be included in the visualization. This dictionary can contain any other relevant data associated with the atomic structures. Properties can be extracted from structures with
extract_properties()or manually defined by the user.environments – optional. List of environments (described as
(structure id, center id, cutoff)) to include when extracting the atomic properties. Can be extracted from structures withall_atomic_environments()or manually defined.settings (dict) – optional dictionary of settings to use when displaying the data. Possible entries for the
settingsdictionary are documented in the chemiscope input file reference.mode (str) – optional. Visualization mode for the chemiscope widget. Can be one of “default”, “structure”, or “map”. The default mode is “default”.
device (str) – torch device to use for the calculation with the default
PETMADFeaturizer. If None, we will try the options in the model’ssupported_devicein order.batch_size (int) – optional. Number of structures processed in each batch with the default
PETMADFeaturizer.write_input (string) – optional. A path to save the chemiscope input file created by this function. Afterwards, the file can be loaded using
chemiscope.show_input()
- Returns:
a chemiscope widget for interactive visualization
To use this function, additional dependencies are required, specifically, pet_mad
- Returns:
a chemiscope widget for interactive visualization
To use this function, additional dependencies are required, specifically, pet-mad used for the default dimensionality reduction. They can be installed with the following command:
pip install chemiscope[explore]
Here is an example using this function with and without a featurizer function. The structures are obtained by reading the structures from a file that ase can read, and performing Kernel PCA using sklearn on a descriptor computed with SOAP using the dscribe library.
import chemiscope import ase.io import dscribe.descriptors import sklearn.decomposition # Read the structures from the dataset structures = ase.io.read("trajectory.xyz", ":") # 1) Basic usage with default featurizer (PET-MAD featurization + Sketch-Map) chemiscope.explore(structures, featurizer="pet-mad-1.0") # or featurizer = chemiscope.get_featurizer("pet-mad-1.0") chemiscope.explore(structures, featurizer=featurizer) # Define a function for dimensionality reduction def soap_kpca_featurize(structures, environments): if environments is not None: raise ValueError("'environments' are not supported by this featurizer") # Compute descriptors soap = dscribe.descriptors.SOAP( species=["C"], r_cut=4.5, n_max=8, l_max=6, periodic=True, ) descriptors = soap.create(structures) # Apply KPCA kpca = sklearn.decomposition.KernelPCA(n_components=2, gamma=0.05) # Return a 2D array of reduced features return kpca.fit_transform(descriptors) # 2) Example with a custom featurizer function chemiscope.explore(structures, featurizer=soap_kpca_featurize)
For more examples, see the related documentation.
- chemiscope.get_featurizer(name)¶
Get a featurizer by name for feature extraction. Currently available version is: “pet-mad-1.0”, which returns an instance of PETMADFeaturizer.
- Parameters:
name (str) – name of the featurizer. Must match one of the known versions. Currently available is “pet-mad-1.0”
Warning
This function requires additional dependencies. Install them using:
pip install chemiscope[explore]
- chemiscope.metatomic_featurizer(model, *, extensions_directory=None, check_consistency=None, device=None, length_unit='Angstrom', variant=None)¶
Create a featurizer function using a metatomic model to obtain the features from structures. The model must be able to create a
"features"output.- Parameters:
model – model to use for the calculation. It can be a file path, a Python instance of
metatomic.torch.AtomisticModel, or the output oftorch.jit.script()onmetatomic.torch.AtomisticModel.extensions_directory – a directory where model extensions are located
check_consistency – should we check the model for consistency when running, defaults to False.
device – a torch device to use for the calculation. If
None, the function will use the options in model’ssupported_deviceattribute.length_unit – Unit of length used in the structures.
variant – selects which feature output variant to use. By default, the main
"features"output is used. To choose another variant, provide its name (e.g.,"cos_sin"), which will select the corresponding"features/<variant>"output.
- Returns:
a function that takes a list of structures and returns the features.
To use this function, additional dependencies are required. They can be installed with the following command:
pip install chemiscope[explore]
Here is an example using a pre-trained metatomic model, stored as a
model.ptfile with the compiled extensions stored in theextensions/directory. The structures are obtained by reading structures from a file that ase can read.import chemiscope import ase.io # Read the structures from the dataset structures = ase.io.read("data/explore_c-gap-20u.xyz", ":") # Provide model file ("model.pt") to `metatensor_featurizer` featurizer = chemiscope.metatensor_featurizer( "model.pt", extensions_directory="extensions" ) chemiscope.explore(structures, featurizer=featurizer)
For more examples, see the related documentation.