Skip to content

Add plot_structure_2d() in new module ml_matrics/struct_vis.py #20

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 18 commits into from
Feb 28, 2022

Conversation

janosh
Copy link
Owner

@janosh janosh commented Feb 14, 2022

Adds ml_matrics/struct_vis.py with ase-inspired plot_structure_2d() but works natively with pymatgen Structures, matplotlib being the only other dependency.

Example

from pymatgen.ext.matproj import MPRester
from ml_matrics.struct_vis import plot_structure_2d

struct = MPRester().get_structure_by_material_id('mp-12712')
plot_structure_2d(struct)

mp-12712

Aims to resemble output of ase.visualize.plot.plot_atoms with minor improvements, less conversion hassle and handling of disordered structures.

pymatgen is unable to convert disordered structures via AseAtomsAdaptor().get_atoms(struct):

ValueError: ASE Atoms only supports ordered structures

which appears to be untrue. ASE does allow for disorder.

ASE Example

from pymatgen.ext.matproj import MPRester
from pymatgen.io.ase import AseAtomsAdaptor
from ase.visualize.plot import plot_atoms

struct = MPRester().get_structure_by_material_id('mp-12712')
atoms = AseAtomsAdaptor().get_atoms(struct)

plot_atoms(atoms)

ase-mp-12712

Disordered Example

import matplotlib.pyplot as plt
from pymatgen.transformations.standard_transformations import SubstitutionTransformation


struct = MPRester().get_structure_by_material_id("mp-19017")

disord_struct: Structure = SubstitutionTransformation(
    {"Fe": {"Fe": 0.75, "C": 0.25}}
).apply_transformation(struct)

plot_structure_2d(disord_struct, rotation="10x,10y,0z", atomic_radii=0.5)

mp-19017-disord

@janosh
Copy link
Owner Author

janosh commented Feb 14, 2022

@sgbaird @CompRhys Would be interested to hear your feedback if you encounter the need to get a quick 2d plot of a pymatgen structure and feel like giving this a try.

@sgbaird
Copy link
Contributor

sgbaird commented Feb 14, 2022

Great! Will give it a try

@janosh
Copy link
Owner Author

janosh commented Feb 14, 2022

Structure with new annotate_sites=True option:
struct-2d-mp-19017-disordered

Room for improvement: element labels aren't yet occluded by sites with higher z-index.

@janosh
Copy link
Owner Author

janosh commented Feb 19, 2022

Output seems suboptimal but maybe good enough for now across most of 20 random structures. I think the code can still be simplified quite a bit though so leaving WIP status.

structs = [
    (fname, Structure.from_file(fname))
    for fname in glob(f"{ROOT}/data/structures/*.yml")
]

fig, axs = plt.subplots(4, 5, figsize=(20, 20))

for (fname, struct), ax in zip(structs, axs.flat):
    ax = plot_structure_2d(struct, ax=ax)
    mp_id = os.path.basename(fname).split(".")[0]
    ax.set_title(f"{struct.formula}\n{mp_id}", fontsize=14)


fig.savefig(f"{ROOT}/assets/mp-structures-2d.svg", bbox_inches="tight")

mp-structures-2d

@CompRhys
Copy link
Collaborator

Maybe a key off to the side? So then it doesn't overlayer the labels?

Does it give different colours to charge assigned elements?

@janosh
Copy link
Owner Author

janosh commented Feb 19, 2022

Maybe a key off to the side? So then it doesn't overlayer the labels?

Could you be more specific?

Does it give different colours to charge assigned elements?

It doesn't. Do you think that's an important feature? I feel like there already aren't enough colors to differentiate elements clearly. Maybe better to include oxidation state in site labels?

@sgbaird
Copy link
Contributor

sgbaird commented Feb 19, 2022

@janosh if you decide to include it, I think as a site label might work. As a legend (e.g. blue: Ni, red: O) incorporating charge states is tough because of the color issue.

@janosh janosh changed the title [WIP] Implement 2d structure visualization Add ml_matrics/struct_vis.py with plot_structure_2d() for 2d structure visualization Feb 28, 2022
@janosh janosh added the enhancement Improvement to existing features/functionality label Feb 28, 2022
@janosh janosh changed the title Add ml_matrics/struct_vis.py with plot_structure_2d() for 2d structure visualization Add plot_structure_2d() in new module ml_matrics/struct_vis.py Feb 28, 2022
@janosh janosh merged commit 32ed956 into main Feb 28, 2022
@janosh janosh deleted the struct-vis-2d branch February 28, 2022 12:28
@janosh janosh added the structure Structure viz related label Nov 9, 2023
janosh added a commit that referenced this pull request Mar 28, 2025
* add ml_matrics/struct_vis.py with ase-inspired plot_structure_2d()

* fix test_get_crystal_sys_invalid()

* plot_structure_2d() add annotate_sites: bool = True

* add example structure plots to readme

* fix GH workflow svgo compression

* rename annotate_sites kwarg to site_labels, can be dict or list for custom labels

* fix test_plot_structure_2d()

* add plot_structure_2d() example with 20 random MP structures

* plot_structure_2d() drop kwargs offset, bbox, maxwidth, simplifies function, add label_kwargs

* assert matplotlib compare_images() passes in test_plot_structure_2d()

* try fix compare_images() by setting explicit plt figsize

* move save_fixture() to new tests/_helpers.py along with stuff in tests/__init__.py

* add convenience root import for plot_structure_2d() + comment crediting ASE

* readme display ![mp-structures-2d] full-width
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
enhancement Improvement to existing features/functionality structure Structure viz related
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants