ipyvasp 0.8.6__py2.py3-none-any.whl → 0.8.7__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/_lattice.py CHANGED
@@ -15,7 +15,7 @@ from matplotlib.collections import LineCollection
15
15
  from mpl_toolkits.mplot3d.art3d import Poly3DCollection, Line3DCollection
16
16
  import matplotlib.colors as mplc
17
17
 
18
- from ipywidgets import interactive
18
+ from ipywidgets import interactive, IntSlider
19
19
 
20
20
  # Inside packages import
21
21
  from .core import plot_toolkit as ptk
@@ -1635,13 +1635,13 @@ def filter_sites(poscar_data, func, tol = 0.01):
1635
1635
  pos = data['positions'][indices]
1636
1636
  qos = data['positions'][others] # need edge items to include
1637
1637
 
1638
- if qos.shape:
1638
+ if qos.size:
1639
1639
  qos = np.concatenate([[[i] for i in others], qos], axis=1) # need to keep index
1640
1640
  qos = np.array([qos + [0, *p] for p in product([-1,0,1],[-1,0,1],[-1,0,1])]).reshape((-1,4)) # all possible translations
1641
1641
  qos = qos[(qos[:,1:] < 1 + tol).all(axis=1) & (qos[:,1:] > -tol).all(axis=1)]# only in cell range
1642
1642
  qos = qos[[func(*q) for q in qos]] # masked only those are true
1643
1643
 
1644
- if qos.shape:
1644
+ if qos.size:
1645
1645
  pos = np.concatenate([pos, qos[:,1:]],axis=0)
1646
1646
 
1647
1647
  all_pos.append(pos)
