Visualizing Clusters with Crystal-Toolkit#
Visualizing clusters can be quite helpful when creating or analysing a cluster expansion.
This can be done seamlessly by relying on Crystal-Toolkit. Simply install crystal-toolkit
and make sure to also install the crystaltoolkit-extension
and setup jupyter integration as detailed in the docs.
Then to visualize simply import crystal-toolkit
, and that’s it!
[1]:
from smol.io import load_work
import crystal_toolkit
Load a cluster expansion#
[2]:
file_path = 'data/basic_ce.mson'
expansion = load_work(file_path)['ClusterExpansion']
Visualize the primitive structure#
To visualize using crystal toolkit simply type the name of the object instance you want to see
[3]:
print(expansion.cluster_subspace.structure) # print out details
expansion.cluster_subspace.structure # visualization
Full Formula (Li0.5 Ni1 O2)
Reduced Formula: Li0.5Ni1O2
abc : 2.969848 2.969848 5.143928
angles: 73.221350 73.221347 60.000002
pbc : True True True
Sites (4)
# SP a b c
--- ---------------------- ---- ---- ----
0 Li+:0.500 0 0 0
1 Ni3+:0.500, Ni4+:0.500 0.5 0.5 0.5
2 O2- 0.75 0.75 0.75
3 O2- 0.25 0.25 0.25
If you see this text, the Crystal Toolkit Jupyter Lab
extension is not installed. You can install it by running
"pip install crystaltoolkit-extension"
from the same environment you run "jupyter lab".
This only works in Jupyter Lab 3.x or above.
Structure Summary
Lattice
abc : 2.969848 2.9698481608006304 5.143928079443783
angles : 73.22134967468278 73.22134665054797 60.00000177324646
volume : 37.04398870365559
A : 2.843413003724563 -0.0 0.8573211961418291
B : 1.5509524920968607 -2.532695099191652 1.046778248525726e-07
C : 2.843413003724563 -0.0 -4.2866068838581715
pbc : True True True
PeriodicSite: Li+:0.500 (0.0000, 0.0000, 0.0000) [0.0000, 0.0000, 0.0000]
PeriodicSite: Ni3+:0.500, Ni4+:0.500 (3.6189, -1.2663, -1.7146) [0.5000, 0.5000, 0.5000]
PeriodicSite: O2- (5.4283, -1.8995, -2.5720) [0.7500, 0.7500, 0.7500]
PeriodicSite: O2- (1.8094, -0.6332, -0.8573) [0.2500, 0.2500, 0.2500]
Visualize a pair cluster#
To visualize clusters in smol
simply look at the base_cluster
for a given orbit
[4]:
cluster = expansion.cluster_subspace.orbits_by_size[2][0].base_cluster
print(cluster)
cluster
Diameter : 2.9698
Charge : 4.0
Centroid : 4.652858 -0.633174 -2.571964 -> 0.750000 0.250000 0.750000
Sites (2)
------------------------------------------------------------------------------------------------------------
0 vacA0+:0.500, Li+:0.500 5.686826 0.000000 -3.429286 -> 1.000000 0.000000 1.000000
1 Ni3+:0.500, Ni4+:0.500 3.618889 -1.266348 -1.714643 -> 0.500000 0.500000 0.500000
If you see this text, the Crystal Toolkit Jupyter Lab
extension is not installed. You can install it by running
"pip install crystaltoolkit-extension"
from the same environment you run "jupyter lab".
This only works in Jupyter Lab 3.x or above.
Cluster
No. sites: 2 Diameter: 2.9698
Centroid: (4.6529, -0.6332, -2.5720) -> [0.7500, 0.2500, 0.7500]
Site: vacA0+:0.500, Li+:0.500 (5.6868, 0.0000, -3.4293) -> [1.0000, 0.0000, 1.0000]
Site: Ni3+:0.500, Ni4+:0.500 (3.6189, -1.2663, -1.7146) -> [0.5000, 0.5000, 0.5000]
Visualize a triplet cluster#
[5]:
cluster = expansion.cluster_subspace.orbits_by_size[3][0].base_cluster
print(cluster)
cluster
Diameter : 2.9698
Charge : 7.5
Centroid : 2.412593 -0.844232 -2.857738 -> 0.000000 0.333333 0.666667
Sites (3)
------------------------------------------------------------------------------------------------------------
0 vacA0+:0.500, Li+:0.500 2.843413 0.000000 -4.286607 -> -0.000000 0.000000 1.000000
1 Ni3+:0.500, Ni4+:0.500 0.775476 -1.266348 -2.571964 -> -0.500000 0.500000 0.500000
2 Ni3+:0.500, Ni4+:0.500 3.618889 -1.266348 -1.714643 -> 0.500000 0.500000 0.500000
If you see this text, the Crystal Toolkit Jupyter Lab
extension is not installed. You can install it by running
"pip install crystaltoolkit-extension"
from the same environment you run "jupyter lab".
This only works in Jupyter Lab 3.x or above.
Cluster
No. sites: 3 Diameter: 2.9698
Centroid: (2.4126, -0.8442, -2.8577) -> [0.0000, 0.3333, 0.6667]
Site: vacA0+:0.500, Li+:0.500 (2.8434, 0.0000, -4.2866) -> [-0.0000, 0.0000, 1.0000]
Site: Ni3+:0.500, Ni4+:0.500 (0.7755, -1.2663, -2.5720) -> [-0.5000, 0.5000, 0.5000]
Site: Ni3+:0.500, Ni4+:0.500 (3.6189, -1.2663, -1.7146) -> [0.5000, 0.5000, 0.5000]
Using a plotting package to visualize clusters#
We strongly recommend using Crystal Toolkit for the ease and very nice interactive visualizations. However, when unable to use Crystal Toolkit, any plotting library with 3D plotting capabilities can be used.
Here we give an example of how to visualize the triplet cluster above using Plotly
[6]:
import numpy as np
import plotly.graph_objs as go
from plotly.offline import iplot # for static plots
# First create a line scatter plot for the unit cell
# points for vertices of the unit cell
s = cluster.lattice.matrix.sum(axis=0)
x = [0, *cluster.lattice.matrix[:, 0], *(s[0] - cluster.lattice.matrix[:, 0]), s[0]]
y = [0, *cluster.lattice.matrix[:, 1], *(s[1] - cluster.lattice.matrix[:, 1]), s[1]]
z = [0, *cluster.lattice.matrix[:, 2], *(s[2] - cluster.lattice.matrix[:, 2]), s[2]]
# now create start/end points for the 12 edges of the unit cell
x_lines, y_lines, z_lines = [], [], []
pairs = [(0, 1), (0, 2), (0, 3),
(1, 5), (1, 6),
(2, 4), (2, 6),
(3, 4), (3, 5),
(4, 7), (5, 7), (6, 7)]
for p in pairs:
for i in range(2):
x_lines.append(x[p[i]])
y_lines.append(y[p[i]])
z_lines.append(z[p[i]])
x_lines.append(None)
y_lines.append(None)
z_lines.append(None)
# Create a scatter 3D trace for the unit cell
lattice_trace = go.Scatter3d(x=x_lines, y=y_lines, z=z_lines, mode='lines')
# Now create a scatter 3D trace for the points in the cluster
x, y, z = zip(*(cluster.frac_coords @ cluster.lattice.matrix))
site_trace = go.Scatter3d(x=x, y=y, z=z, mode='markers')
# Create a plotly figure and remove grid lines
fig = go.Figure(data=[lattice_trace, site_trace])
fig.update_scenes(xaxis_showgrid=False, yaxis_showgrid=False,zaxis_showgrid=False,
xaxis_showbackground=False, yaxis_showbackground=False,
zaxis_showbackground=False)
# offline plot (instead of fig.show())
iplot(fig)