ipyvasp 0.9.91__py2.py3-none-any.whl → 0.9.94__py2.py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- ipyvasp/__init__.py +1 -1
- ipyvasp/_enplots.py +41 -45
- ipyvasp/_lattice.py +13 -4
- ipyvasp/_version.py +1 -1
- ipyvasp/bsdos.py +1 -0
- ipyvasp/core/plot_toolkit.py +3 -2
- ipyvasp/lattice.py +4 -4
- ipyvasp/widgets.py +735 -732
- {ipyvasp-0.9.91.dist-info → ipyvasp-0.9.94.dist-info}/METADATA +6 -2
- ipyvasp-0.9.94.dist-info/RECORD +25 -0
- ipyvasp-0.9.91.dist-info/RECORD +0 -25
- {ipyvasp-0.9.91.dist-info → ipyvasp-0.9.94.dist-info}/LICENSE +0 -0
- {ipyvasp-0.9.91.dist-info → ipyvasp-0.9.94.dist-info}/WHEEL +0 -0
- {ipyvasp-0.9.91.dist-info → ipyvasp-0.9.94.dist-info}/entry_points.txt +0 -0
- {ipyvasp-0.9.91.dist-info → ipyvasp-0.9.94.dist-info}/top_level.txt +0 -0
ipyvasp/__init__.py
CHANGED
|
@@ -31,7 +31,7 @@ from .bsdos import *
|
|
|
31
31
|
from .potential import *
|
|
32
32
|
from .evals_dataframe import *
|
|
33
33
|
from .utils import *
|
|
34
|
-
from .widgets import Files, BandsWidget,
|
|
34
|
+
from .widgets import Files, BandsWidget, KPathWidget, summarize, load_results
|
|
35
35
|
from .core import plot_toolkit, spatial_toolkit
|
|
36
36
|
from .core.spatial_toolkit import to_basis, to_R3, get_TM, get_bz, rotation
|
|
37
37
|
from .core.plot_toolkit import (
|
ipyvasp/_enplots.py
CHANGED
|
@@ -716,8 +716,9 @@ def splot_dos_lines(
|
|
|
716
716
|
**legend_kws,
|
|
717
717
|
}
|
|
718
718
|
add_legend(ax, **kwargs) # Labels are picked from plot
|
|
719
|
-
|
|
720
|
-
|
|
719
|
+
|
|
720
|
+
elim = elim if elim is not None else []
|
|
721
|
+
kws = dict(ylim=elim) if vertical else dict(xlim=elim)
|
|
721
722
|
xlabel, ylabel = "Energy (eV)", "DOS"
|
|
722
723
|
if vertical:
|
|
723
724
|
xlabel, ylabel = ylabel, xlabel
|
|
@@ -754,7 +755,7 @@ def _format_rgb_data(
|
|
|
754
755
|
if data["pros"].shape[2] == 2:
|
|
755
756
|
data["norms"][:, :, 2] = np.nan # Avoid wrong info here
|
|
756
757
|
elif data["pros"].shape[2] == 1:
|
|
757
|
-
data["
|
|
758
|
+
data["norms"][:, :, 1:] = np.nan
|
|
758
759
|
|
|
759
760
|
lws = np.sum(rgb, axis=2) # Sum of all colors
|
|
760
761
|
lws = maxwidth * lws / (float(np.max(lws)) or 1) # Normalize to maxwidth
|
|
@@ -773,8 +774,7 @@ def _format_rgb_data(
|
|
|
773
774
|
indices = range(np.shape(data["evals"])[1])
|
|
774
775
|
|
|
775
776
|
# Now process data to make single data for faster plotting.
|
|
776
|
-
|
|
777
|
-
K, E, C, S, PT, OT, KT, ET = [], [], [], [], [], [], [], []
|
|
777
|
+
K, E, C, S, CDATA = [], [], [], [], []
|
|
778
778
|
for i, b in enumerate(indices):
|
|
779
779
|
K = [*K, *data["kpath"], np.nan]
|
|
780
780
|
E = [*E, *data["evals"][:, i], np.nan]
|
|
@@ -784,32 +784,26 @@ def _format_rgb_data(
|
|
|
784
784
|
"rgb(0,0,0)",
|
|
785
785
|
]
|
|
786
786
|
S = [*S, *data["widths"][:, i], data["widths"][-1, i]]
|
|
787
|
-
|
|
788
|
-
|
|
789
|
-
|
|
790
|
-
|
|
791
|
-
|
|
792
|
-
|
|
793
|
-
|
|
794
|
-
|
|
795
|
-
|
|
796
|
-
|
|
797
|
-
|
|
798
|
-
|
|
799
|
-
|
|
800
|
-
|
|
801
|
-
] # Add bands subscripts to labels.
|
|
802
|
-
|
|
803
|
-
T = [
|
|
804
|
-
f"</br>{p} </br></br>Band: {e} {o}</br>{k}"
|
|
805
|
-
for (p, e, o, k) in zip(PT, ET, OT, KT)
|
|
806
|
-
]
|
|
787
|
+
|
|
788
|
+
CDATA = [*CDATA , *[
|
|
789
|
+
{
|
|
790
|
+
"nk":j+1,
|
|
791
|
+
**{f"k{u}":v for u,v in zip("xyz",xyz)},
|
|
792
|
+
"nb":b+1,
|
|
793
|
+
"occ":occ,
|
|
794
|
+
**{c:"" if np.isnan(v) else v for c,v in zip("rgb",rgb)}
|
|
795
|
+
}
|
|
796
|
+
for (j, xyz), occ, rgb in zip(
|
|
797
|
+
enumerate(data["kpoints"]), data["occs"][:, i],data["norms"][:, i]
|
|
798
|
+
)
|
|
799
|
+
], {k:np.nan for k in ("nk","kx","ky","kz","nb","occ","r","g","b")}]
|
|
800
|
+
|
|
807
801
|
return {
|
|
808
802
|
"K": K,
|
|
809
803
|
"E": E,
|
|
810
804
|
"C": C,
|
|
811
805
|
"S": S,
|
|
812
|
-
"
|
|
806
|
+
"CDATA": CDATA,
|
|
813
807
|
"labels": labels,
|
|
814
808
|
} # K, energy, marker color, marker size, text, labels that get changed
|
|
815
809
|
|
|
@@ -830,10 +824,15 @@ def _fmt_labels(ticklabels):
|
|
|
830
824
|
]
|
|
831
825
|
return ticklabels
|
|
832
826
|
|
|
827
|
+
_hover_temp = { # keep order same
|
|
828
|
+
"xy":"(%{x}, %{y})",
|
|
829
|
+
"k": "<br>K<sub>%{customdata.nk}</sub>: %{customdata.kx:.3f} %{customdata.ky:.3f} %{customdata.kz:.3f}",
|
|
830
|
+
"b":"Band: %{customdata.nb}, Occ: %{customdata.occ:.4f}"
|
|
831
|
+
}
|
|
833
832
|
|
|
834
833
|
@gu._fmt_doc(_docs)
|
|
835
834
|
def iplot_bands(
|
|
836
|
-
K, E, fig=None, elim=None, kticks=None, interp=None, title=None, **kwargs
|
|
835
|
+
K, E, occs = None, fig=None, elim=None, kticks=None, interp=None, title=None, **kwargs
|
|
837
836
|
):
|
|
838
837
|
"""Plot band structure using plotly.
|
|
839
838
|
{params}\n {K}\n {E}
|
|
@@ -854,18 +853,15 @@ def iplot_bands(
|
|
|
854
853
|
data = _format_rgb_data(
|
|
855
854
|
K,
|
|
856
855
|
E,
|
|
857
|
-
[E],
|
|
856
|
+
[E], # don't let it fail if no projections
|
|
858
857
|
["X"],
|
|
859
858
|
interp,
|
|
860
|
-
E,
|
|
859
|
+
E if occs is None else occs,
|
|
861
860
|
np.array([K, K, K]).reshape((-1, 3)),
|
|
862
861
|
maxwidth=1,
|
|
863
862
|
indices=indices,
|
|
864
863
|
) # moking other arrays, we need only
|
|
865
|
-
K, E
|
|
866
|
-
T = [
|
|
867
|
-
"Band" + t.split("Band")[1].split("Occ")[0] for t in T
|
|
868
|
-
] # Just Band number here
|
|
864
|
+
K, E = data["K"], data["E"]
|
|
869
865
|
|
|
870
866
|
if fig is None:
|
|
871
867
|
fig = go.Figure()
|
|
@@ -873,10 +869,12 @@ def iplot_bands(
|
|
|
873
869
|
kwargs = {
|
|
874
870
|
"mode": "markers + lines",
|
|
875
871
|
"marker": dict(size=0.1),
|
|
872
|
+
"hovertemplate": "<br>".join(_hover_temp.values()),
|
|
873
|
+
"customdata": [{k:v for k,v in d.items() if not k in 'rgb'} for d in data["CDATA"]], # useless rgb data to skip
|
|
876
874
|
**kwargs,
|
|
877
875
|
} # marker so that it is selectable by box, otherwise it does not
|
|
878
|
-
fig.add_trace(go.Scatter(x=K, y=E,
|
|
879
|
-
|
|
876
|
+
fig.add_trace(go.Scatter(x=K, y=E, **kwargs))
|
|
877
|
+
|
|
880
878
|
fig.update_layout(
|
|
881
879
|
template="plotly_white",
|
|
882
880
|
title=(
|
|
@@ -932,14 +930,7 @@ def iplot_rgb_lines(
|
|
|
932
930
|
data = _format_rgb_data(
|
|
933
931
|
K, E, pros, labels, interp, occs, kpoints, maxwidth=maxwidth, indices=indices
|
|
934
932
|
)
|
|
935
|
-
K, E, C, S,
|
|
936
|
-
data["K"],
|
|
937
|
-
data["E"],
|
|
938
|
-
data["C"],
|
|
939
|
-
data["S"],
|
|
940
|
-
data["T"],
|
|
941
|
-
data["labels"],
|
|
942
|
-
)
|
|
933
|
+
K, E, C, S, labels = [data[key] for key in "K E C S labels".split()]
|
|
943
934
|
|
|
944
935
|
if fig is None:
|
|
945
936
|
fig = go.Figure()
|
|
@@ -948,13 +939,18 @@ def iplot_rgb_lines(
|
|
|
948
939
|
kwargs.pop("marker_size", None) # Provided by S
|
|
949
940
|
kwargs.update(
|
|
950
941
|
{
|
|
951
|
-
"hovertext": T,
|
|
952
942
|
"marker": {
|
|
953
943
|
"line_color": "rgba(0,0,0,0)",
|
|
954
944
|
**kwargs.get("marker", {}),
|
|
955
945
|
"color": C,
|
|
956
946
|
"size": S,
|
|
957
947
|
},
|
|
948
|
+
"hovertemplate": "<br>".join([_hover_temp["xy"],
|
|
949
|
+
"<br>Projection: [{}, {}, {}]".format(*labels), # clean labels instead of ''
|
|
950
|
+
"Value: [%{customdata.r}, %{customdata.g}, %{customdata.b}]",
|
|
951
|
+
_hover_temp["k"], _hover_temp["b"],
|
|
952
|
+
]),
|
|
953
|
+
"customdata": data["CDATA"], # need for selection and hover template
|
|
958
954
|
}
|
|
959
955
|
) # marker edge should be free
|
|
960
956
|
|
|
@@ -967,7 +963,7 @@ def iplot_rgb_lines(
|
|
|
967
963
|
+ ", ".join(labels)
|
|
968
964
|
+ "]", # Do not set autosize = False, need to be responsive in widgets boxes
|
|
969
965
|
margin=go.layout.Margin(l=60, r=50, b=40, t=75, pad=0),
|
|
970
|
-
yaxis=go.layout.YAxis(title_text="Energy (eV)",
|
|
966
|
+
yaxis=go.layout.YAxis(title_text="Energy (eV)",range=elim or [min(E), max(E)]),
|
|
971
967
|
xaxis=go.layout.XAxis(
|
|
972
968
|
ticktext=_fmt_labels(xticklabels),
|
|
973
969
|
tickvals=xticks,
|
ipyvasp/_lattice.py
CHANGED
|
@@ -232,7 +232,7 @@ def periodic_table(selection=None):
|
|
|
232
232
|
return ax
|
|
233
233
|
|
|
234
234
|
|
|
235
|
-
def write_poscar(poscar_data, outfile=None, selective_dynamics=None, overwrite=False, comment=""):
|
|
235
|
+
def write_poscar(poscar_data, outfile=None, selective_dynamics=None, overwrite=False, comment="", scale=None):
|
|
236
236
|
"""Writes POSCAR data to a file or returns string
|
|
237
237
|
|
|
238
238
|
Parameters
|
|
@@ -246,6 +246,8 @@ def write_poscar(poscar_data, outfile=None, selective_dynamics=None, overwrite=F
|
|
|
246
246
|
If file already exists, overwrite=True changes it.
|
|
247
247
|
comment: str
|
|
248
248
|
Add comment, previous comment will be there too.
|
|
249
|
+
scale: float
|
|
250
|
+
Scale factor for the basis vectors. Default is provided by loaded data.
|
|
249
251
|
|
|
250
252
|
|
|
251
253
|
.. note::
|
|
@@ -253,7 +255,14 @@ def write_poscar(poscar_data, outfile=None, selective_dynamics=None, overwrite=F
|
|
|
253
255
|
"""
|
|
254
256
|
_comment = poscar_data.metadata.comment + comment
|
|
255
257
|
out_str = f"{poscar_data.SYSTEM} # " + (_comment or "Created by ipyvasp")
|
|
256
|
-
|
|
258
|
+
|
|
259
|
+
if scale is None:
|
|
260
|
+
scale = poscar_data.metadata.scale
|
|
261
|
+
elif not isinstance(scale, (int, float)):
|
|
262
|
+
raise TypeError("scale must be a number or None.")
|
|
263
|
+
elif scale == 0:
|
|
264
|
+
raise ValueError("scale can not be zero.")
|
|
265
|
+
|
|
257
266
|
out_str += "\n {:<20.14f}\n".format(scale)
|
|
258
267
|
out_str += "\n".join(
|
|
259
268
|
["{:>22.16f}{:>22.16f}{:>22.16f}".format(*a) for a in poscar_data.basis / scale]
|
|
@@ -550,9 +559,9 @@ class InvokeMaterialsProject:
|
|
|
550
559
|
else:
|
|
551
560
|
print(self._cif)
|
|
552
561
|
|
|
553
|
-
def write_poscar(self, outfile=None, overwrite=False, comment=""):
|
|
562
|
+
def write_poscar(self, outfile=None, overwrite=False, comment="",scale=None):
|
|
554
563
|
"Use `ipyvasp.lattice.POSCAR.write` if you need extra options."
|
|
555
|
-
write_poscar(self.export_poscar(), outfile=outfile, overwrite=overwrite, comment=comment)
|
|
564
|
+
write_poscar(self.export_poscar(), outfile=outfile, overwrite=overwrite, comment=comment, scale=scale)
|
|
556
565
|
|
|
557
566
|
def export_poscar(self):
|
|
558
567
|
"Export poscar data form cif content."
|
ipyvasp/_version.py
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
__version__ = "0.9.
|
|
1
|
+
__version__ = "0.9.94"
|
ipyvasp/bsdos.py
CHANGED
ipyvasp/core/plot_toolkit.py
CHANGED
|
@@ -20,6 +20,7 @@ import PIL # For text image.
|
|
|
20
20
|
|
|
21
21
|
import plotly.graph_objects as go
|
|
22
22
|
from plotly.io._base_renderers import open_html_in_browser
|
|
23
|
+
from einteract import patched_plotly
|
|
23
24
|
|
|
24
25
|
from .spatial_toolkit import to_R3, rotation
|
|
25
26
|
from ..utils import _sig_kwargs
|
|
@@ -1011,7 +1012,7 @@ def iplot2html(fig, outfile=None, modebar=True):
|
|
|
1011
1012
|
def iplot2widget(fig, fig_widget=None, template=None):
|
|
1012
1013
|
"Converts plotly's figure to FigureWidget by copying attributes and data. If fig_widget is provided, it will update it. Adds template if provided. If fig is FigureWidget, it is just returned"
|
|
1013
1014
|
if isinstance(fig, go.FigureWidget):
|
|
1014
|
-
return fig
|
|
1015
|
+
return patched_plotly(fig) # add attributes selected and clicked
|
|
1015
1016
|
|
|
1016
1017
|
if not isinstance(fig, go.Figure):
|
|
1017
1018
|
raise ValueError("fig must be instance of plotly.graph_objects.Figure")
|
|
@@ -1035,7 +1036,7 @@ def iplot2widget(fig, fig_widget=None, template=None):
|
|
|
1035
1036
|
for data in fig.data:
|
|
1036
1037
|
fig_widget.add_trace(data)
|
|
1037
1038
|
|
|
1038
|
-
return fig_widget
|
|
1039
|
+
return patched_plotly(fig_widget) # add attributes selected and clicked
|
|
1039
1040
|
|
|
1040
1041
|
@_sig_kwargs(plt.imshow, ('ax','X'))
|
|
1041
1042
|
def image2plt(image_or_fname, ax = None, crop = None, **kwargs):
|
ipyvasp/lattice.py
CHANGED
|
@@ -342,7 +342,7 @@ class POSCAR:
|
|
|
342
342
|
[
|
|
343
343
|
f"{k}={v}"
|
|
344
344
|
for k, v in zip(
|
|
345
|
-
|
|
345
|
+
['a','b','c','alpha','beta','gamma'], (*self.data.norms.round(3), *self.data.angles.round(3))
|
|
346
346
|
)
|
|
347
347
|
]
|
|
348
348
|
)
|
|
@@ -436,10 +436,10 @@ class POSCAR:
|
|
|
436
436
|
return weas_viewer(self, **kwargs)
|
|
437
437
|
|
|
438
438
|
def view_kpath(self, height='400px'):
|
|
439
|
-
"Initialize a
|
|
440
|
-
from .widgets import
|
|
439
|
+
"Initialize a KPathWidget instance to view kpath for current POSCAR, and you can select others too."
|
|
440
|
+
from .widgets import KPathWidget
|
|
441
441
|
|
|
442
|
-
return
|
|
442
|
+
return KPathWidget([self.path,],height=height)
|
|
443
443
|
|
|
444
444
|
@_sub_doc(plat.iplot_lattice)
|
|
445
445
|
@_sig_kwargs(plat.iplot_lattice, ("poscar_data",))
|