@@ -1681,10 +1681,10 @@ def iplot_lattice(
1681
1681
 
1682
1682
  Parameters
1683
1683
  ----------
1684
- sizes : float or tuple
1685
- Size of sites. Either one int/float or list equal to type of ions.
1686
- colors : tuple
1687
- Sequence of colors for each type. Automatically generated if not provided.
1684
+ sizes : float or dict of type -> float
1685
+ Size of sites. Either one int/float or a mapping like {'Ga': 2, ...}.
1686
+ colors : color or dict of type -> color
1687
+ Mapping of colors like {'Ga': 'red, ...} or a single color. Automatically generated color for missing types.
1688
1688
  bond_length : float or dict
1689
1689
  Length of bond in Angstrom. Auto calculated if not provides. Can be a dict like {'Fe-O':3.2,...} to specify bond length between specific types.
1690
1690
  bond_kws : dict
@@ -1717,17 +1717,9 @@ def iplot_lattice(
1717
1717
  fig = go.Figure()
1718
1718
 
1719
1719
  uelems = poscar_data.types.to_dict()
1720
- if not isinstance(sizes, (list, tuple, np.ndarray)):
1721
- sizes = [sizes for elem in uelems.keys()]
1722
-
1723
- if colors and len(colors) != len(uelems.keys()):
1724
- print(
1725
- "Warning: Number of colors does not match number of atom types. Using default colors."
1726
- )
1727
-
1728
- if (colors is None) or len(colors) != len(uelems.keys()):
1729
- colors = [_atom_colors[elem] for elem in uelems.keys()]
1730
- colors = ["rgb({},{},{})".format(*[int(_c * 255) for _c in c]) for c in colors]
1720
+ _fcs = _fix_color_size(uelems, colors, sizes, 10, backend = 'plotly')
1721
+ sizes = [v['size'] for v in _fcs.values()]
1722
+ colors = [v['color'] for v in _fcs.values()]
1731
1723
 
1732
1724
  _colors = np.array([colors[i] for i, vs in enumerate(uelems.values()) for v in vs],dtype=object) # could be mixed color types
1733
1725
 
@@ -1854,6 +1846,33 @@ def _validate_label_func(fmt_label, parameter):
1854
1846
  elif not isinstance(test_out, str):
1855
1847
  raise ValueError("fmt_label must return a string or a list/tuple of length 2.")
1856
1848
 
1849
+ def _fix_color_size(types, colors, sizes, default_size, backend=None):
1850
+ cs = {key: {'color': _atom_colors.get(key, 'blue'), 'size': default_size} for key in types}
1851
+ for k in cs:
1852
+ if len(cs[k]['color']) == 3: # otherwise its blue
1853
+ if backend == 'plotly':
1854
+ cs[k]['color'] = "rgb({},{},{})".format(*[int(255*c) for c in cs[k]['color']])
1855
+ elif backend == 'ngl':
1856
+ cs[k]['color'] = mplc.to_hex(cs[k]['color'])
1857
+
1858
+ if isinstance(sizes,(int,float,np.integer)):
1859
+ for k in cs:
1860
+ cs[k]['size'] = sizes
1861
+ elif isinstance(sizes, dict):
1862
+ for k,v in sizes.items():
1863
+ cs[k]['size'] = v
1864
+ else:
1865
+ raise TypeError("sizes should be a single int/float or dict as {'Ga':10,'As':15,...}")
1866
+
1867
+ if isinstance(colors,dict):
1868
+ for k,v in colors.items():
1869
+ cs[k]['color'] = v
1870
+ elif colors is not None and isinstance(colors,(str,list,tuple,np.ndarray)):
1871
+ for k in cs:
1872
+ cs[k]['color'] = colors
1873
+ else:
1874
+ raise TypeError("colors should be a single valid color or dict as {'Ga':'red','As':'blue',...}")
1875
+ return cs
1857
1876
 
1858
1877
  # Cell
1859
1878
  def splot_lattice(
@@ -1880,10 +1899,10 @@ def splot_lattice(
1880
1899
  ----------
1881
1900
  plane : str
1882
1901
  Plane to plot. Either 'xy','xz','yz' or None for 3D plot.
1883
- sizes : float or tuple
1884
- Size of sites. Either one int/float or list equal to type of ions.
1885
- colors : tuple
1886
- Sequence of colors for each ion type. If None, automatically generated.
1902
+ sizes : float or dict of type -> float
1903
+ Size of sites. Either one int/float or a mapping like {'Ga': 2, ...}.
1904
+ colors : color or dict of type -> color
1905
+ Mapping of colors like {'Ga': 'red, ...} or a single color. Automatically generated color for missing types.
1887
1906
  bond_length : float or dict
1888
1907
  Length of bond in Angstrom. Auto calculated if not provides. Can be a dict like {'Fe-O':3.2,...} to specify bond length between specific types.
1889
1908
  alpha : float
@@ -1941,23 +1960,10 @@ def splot_lattice(
1941
1960
  print(f"Warning: Parameters {list(kwargs.keys())} are not used when `plot_cell = False`.")
1942
1961
 
1943
1962
  uelems = poscar_data.types.to_dict()
1944
- if not isinstance(sizes, (list, tuple, np.ndarray)):
1945
- if not isinstance(sizes, (int, float, np.integer)):
1946
- raise ValueError("sizes must be a number or a list/tuple of numbers.")
1947
- sizes = [sizes for _ in uelems]
1948
-
1949
- if len(sizes) != len(uelems):
1950
- raise ValueError(
1951
- f"Length of `sizes` must be equal to number of elements in POSCAR. Got {len(sizes)} sizes for {len(uelems)} elements."
1952
- )
1953
-
1954
- if colors and len(colors) != len(uelems.keys()):
1955
- print(
1956
- "Warning: Number of colors does not match number of atom types. Using default colors."
1957
- )
1958
1963
 
1959
- if (colors is None) or len(colors) != len(uelems.keys()):
1960
- colors = [_atom_colors[elem] for elem in uelems.keys()]
1964
+ _fcs = _fix_color_size(uelems, colors, sizes, 50)
1965
+ sizes = [v['size'] for v in _fcs.values()]
1966
+ colors = [v['color'] for v in _fcs.values()]
1961
1967
 
1962
1968
  # Before doing other stuff, create something for legend.
1963
1969
  if showlegend:
@@ -2691,8 +2697,12 @@ def deform_poscar(poscar_data, deformation):
2691
2697
  def view_poscar(poscar_data, **kwargs):
2692
2698
  "View a POSCAR in a jupyter notebook. kwargs are passed to splot_lattice. After setting a view, you can do view.f(**view.kwargs) to get same plot in a cell."
2693
2699
 
2694
- def view(elev=30, azim=30, roll=0):
2700
+ def view(elev, azim, roll):
2695
2701
  ax = splot_lattice(poscar_data, **kwargs)
2696
2702
  ax.view_init(elev=elev, azim=azim, roll=roll)
2703
+
2704
+ elev = IntSlider(description='elev', min=0,max=180,value=30, continuous_update=False)
2705
+ azim = IntSlider(description='azim', min=0,max=360,value=30, continuous_update=False)
2706
+ roll = IntSlider(description='roll', min=0,max=360,value=0, continuous_update=False)
2697
2707
 
2698
- return interactive(view, elev=(0, 180), azim=(0, 360), roll=(0, 360))
2708
+ return interactive(view, elev=elev, azim=azim, roll=roll)
ipyvasp/_version.py CHANGED
@@ -1 +1 @@
1
- __version__ = "0.8.6"
1
+ __version__ = "0.8.7"
ipyvasp/lattice.py CHANGED
@@ -75,7 +75,7 @@ def download_structure(
75
75
  def ngl_viewer(
76
76
  poscar,
77
77
  colors=None,
78
- sizes=None,
78
+ sizes=0.5,
79
79
  plot_cell=True,
80
80
  linewidth=0.05,
81
81
  color=[0, 0, 0.2],
@@ -91,13 +91,12 @@ def ngl_viewer(
91
91
  Parameters
92
92
  ----------
93
93
  poscar : ipyvasp.POSCAR
94
- colors : list or str
95
- List of colors for each atom type. If str, use sames colors for all.
94
+ sizes : float or dict of type -> float
95
+ Size of sites. Either one int/float or a mapping like {'Ga': 2, ...}.
96
+ colors : color or sheme name or dict of type -> color
97
+ Mapping of colors like {'Ga': 'red, ...} or a single color. Automatically generated color for missing types.
96
98
  If `colors = 'element'`, then element colors from `nglview` will be used.
97
99
  You can use `nglview.color.COLOR_SCHEME` to see available color schemes to use.
98
- If colors is None, then default colors from ipyvasp will be used that are same in `[i,s]plot_lattice`.
99
- sizes : list
100
- List of sizes for each atom type.
101
100
  plot_cell : bool
102
101
  Plot unit cell. Default True.
103
102
  linewidth : float
@@ -139,26 +138,10 @@ def ngl_viewer(
139
138
  data=plat._fix_sites(poscar.data, eqv_sites=True if plot_cell else False, origin=origin)
140
139
  )
141
140
 
142
- _types = list(poscar.data.types.keys())
143
- _sizes = [0.5 for _ in _types]
144
- _colors = [mcolors.to_hex(plat._atom_colors[e]) for e in _types]
145
-
146
- if sizes:
147
- if len(sizes) != len(_types):
148
- raise ValueError(
149
- "sizes must have the same length as the number of atom types."
150
- )
151
- _sizes = sizes
152
-
153
- if colors:
154
- if isinstance(colors, str):
155
- _colors = [colors for _ in _types] # All same color, may be 'element'
156
- else:
157
- if len(colors) != len(_types):
158
- raise ValueError(
159
- "colors must have the same length as the number of atom types."
160
- )
161
- _colors = [mcolors.to_hex(c) for c in colors]
141
+ _types = poscar.data.types.to_dict()
142
+ _fcs = plat._fix_color_size(_types,colors,sizes,0.5, backend='ngl')
143
+ _sizes = [v['size'] for v in _fcs.values()]
144
+ _colors = [v['color'] for v in _fcs.values()]
162
145
 
163
146
  view = nv.NGLWidget(
164
147
  nv.ASEStructure(poscar.to_ase()),
@@ -199,7 +182,7 @@ def ngl_viewer(
199
182
 
200
183
 
201
184
  def weas_viewer(poscar,
202
- sizes=None,
185
+ sizes=1,
203
186
  colors=None,
204
187
  bond_length=None,
205
188
  model_style = 1,
@@ -207,9 +190,11 @@ def weas_viewer(poscar,
207
190
  origin = (0,0,0)
208
191
  ):
209
192
  """
210
- colors : list or str
211
- List of colors for each atom type. If str, use 'VESTA','JMOL','CPK'.
212
- By default, ipyvasp colors are used.
193
+ sizes : float or dict of type -> float
194
+ Size of sites. Either one int/float or a mapping like {'Ga': 2, ...}.
195
+ colors : color, color scheme or dict of type -> color
196
+ Mapping of colors like {'Ga': 'red, ...} or a single color. Automatically generated color for missing types.
197
+ You can use color schemes as 'VESTA','JMOL','CPK'.
213
198
  sizes : list
214
199
  List of sizes for each atom type.
215
200
  model_type: int
@@ -236,8 +221,7 @@ def weas_viewer(poscar,
236
221
  w = WeasWidget(from_ase=poscar.to_ase())
237
222
  w.avr.show_bonded_atoms = False if plot_cell else True # plot_cell fix atoms itself
238
223
  w.avr.model_style = model_style
239
- w.avr.show_cell = plot_cell
240
-
224
+ w.avr.show_cell = plot_cell
241
225
 
242
226
  if bond_length:
243
227
  if isinstance(bond_length,(int,float)):
@@ -247,40 +231,30 @@ def weas_viewer(poscar,
247
231
  elif isinstance(bond_length, dict):
248
232
  for key, value in bond_length.items():
249
233
  w.avr.bond.settings[key].update({'max': value})
250
-
251
- if sizes is not None:
252
- if not isinstance(sizes, (list,tuple)) or len(sizes) != len(poscar.data.types):
253
- raise ValueError(f"sizes should be list/tuple of same sizes as atom types = {len(poscar.data.types)}.")
254
- for key, value in zip(poscar.data.types,sizes):
255
- w.avr.species.settings[key].update({"radius": value})
256
234
 
257
- if colors is None:
258
- colors = [plat._atom_colors[key] for key in poscar.data.types]
259
-
260
- if isinstance(colors, str):
261
- if not colors in ['VESTA','JMOL','CPK']:
262
- raise ValueError("colors should be one of ['VESTA','JMOL','CPK'] if given as string!")
263
-
264
- w.avr.color_type = colors
235
+ _fcs = plat._fix_color_size(poscar.data.types.to_dict(), colors, sizes, 1)
265
236
 
266
- if not isinstance(colors, str):
267
- if not isinstance(colors, (list,tuple)) or len(colors) != len(poscar.data.types):
268
- raise ValueError(f"colors should be list/tuple of same sizes as atom types = {len(poscar.data.types)}.")
237
+ for key, value in _fcs.items():
238
+ w.avr.species.settings[key].update({"radius": value["size"]})
269
239
 
270
- colors = {key: value for key, value in zip(poscar.data.types,colors)}
240
+ if isinstance(colors, str) and colors in ['VESTA','JMOL','CPK']:
241
+ w.avr.color_type = colors
242
+ else:
243
+ colors = {key: value["color"] for key, value in _fcs.items()}
271
244
  for key,value in colors.items():
272
245
  w.avr.species.settings[key].update({"color": value})
273
246
  for (k1,c1), (k2,c2) in permutations(colors.items(),2):
274
247
  with suppress(KeyError):
275
248
  w.avr.bond.settings[f'{k1}-{k2}'].update({'color1':c1,'color2':c2})
276
-
249
+
277
250
  return w
278
251
 
279
252
 
280
253
  class POSCAR:
281
254
  _cb_instance = {} # Loads last clipboard data if not changed
282
255
  _mp_instance = {} # Loads last mp data if not changed
283
- _update_kws = {} # kwargs to pass to auto update figurewidget
256
+ _plotly_kws = {} # kwargs to pass to auto update figurewidget
257
+ _weas_kws = {}
284
258
 
285
259
  def __init__(self, path=None, content=None, data=None):
286
260
  """
@@ -370,6 +344,7 @@ class POSCAR:
370
344
  @_sub_doc(weas_viewer)
371
345
  @_sig_kwargs(weas_viewer, ("poscar",))
372
346
  def view_weas(self, **kwargs):
347
+ self.__class__._weas_kws = kwargs # attach to class, not self
373
348
  return weas_viewer(self, **kwargs)
374
349
 
375
350
 
@@ -381,17 +356,13 @@ class POSCAR:
381
356
 
382
357
  @_sub_doc(plat.iplot_lattice)
383
358
  @_sig_kwargs(plat.iplot_lattice, ("poscar_data",))
384
- def view_widget(self, **kwargs):
385
- self.__class__._update_kws = kwargs # attach to class, not self
359
+ def view_plotly(self, **kwargs):
360
+ self.__class__._plotly_kws = kwargs # attach to class, not self
386
361
  return iplot2widget(self.iplot_lattice(**kwargs))
387
362
 
388
- @_sig_kwargs(plat.iplot_lattice, ("poscar_data",))
389
- def update_widget(self, handle, **kwargs):
390
- """Update widget (if shown in notebook) after some operation on POSCAR with `handle` returned by `view_widget`
391
- kwargs are passed to `self.iplot_lattice` method.
392
- """
393
- kwargs = {**self.__class__._update_kws, **kwargs}
394
- iplot2widget(self.iplot_lattice(**kwargs), fig_widget=handle)
363
+ def update_plotly(self, handle):
364
+ "Update plotly widget (already shown in notebook) after some operation on POSCAR with `handle` returned by `view_plotly`."
365
+ iplot2widget(self.iplot_lattice(**self._plotly_kws), fig_widget=handle)
395
366
 
396
367
  @classmethod
397
368
  def from_file(cls, path):
@@ -535,11 +506,9 @@ class POSCAR:
535
506
 
536
507
 
537
508
  def update_weas(self, handle):
538
- """Send result of any operation to view on opened weas widget handle with default parameters becuase any operations
539
- can be incompatible with presious state of POSCAR. VESTA color scheme is used here.
509
+ """Send result of any operation to view on opened weas widget handle.
540
510
  Useful in Jupyterlab side panel to look operations results on POSCAR."""
541
- handle.from_ase(self.to_ase())
542
- handle.avr.color_type = 'VESTA'
511
+ handle.children = weas_viewer(self, **self._weas_kws).children # does not work properly otherwise
543
512
 
544
513
  @property
545
514
  def data(self):
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: ipyvasp
3
- Version: 0.8.6
3
+ Version: 0.8.7
4
4
  Summary: A processing tool for VASP DFT input/output processing in Jupyter Notebook.
5
5
  Home-page: https://github.com/massgh/ipyvasp
6
6
  Author: Abdul Saboor
@@ -1,12 +1,12 @@
1
1
  ipyvasp/__init__.py,sha256=7o41i5eYlNKg1Hsv0DLNFZ81GilxB02IXAJN-QiJQi0,1420
2
2
  ipyvasp/__main__.py,sha256=eJV1TZSiT8mC_VqAeksNnBI2I8mKMiPkEIlwikbtOjI,216
3
3
  ipyvasp/_enplots.py,sha256=D38paN8zqZgluNAwmCwcocd7-_h_T0HTGolI1eBkDes,37484
4
- ipyvasp/_lattice.py,sha256=-0Zo12xSPgwWy1TEPtrsX6iEBah6VhpH4GuZ7f98K8g,103373
5
- ipyvasp/_version.py,sha256=7wELFVirq7De70ypmqa09QF6v-b6qREPH4ww4_OHDrg,23
4
+ ipyvasp/_lattice.py,sha256=AU_iQ4ZdJ0fEb8FxiADexOsVMp_zWJ11HLxBg_u9q7M,104022
5
+ ipyvasp/_version.py,sha256=ggGr8Eeuw9YZ1g40gSyKadNe96lor0upJSmlkeVHJlg,23
6
6
  ipyvasp/bsdos.py,sha256=ZtQji-W11UdFFicAoWZjlqVhI5tqYu_jpKyPPWKkeeo,30634
7
7
  ipyvasp/cli.py,sha256=aWFEVhNmnW8eSOp5uh95JaDwLQ9K9nlCQcbnOSuhWgw,6844
8
8
  ipyvasp/evals_dataframe.py,sha256=-sqxK7LPV6sYDO_XXmZ80FznOaXTkVdbqJKKvTUtMak,20637
9
- ipyvasp/lattice.py,sha256=QaLBQ3Qo-1TkX5iIfYEBW2vjBR1EjkKrYY5Mn8BVCpE,28914
9
+ ipyvasp/lattice.py,sha256=HUMh1GYS8CbY7D4VssRQbOV-klm7pK6gnfUU_evwC0k,27752
10
10
  ipyvasp/misc.py,sha256=SZJ_ePUR2-HEKYTEpDHVRVE7zpIQVTCjiuw0BCC9UTU,2349
11
11
  ipyvasp/potential.py,sha256=tzA73c5lkp6ahLSJchMrU043-QWaOV0nIOUA7VMmfKQ,11408
12
12
  ipyvasp/surface.py,sha256=MjE5oB0wW6Pca_C-xu8rN6OMH7lUEeNPNyM7Kz_Im-8,23766
@@ -17,9 +17,9 @@ ipyvasp/core/parser.py,sha256=C3CaZsJbPME_ttYlYy4DXeOdL7dnkXs-cHRwFZL6bio,38058
17
17
  ipyvasp/core/plot_toolkit.py,sha256=cktbPZTJ4K0_6-vKYqtQ1xIIPZg-gHJY5793M9XoYQ0,35754
18
18
  ipyvasp/core/serializer.py,sha256=OsnYhlwt8O6UeJQMKmjp1-hwRjhxiqobV6bybfDECUY,35777
19
19
  ipyvasp/core/spatial_toolkit.py,sha256=8DBYTiBFWJ7OBKuvOPw7UoEVCyNjJhSW0OcudjYZvAw,14748
20
- ipyvasp-0.8.6.dist-info/LICENSE,sha256=F3SO5RiAZOMfmMGf1KOuk2g_c4ObvuBJhd9iBLDgXoQ,1263
21
- ipyvasp-0.8.6.dist-info/METADATA,sha256=YWCB-4vDEen-pd4fYsn2j-emR3YU-5Fb7bbWijN0gm8,2436
22
- ipyvasp-0.8.6.dist-info/WHEEL,sha256=iYlv5fX357PQyRT2o6tw1bN-YcKFFHKqB_LwHO5wP-g,110
23
- ipyvasp-0.8.6.dist-info/entry_points.txt,sha256=C7m0Sjmr14wFjflCkWXLzr5N6-cQj8uJC9n82mUtzt8,44
24
- ipyvasp-0.8.6.dist-info/top_level.txt,sha256=ftziWlMWu_1VpDP1sRTFrkfBnWxAi393HYDVu4wRhUk,8
25
- ipyvasp-0.8.6.dist-info/RECORD,,
20
+ ipyvasp-0.8.7.dist-info/LICENSE,sha256=F3SO5RiAZOMfmMGf1KOuk2g_c4ObvuBJhd9iBLDgXoQ,1263
21
+ ipyvasp-0.8.7.dist-info/METADATA,sha256=xAr8HFygxeP0mLIRR5Pqbb04UuUOoXGwr7rUq4uDy2I,2436
22
+ ipyvasp-0.8.7.dist-info/WHEEL,sha256=iYlv5fX357PQyRT2o6tw1bN-YcKFFHKqB_LwHO5wP-g,110
23
+ ipyvasp-0.8.7.dist-info/entry_points.txt,sha256=C7m0Sjmr14wFjflCkWXLzr5N6-cQj8uJC9n82mUtzt8,44
24
+ ipyvasp-0.8.7.dist-info/top_level.txt,sha256=ftziWlMWu_1VpDP1sRTFrkfBnWxAi393HYDVu4wRhUk,8
25
+ ipyvasp-0.8.7.dist-info/RECORD,,