tbkit 0.2.0__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.
- tbkit/__init__.py +27 -0
- tbkit/dos.py +65 -0
- tbkit/error_handling.py +988 -0
- tbkit/graphene.py +173 -0
- tbkit/kspace.py +563 -0
- tbkit/lattice.py +424 -0
- tbkit/lattices.py +126 -0
- tbkit/plot.py +690 -0
- tbkit/propagation.py +338 -0
- tbkit/save.py +98 -0
- tbkit/system.py +744 -0
- tbkit-0.2.0.dist-info/METADATA +260 -0
- tbkit-0.2.0.dist-info/RECORD +16 -0
- tbkit-0.2.0.dist-info/WHEEL +5 -0
- tbkit-0.2.0.dist-info/licenses/LICENSE +29 -0
- tbkit-0.2.0.dist-info/top_level.txt +1 -0
tbkit/plot.py
ADDED
|
@@ -0,0 +1,690 @@
|
|
|
1
|
+
from __future__ import annotations
|
|
2
|
+
|
|
3
|
+
import numpy as np
|
|
4
|
+
from numpy.typing import NDArray, ArrayLike
|
|
5
|
+
import matplotlib.pyplot as plt
|
|
6
|
+
from matplotlib.figure import Figure
|
|
7
|
+
from matplotlib.axes import Axes
|
|
8
|
+
from mpl_toolkits.mplot3d import Axes3D
|
|
9
|
+
from matplotlib.legend_handler import HandlerLine2D
|
|
10
|
+
import tbkit.error_handling as error_handling
|
|
11
|
+
import tbkit.dos as dos
|
|
12
|
+
from tbkit.system import System
|
|
13
|
+
import os
|
|
14
|
+
|
|
15
|
+
|
|
16
|
+
#################################
|
|
17
|
+
# CLASS PLOT
|
|
18
|
+
#################################
|
|
19
|
+
|
|
20
|
+
|
|
21
|
+
class Plot:
|
|
22
|
+
'''
|
|
23
|
+
Plot the results of the classes **lattice** or **system**.
|
|
24
|
+
|
|
25
|
+
:param sys: class instance **system**.
|
|
26
|
+
:param colors: Default value None. Color plot.
|
|
27
|
+
'''
|
|
28
|
+
|
|
29
|
+
def __init__(self, sys: System, colors: list[str] | None = None) -> None:
|
|
30
|
+
error_handling.sys(sys)
|
|
31
|
+
self.sys = sys
|
|
32
|
+
if colors is None:
|
|
33
|
+
self.colors = ['b', 'r', 'g', 'y', 'm', 'k']
|
|
34
|
+
else:
|
|
35
|
+
self.colors = colors
|
|
36
|
+
|
|
37
|
+
def plt_hopping(self, coor: NDArray, hop: NDArray, c: float) -> None:
|
|
38
|
+
'''
|
|
39
|
+
Private method called by *lattice_generic*.
|
|
40
|
+
'''
|
|
41
|
+
for i in range(len(hop)):
|
|
42
|
+
plt.plot([coor['x'][hop['i'][i]],
|
|
43
|
+
coor['x'][hop['j'][i]]],
|
|
44
|
+
[coor['y'][hop['i'][i]],
|
|
45
|
+
coor['y'][hop['j'][i]]],
|
|
46
|
+
'k', lw=c*hop['t'][i].real)
|
|
47
|
+
|
|
48
|
+
def lattice_generic(
|
|
49
|
+
self,
|
|
50
|
+
coor: NDArray,
|
|
51
|
+
ms: float,
|
|
52
|
+
lw: float,
|
|
53
|
+
c: float,
|
|
54
|
+
fs: float,
|
|
55
|
+
axis: bool,
|
|
56
|
+
plt_hop: bool,
|
|
57
|
+
plt_hop_low: bool,
|
|
58
|
+
plt_index: bool,
|
|
59
|
+
figsize: tuple[float, float] | None,
|
|
60
|
+
) -> Figure:
|
|
61
|
+
'''
|
|
62
|
+
Private method called by *lattice* and *lattice_hop*.
|
|
63
|
+
'''
|
|
64
|
+
error_handling.positive_real(ms, 'ms')
|
|
65
|
+
error_handling.positive_real(lw, 'lw')
|
|
66
|
+
error_handling.positive_real(c, 'c')
|
|
67
|
+
error_handling.positive_real(fs, 'fs')
|
|
68
|
+
error_handling.boolean(axis, 'axis')
|
|
69
|
+
error_handling.boolean(plt_hop, 'plt_hop')
|
|
70
|
+
error_handling.boolean(plt_hop_low, 'plt_hop_low')
|
|
71
|
+
error_handling.boolean(plt_index, 'plt_index')
|
|
72
|
+
error_handling.tuple_2elem(figsize, 'figsize')
|
|
73
|
+
fig, ax = plt.subplots(figsize=figsize)
|
|
74
|
+
# hoppings
|
|
75
|
+
if plt_hop:
|
|
76
|
+
error_handling.empty_ndarray(self.sys.hop, 'sys.hop')
|
|
77
|
+
self.plt_hopping(coor, self.sys.hop[self.sys.hop['ang']>=0], c)
|
|
78
|
+
if plt_hop_low:
|
|
79
|
+
error_handling.empty_ndarray(self.sys.hop, 'sys.hop')
|
|
80
|
+
self.plt_hopping(coor, self.sys.hop[self.sys.hop['ang']<0], c)
|
|
81
|
+
# plot sites
|
|
82
|
+
for color, tag in zip(self.colors, self.sys.lat.tags):
|
|
83
|
+
plt.plot(coor['x'][coor['tag'] == tag],
|
|
84
|
+
coor['y'][coor['tag'] == tag],
|
|
85
|
+
'o', color=color, ms=ms, markeredgecolor='none')
|
|
86
|
+
ax.set_aspect('equal')
|
|
87
|
+
ax.set_xlim([np.min(coor['x'])-1., np.max(coor['x'])+1.])
|
|
88
|
+
ax.set_ylim([np.min(coor['y'])-1., np.max(coor['y'])+1.])
|
|
89
|
+
if not axis:
|
|
90
|
+
ax.axis('off')
|
|
91
|
+
# plot indices
|
|
92
|
+
if plt_index:
|
|
93
|
+
indices = ['{}'.format(i) for i in range(self.sys.lat.sites)]
|
|
94
|
+
for l, x, y in zip(indices, coor['x'], coor['y']):
|
|
95
|
+
plt.annotate(l, xy=(x, y), xytext=(0, 0),
|
|
96
|
+
textcoords='offset points',
|
|
97
|
+
ha='right', va='bottom', size=fs)
|
|
98
|
+
plt.draw()
|
|
99
|
+
return fig
|
|
100
|
+
|
|
101
|
+
def lattice(
|
|
102
|
+
self,
|
|
103
|
+
ms: float = 20,
|
|
104
|
+
lw: float = 5.,
|
|
105
|
+
c: float = 3.,
|
|
106
|
+
fs: float = 20,
|
|
107
|
+
axis: bool = False,
|
|
108
|
+
plt_hop: bool = False,
|
|
109
|
+
plt_hop_low: bool = False,
|
|
110
|
+
plt_index: bool = False,
|
|
111
|
+
figsize: tuple[float, float] | None = None,
|
|
112
|
+
) -> Figure:
|
|
113
|
+
'''
|
|
114
|
+
Plot lattice.
|
|
115
|
+
|
|
116
|
+
:param ms: Positive number. Default value 20. Markersize.
|
|
117
|
+
:param c: Positive number. Default value 3.
|
|
118
|
+
Coefficient. Hopping linewidths given by c*hop['t'].
|
|
119
|
+
:param fs: Positive number. Default value 20. Fontsize.
|
|
120
|
+
:param plt_hop: Boolean. Default value False. Plot hoppings.
|
|
121
|
+
:param plt_hop_low: Boolean. Default value False.
|
|
122
|
+
Plot hoppings diagonal low.
|
|
123
|
+
:param plt_index: Boolean. Default value False. Plot site labels.
|
|
124
|
+
:param axis: Boolean. Default value False. Plot axis.
|
|
125
|
+
:param figsize: Tuple. Default value None. Figure size.
|
|
126
|
+
|
|
127
|
+
:returns:
|
|
128
|
+
* **fig** -- Figure.
|
|
129
|
+
'''
|
|
130
|
+
error_handling.empty_ndarray(self.sys.lat.coor, 'lat.get_lattice')
|
|
131
|
+
return self.lattice_generic(self.sys.lat.coor, ms, lw, c, fs, axis, plt_hop,
|
|
132
|
+
plt_hop_low, plt_index, figsize)
|
|
133
|
+
|
|
134
|
+
def lattice_hop(
|
|
135
|
+
self,
|
|
136
|
+
ms: float = 20,
|
|
137
|
+
lw: float = 5,
|
|
138
|
+
c: float = 3.,
|
|
139
|
+
fs: float = 20,
|
|
140
|
+
axis: bool = False,
|
|
141
|
+
plt_hop: bool = False,
|
|
142
|
+
plt_hop_low: bool = False,
|
|
143
|
+
plt_index: bool = False,
|
|
144
|
+
figsize: tuple[float, float] | None = None,
|
|
145
|
+
) -> Figure:
|
|
146
|
+
'''
|
|
147
|
+
Plot lattice in hopping space.
|
|
148
|
+
|
|
149
|
+
:param ms: Positive Float. Default value 20. Markersize.
|
|
150
|
+
:param c: Positive Float. Default value 3. Coefficient.
|
|
151
|
+
Hopping linewidths given by c*hop['t'].
|
|
152
|
+
:param fs: Positive Float. Default value 20. Fontsize.
|
|
153
|
+
:param axis: Boolean. Default value False. Plot axis.
|
|
154
|
+
:param plt_hop: Boolean. Default value False. Plot hoppings.
|
|
155
|
+
:param plt_index: Boolean. Default value False. Plot site labels.
|
|
156
|
+
:param figsize: Tuple. Default value None. Figure size.
|
|
157
|
+
|
|
158
|
+
:returns:
|
|
159
|
+
* **fig** -- Figure.
|
|
160
|
+
'''
|
|
161
|
+
error_handling.empty_ndarray(self.sys.coor_hop, 'sys.get_coor_hop')
|
|
162
|
+
return self.lattice_generic(self.sys.coor_hop, ms, lw, c, fs, axis, plt_hop,
|
|
163
|
+
plt_hop_low, plt_index, figsize)
|
|
164
|
+
|
|
165
|
+
|
|
166
|
+
def spectrum_hist(self, nbr_bins: int = 61, fs: float = 20, lims: tuple[float, float] | None = None) -> None:
|
|
167
|
+
"""
|
|
168
|
+
Plot the spectrum.
|
|
169
|
+
|
|
170
|
+
:param nbr_bins: Default value 101. Number of bins of the histogram.
|
|
171
|
+
:param lims: List, lims[0] energy min, lims[1] energy max.
|
|
172
|
+
"""
|
|
173
|
+
error_handling.empty_ndarray(self.sys.en, 'sys.get_eig')
|
|
174
|
+
error_handling.positive_real(nbr_bins, 'nbr_bins')
|
|
175
|
+
error_handling.lims(lims)
|
|
176
|
+
fig, ax = plt.subplots()
|
|
177
|
+
if lims is None:
|
|
178
|
+
en_max = np.max(self.sys.en.real)
|
|
179
|
+
ind_en = np.ones(self.sys.lat.sites, bool)
|
|
180
|
+
ax.set_ylim([-en_max, en_max])
|
|
181
|
+
else:
|
|
182
|
+
ind_en = np.argwhere((self.sys.en > lims[0]) & (self.sys.en < lims[1]))
|
|
183
|
+
ind_en = np.ravel(ind_en)
|
|
184
|
+
ax.set_xlim(lims)
|
|
185
|
+
en = self.sys.en[ind_en]
|
|
186
|
+
n, bins, patches = plt.hist(en, bins=nbr_bins, color='b', alpha=0.8)
|
|
187
|
+
ax.set_title('Spectrum', fontsize=fs)
|
|
188
|
+
ax.set_xlabel('$E$', fontsize=fs)
|
|
189
|
+
ax.set_ylabel('number of states', fontsize=fs)
|
|
190
|
+
ax.set_ylim([0, np.max(n)+1])
|
|
191
|
+
for label in ax.xaxis.get_majorticklabels():
|
|
192
|
+
label.set_fontsize(fs)
|
|
193
|
+
for label in ax.yaxis.get_majorticklabels():
|
|
194
|
+
label.set_fontsize(fs)
|
|
195
|
+
|
|
196
|
+
def dos(
|
|
197
|
+
self,
|
|
198
|
+
broadening: float = 0.05,
|
|
199
|
+
kernel: str = 'gaussian',
|
|
200
|
+
e_grid: ArrayLike | None = None,
|
|
201
|
+
fs: float = 20,
|
|
202
|
+
lw: float = 2.,
|
|
203
|
+
figsize: tuple[float, float] | None = None,
|
|
204
|
+
) -> Figure:
|
|
205
|
+
'''
|
|
206
|
+
Plot the (broadened) density of states, see *tbkit.dos.density_of_states*.
|
|
207
|
+
|
|
208
|
+
:param broadening: Positive real number. Default value 0.05. Kernel width.
|
|
209
|
+
:param kernel: String. Default value 'gaussian'. 'gaussian' or 'lorentzian'.
|
|
210
|
+
:param e_grid: Real ndarray. Default value None. Energies at which to
|
|
211
|
+
evaluate the density of states.
|
|
212
|
+
:param fs: Positive number. Default value 20. Fontsize.
|
|
213
|
+
:param lw: Positive number. Default value 2. Linewidth.
|
|
214
|
+
:param figsize: Tuple. Default value None. Figure size.
|
|
215
|
+
|
|
216
|
+
:returns:
|
|
217
|
+
* **fig** -- Figure.
|
|
218
|
+
'''
|
|
219
|
+
error_handling.empty_ndarray(self.sys.en, 'sys.get_eig')
|
|
220
|
+
error_handling.positive_real(fs, 'fs')
|
|
221
|
+
error_handling.positive_real(lw, 'lw')
|
|
222
|
+
error_handling.tuple_2elem(figsize, 'figsize')
|
|
223
|
+
e_grid, rho = dos.density_of_states(self.sys.en, e_grid=e_grid,
|
|
224
|
+
broadening=broadening, kernel=kernel)
|
|
225
|
+
fig, ax = plt.subplots(figsize=figsize)
|
|
226
|
+
ax.plot(e_grid, rho, 'b', lw=lw)
|
|
227
|
+
ax.fill_between(e_grid, rho, color='b', alpha=0.2)
|
|
228
|
+
ax.set_xlim([e_grid[0], e_grid[-1]])
|
|
229
|
+
ax.set_ylim([0., None])
|
|
230
|
+
ax.set_title('Density of states', fontsize=fs)
|
|
231
|
+
ax.set_xlabel('$E$', fontsize=fs)
|
|
232
|
+
ax.set_ylabel(r'$\rho(E)$', fontsize=fs)
|
|
233
|
+
for label in ax.xaxis.get_majorticklabels():
|
|
234
|
+
label.set_fontsize(fs)
|
|
235
|
+
for label in ax.yaxis.get_majorticklabels():
|
|
236
|
+
label.set_fontsize(fs)
|
|
237
|
+
fig.set_layout_engine('tight')
|
|
238
|
+
plt.draw()
|
|
239
|
+
return fig
|
|
240
|
+
|
|
241
|
+
def spectrum(
|
|
242
|
+
self,
|
|
243
|
+
ms: float = 10,
|
|
244
|
+
fs: float = 20,
|
|
245
|
+
lims: tuple[float, float] | None = None,
|
|
246
|
+
tag_pola: str | None = None,
|
|
247
|
+
ipr: bool | None = None,
|
|
248
|
+
peterman: bool | None = None,
|
|
249
|
+
) -> Figure:
|
|
250
|
+
'''
|
|
251
|
+
Plot spectrum (eigenenergies real part (blue circles),
|
|
252
|
+
and sublattice polarization if *pola* not empty (red circles).
|
|
253
|
+
|
|
254
|
+
:param ms: Default value 10. Markersize.
|
|
255
|
+
:param fs: Default value 20. Fontsize.
|
|
256
|
+
:param lims: List, lims[0] energy min, lims[1] energy max.
|
|
257
|
+
:param tag_pola: Default value None. One-character string. Tag of the sublattice.
|
|
258
|
+
:param ipr: Default value None. If True plot the Inverse Partitipation Ration.
|
|
259
|
+
:param petermann: Default value None. If True plot the Petermann factor.
|
|
260
|
+
|
|
261
|
+
:returns:
|
|
262
|
+
* **fig** -- Figure.
|
|
263
|
+
'''
|
|
264
|
+
error_handling.empty_ndarray(self.sys.en, 'sys.get_eig')
|
|
265
|
+
error_handling.positive_real(ms, 'ms')
|
|
266
|
+
error_handling.positive_real(fs, 'fs')
|
|
267
|
+
error_handling.lims(lims)
|
|
268
|
+
fig, ax1 = plt.subplots()
|
|
269
|
+
ax1 = plt.gca()
|
|
270
|
+
x = np.arange(self.sys.lat.sites)
|
|
271
|
+
if lims is None:
|
|
272
|
+
en_max = np.max(self.sys.en.real)
|
|
273
|
+
ax1.set_ylim([-en_max-0.2, en_max+0.2])
|
|
274
|
+
ind = np.ones(self.sys.lat.sites, bool)
|
|
275
|
+
else:
|
|
276
|
+
ind = (self.sys.en > lims[0]) & (self.sys.en < lims[1])
|
|
277
|
+
ax1.set_ylim([lims[0]-0.1, lims[1]+0.1])
|
|
278
|
+
ax1.plot(x[ind], self.sys.en.real[ind], 'ob', markersize=ms)
|
|
279
|
+
ax1.set_title('Spectrum', fontsize=fs)
|
|
280
|
+
ax1.set_xlabel('$n$', fontsize=fs)
|
|
281
|
+
ax1.set_ylabel('$E_n$', fontsize=fs, color='blue')
|
|
282
|
+
for label in ax1.get_yticklabels():
|
|
283
|
+
label.set_color('b')
|
|
284
|
+
if tag_pola:
|
|
285
|
+
error_handling.tag(tag_pola, self.sys.lat.tags)
|
|
286
|
+
fig, ax2 = self.polarization(fig=fig, ax1=ax1, ms=ms, fs=fs, tag_pola=tag_pola, ind=ind)
|
|
287
|
+
elif ipr:
|
|
288
|
+
fig, ax2 = self.ipr(fig=fig, ax1=ax1, ms=ms, fs=fs, ind=ind)
|
|
289
|
+
elif peterman:
|
|
290
|
+
fig, ax2 = self.petermann(fig=fig, ax1=ax1, ms=ms, fs=fs, ind=ind)
|
|
291
|
+
for label in ax1.xaxis.get_majorticklabels():
|
|
292
|
+
label.set_fontsize(fs)
|
|
293
|
+
for label in ax1.yaxis.get_majorticklabels():
|
|
294
|
+
label.set_fontsize(fs)
|
|
295
|
+
xa = ax1.get_xaxis()
|
|
296
|
+
ax1.set_xlim([x[ind][0]-0.5, x[ind][-1]+0.5])
|
|
297
|
+
xa.set_major_locator(plt.MaxNLocator(integer=True))
|
|
298
|
+
fig.set_layout_engine('tight')
|
|
299
|
+
plt.draw()
|
|
300
|
+
return fig
|
|
301
|
+
|
|
302
|
+
def polarization(
|
|
303
|
+
self,
|
|
304
|
+
fig: Figure | None = None,
|
|
305
|
+
ax1: Axes | None = None,
|
|
306
|
+
ms: float = 10.,
|
|
307
|
+
fs: float = 20.,
|
|
308
|
+
lims: tuple[float, float] | None = None,
|
|
309
|
+
tag_pola: str | None = None,
|
|
310
|
+
ind: NDArray | None = None,
|
|
311
|
+
) -> tuple[Figure, Axes]:
|
|
312
|
+
'''
|
|
313
|
+
Plot sublattice polarization.
|
|
314
|
+
|
|
315
|
+
:param fig: Figure. Default value None. (used by the method spectrum).
|
|
316
|
+
:param ax1: Axis. Default value None. (used by the method spectrum).
|
|
317
|
+
:param ms: Positive Float. Default value 10. Markersize.
|
|
318
|
+
:param fs: Positive Float. Default value 20. Fontsize.
|
|
319
|
+
:param lims: List, lims[0] energy min, lims[1] energy max.
|
|
320
|
+
:param tag_pola: One-character string. Default value None. Tag of the sublattice.
|
|
321
|
+
:param ind: List. Default value None. List of indices. (used in the method spectrum).
|
|
322
|
+
|
|
323
|
+
:returns:
|
|
324
|
+
* **fig** -- Figure.
|
|
325
|
+
'''
|
|
326
|
+
if fig is None:
|
|
327
|
+
error_handling.sys(self.sys)
|
|
328
|
+
error_handling.empty_ndarray(self.sys.en, 'sys.get_eig')
|
|
329
|
+
error_handling.positive_real(ms, 'ms')
|
|
330
|
+
error_handling.positive_real(fs, 'fs')
|
|
331
|
+
error_handling.lims(lims)
|
|
332
|
+
fig, ax2 = plt.subplots()
|
|
333
|
+
ax2 = plt.gca()
|
|
334
|
+
if lims is None:
|
|
335
|
+
ax2.set_ylim([-0.1, 1.1])
|
|
336
|
+
ind = np.ones(self.sys.lat.sites, bool)
|
|
337
|
+
else:
|
|
338
|
+
ind = (self.sys.en > lims[0]) & (self.sys.en < lims[1])
|
|
339
|
+
ax2.set_ylim([lims[0]-0.1, lims[1]+0.1])
|
|
340
|
+
else:
|
|
341
|
+
ax2 = plt.twinx()
|
|
342
|
+
error_handling.empty_ndarray(self.sys.pola, 'sys.get_pola')
|
|
343
|
+
error_handling.tag(tag_pola, self.sys.lat.tags)
|
|
344
|
+
x = np.arange(self.sys.lat.sites)
|
|
345
|
+
i_tag = self.sys.lat.tags == tag_pola
|
|
346
|
+
ax2.plot(x[ind], np.ravel(self.sys.pola[ind, i_tag]), 'or', markersize=(4*ms)//5)
|
|
347
|
+
ylabel = '$<' + tag_pola.upper() + '|' + tag_pola.upper() + '>$'
|
|
348
|
+
ax2.set_ylabel(ylabel, fontsize=fs, color='red')
|
|
349
|
+
ax2.set_ylim([-0.1, 1.1])
|
|
350
|
+
ax2.set_xlim(-0.5, x[ind][-1]+0.5)
|
|
351
|
+
for tick in ax2.xaxis.get_major_ticks():
|
|
352
|
+
tick.label1.set_fontsize(fs)
|
|
353
|
+
for label in ax2.get_yticklabels():
|
|
354
|
+
label.set_color('r')
|
|
355
|
+
return fig, ax2
|
|
356
|
+
|
|
357
|
+
def ipr(
|
|
358
|
+
self,
|
|
359
|
+
fig: Figure | None = None,
|
|
360
|
+
ax1: Axes | None = None,
|
|
361
|
+
ms: float = 10,
|
|
362
|
+
fs: float = 20,
|
|
363
|
+
lims: tuple[float, float] | None = None,
|
|
364
|
+
ind: NDArray | None = None,
|
|
365
|
+
) -> tuple[Figure, Axes]:
|
|
366
|
+
'''
|
|
367
|
+
Plot Inverse Participation Ration.
|
|
368
|
+
|
|
369
|
+
:param fig: Figure. Default value None. (used by the method spectrum).
|
|
370
|
+
:param ax1: Axis. Default value None. (used by the method spectrum).
|
|
371
|
+
:param ms: Positive Float. Default value 10. Markersize.
|
|
372
|
+
:param fs: Positive Float. Default value 20. Fontsize.
|
|
373
|
+
:param lims: List. lims[0] energy min, lims[1] energy max.
|
|
374
|
+
:param ind: List. Default value None. List of indices. (used in the method spectrum).
|
|
375
|
+
|
|
376
|
+
:returns:
|
|
377
|
+
* **fig** -- Figure.
|
|
378
|
+
'''
|
|
379
|
+
if fig is None:
|
|
380
|
+
error_handling.sys(self.sys)
|
|
381
|
+
error_handling.empty_ndarray(self.sys.ipr, 'sys.get_ipr')
|
|
382
|
+
error_handling.positive_real(ms, 'ms')
|
|
383
|
+
error_handling.positive_real(fs, 'fs')
|
|
384
|
+
error_handling.lims(lims)
|
|
385
|
+
fig, ax2 = plt.subplots()
|
|
386
|
+
ax2 = plt.gca()
|
|
387
|
+
if lims is None:
|
|
388
|
+
ind = np.ones(self.sys.lat.sites, bool)
|
|
389
|
+
else:
|
|
390
|
+
ind = (self.sys.en > lims[0]) & (self.sys.en < lims[1])
|
|
391
|
+
else:
|
|
392
|
+
ax2 = plt.twinx()
|
|
393
|
+
error_handling.empty_ndarray(self.sys.ipr, 'sys.get_ipr')
|
|
394
|
+
x = np.arange(self.sys.lat.sites)
|
|
395
|
+
ax2.plot(x[ind], self.sys.ipr[ind], 'or', markersize=(4*ms)//5)
|
|
396
|
+
ax2.set_ylabel( 'IPR' , fontsize=fs, color='red')
|
|
397
|
+
ax2.set_xlim(-0.5, x[ind][-1]+0.5)
|
|
398
|
+
for tick in ax2.xaxis.get_major_ticks():
|
|
399
|
+
tick.label1.set_fontsize(fs)
|
|
400
|
+
for label in ax2.get_yticklabels():
|
|
401
|
+
label.set_color('r')
|
|
402
|
+
return fig, ax2
|
|
403
|
+
|
|
404
|
+
def petermann(
|
|
405
|
+
self,
|
|
406
|
+
fig: Figure | None = None,
|
|
407
|
+
ax1: Axes | None = None,
|
|
408
|
+
ms: float = 10,
|
|
409
|
+
fs: float = 20,
|
|
410
|
+
lims: tuple[float, float] | None = None,
|
|
411
|
+
ind: NDArray | None = None,
|
|
412
|
+
) -> tuple[Figure, Axes]:
|
|
413
|
+
'''
|
|
414
|
+
Plot Peterman factor.
|
|
415
|
+
|
|
416
|
+
:param fig: Figure. Default value None. (used by the method spectrum).
|
|
417
|
+
:param ax1: Axis. Default value None. (used by the method spectrum).
|
|
418
|
+
:param ms: Positive Float. Default value 10. Markersize.
|
|
419
|
+
:param fs: Positive Float. Default value 20. Fontsize.
|
|
420
|
+
:param lims: List. lims[0] energy min, lims[1] energy max.
|
|
421
|
+
:param ind: List. Default value None. List of indices. (used in the method spectrum).
|
|
422
|
+
|
|
423
|
+
:returns:
|
|
424
|
+
* **fig** -- Figure.
|
|
425
|
+
'''
|
|
426
|
+
if fig is None:
|
|
427
|
+
error_handling.sys(self.sys)
|
|
428
|
+
error_handling.empty_ndarray(self.sys.ipr, 'sys.get_petermann')
|
|
429
|
+
error_handling.positive_real(ms, 'ms')
|
|
430
|
+
error_handling.positive_real(fs, 'fs')
|
|
431
|
+
error_handling.lims(lims)
|
|
432
|
+
fig, ax2 = plt.subplots()
|
|
433
|
+
ax2 = plt.gca()
|
|
434
|
+
if lims is None:
|
|
435
|
+
ind = np.ones(self.sys.lat.sites, bool)
|
|
436
|
+
else:
|
|
437
|
+
ind = (self.sys.en > lims[0]) & (self.sys.en < lims[1])
|
|
438
|
+
else:
|
|
439
|
+
ax2 = plt.twinx()
|
|
440
|
+
error_handling.empty_ndarray(self.sys.ipr, 'sys.get_ipr')
|
|
441
|
+
x = np.arange(self.sys.lat.sites)
|
|
442
|
+
ax2.plot(x[ind], self.sys.petermann[ind], 'or', markersize=(4*ms)//5)
|
|
443
|
+
ax2.set_ylabel( 'K' , fontsize=fs, color='red')
|
|
444
|
+
ax2.set_xlim(-0.5, x[ind][-1]+0.5)
|
|
445
|
+
for tick in ax2.xaxis.get_major_ticks():
|
|
446
|
+
tick.label1.set_fontsize(fs)
|
|
447
|
+
for label in ax2.get_yticklabels():
|
|
448
|
+
label.set_color('r')
|
|
449
|
+
return fig, ax2
|
|
450
|
+
|
|
451
|
+
def spectrum_complex(self, ms: float = 10., fs: float = 20., lims: tuple[float, float] | None = None) -> Figure:
|
|
452
|
+
'''
|
|
453
|
+
Plot complex value eigenenergies, real part (blue circles),
|
|
454
|
+
and imaginary part (red circles).
|
|
455
|
+
|
|
456
|
+
:param ms: Positive Float. Default value 20. Markersize.
|
|
457
|
+
:param fs: Positive Float. Default value 20. Font size.
|
|
458
|
+
:param lims: List. lims[0] energy min, lims[1] energy max.
|
|
459
|
+
|
|
460
|
+
:returns:
|
|
461
|
+
* **fig** -- Figure.
|
|
462
|
+
'''
|
|
463
|
+
error_handling.empty_ndarray(self.sys.en, 'sys.get_eig')
|
|
464
|
+
error_handling.positive_real(ms, 'ms')
|
|
465
|
+
error_handling.positive_real(fs, 'fs')
|
|
466
|
+
error_handling.lims(lims)
|
|
467
|
+
fig, ax1 = plt.subplots()
|
|
468
|
+
ax1 = plt.gca()
|
|
469
|
+
x = np.arange(self.sys.lat.sites)
|
|
470
|
+
if lims is None:
|
|
471
|
+
en_max = np.max(self.sys.en.real)
|
|
472
|
+
ax1.set_ylim([-en_max-0.2, en_max+0.2])
|
|
473
|
+
ind = np.ones(self.sys.lat.sites, bool)
|
|
474
|
+
else:
|
|
475
|
+
ind = (self.sys.en > lims[0]) & (self.sys.en < lims[1])
|
|
476
|
+
ax1.set_ylim([lims[0]-0.1, lims[1]+0.1])
|
|
477
|
+
ax1.plot(x[ind], self.sys.en.real[ind], 'ob', markersize=ms)
|
|
478
|
+
ax1.plot(x[ind], self.sys.en.imag[ind], 'or', markersize=ms)
|
|
479
|
+
ax1.set_title('Spectrum', fontsize=fs)
|
|
480
|
+
ax1.set_xlabel('$n$', fontsize=fs)
|
|
481
|
+
ax1.set_ylabel('Re '+r'$E_n$'+', Im '+r'$E_n$', fontsize=fs)
|
|
482
|
+
for label in ax1.xaxis.get_majorticklabels():
|
|
483
|
+
label.set_fontsize(fs)
|
|
484
|
+
for label in ax1.yaxis.get_majorticklabels():
|
|
485
|
+
label.set_fontsize(fs)
|
|
486
|
+
xa = ax1.get_xaxis()
|
|
487
|
+
ax1.set_xlim([x[ind][0]-0.1, x[ind][-1]+0.1])
|
|
488
|
+
xa.set_major_locator(plt.MaxNLocator(integer=True))
|
|
489
|
+
fig.set_layout_engine('tight')
|
|
490
|
+
plt.draw()
|
|
491
|
+
return fig
|
|
492
|
+
|
|
493
|
+
def intensity_1d(
|
|
494
|
+
self, intensity: NDArray, ms: float = 20., lw: float = 2., fs: float = 20.,
|
|
495
|
+
title: str = r'$|\psi^{(j)}|^2$',
|
|
496
|
+
) -> Figure:
|
|
497
|
+
'''
|
|
498
|
+
Plot intensity for 1D lattices.
|
|
499
|
+
|
|
500
|
+
:param intensity: np.array. Field intensity.
|
|
501
|
+
:param ms: Positive Float. Default value 20. Markersize.
|
|
502
|
+
:param lw: Positive Float. Default value 2. Linewith, connect sublattice sites.
|
|
503
|
+
:param fs: Positive Float. Default value 20. Font size.
|
|
504
|
+
:param title: String. Default value 'Intensity'. Figure title.
|
|
505
|
+
'''
|
|
506
|
+
error_handling.ndarray(intensity, 'intensity', self.sys.lat.sites)
|
|
507
|
+
error_handling.empty_ndarray(self.sys.lat.coor, 'sys.get_lattice')
|
|
508
|
+
error_handling.positive_real(ms, 'ms')
|
|
509
|
+
error_handling.positive_real(lw, 'lw')
|
|
510
|
+
error_handling.positive_real(fs, 'fs')
|
|
511
|
+
error_handling.string(title, 'title')
|
|
512
|
+
fig, ax = plt.subplots()
|
|
513
|
+
ax.set_xlabel('$j$', fontsize=fs)
|
|
514
|
+
ax.set_ylabel(title, fontsize=fs)
|
|
515
|
+
ax.set_title(title, fontsize=fs)
|
|
516
|
+
for t, c in zip(self.sys.lat.tags, self.colors):
|
|
517
|
+
plt.plot(self.sys.lat.coor['x'][self.sys.lat.coor['tag'] == t],
|
|
518
|
+
intensity[self.sys.lat.coor['tag'] == t],
|
|
519
|
+
'-o', color=c, ms=ms, lw=lw)
|
|
520
|
+
plt.xlim([-1., self.sys.lat.sites])
|
|
521
|
+
plt.ylim([0., np.max(intensity)+.05])
|
|
522
|
+
fig.set_layout_engine('tight')
|
|
523
|
+
plt.draw()
|
|
524
|
+
return fig
|
|
525
|
+
|
|
526
|
+
def intensity_disk(
|
|
527
|
+
self,
|
|
528
|
+
intensity: NDArray,
|
|
529
|
+
s: float = 200.,
|
|
530
|
+
fs: float = 20.,
|
|
531
|
+
lims: tuple[float, float] | None = None,
|
|
532
|
+
figsize: tuple[float, float] | None = None,
|
|
533
|
+
title: str = r'$|\psi|^2$',
|
|
534
|
+
) -> Figure:
|
|
535
|
+
r'''
|
|
536
|
+
Plot the intensity. Colormap with identical disk shape.
|
|
537
|
+
|
|
538
|
+
:param intensity: np.array.Field intensity.
|
|
539
|
+
:param s: Default value 200. Disk size.
|
|
540
|
+
:param fs: Default value 20. Font size.
|
|
541
|
+
:param lims: List. Default value None. Colormap limits.
|
|
542
|
+
:param figsize: Tuple. Default value None. Figure size.
|
|
543
|
+
:param title: String. Default value '$|\psi_n|^2$'. Title.
|
|
544
|
+
|
|
545
|
+
:returns:
|
|
546
|
+
* **fig** -- Figure.
|
|
547
|
+
'''
|
|
548
|
+
error_handling.empty_ndarray(self.sys.lat.coor, 'sys.get_lattice')
|
|
549
|
+
error_handling.ndarray(intensity, 'intensity', self.sys.lat.sites)
|
|
550
|
+
error_handling.positive_real(s, 's')
|
|
551
|
+
error_handling.positive_real(fs, 'fs')
|
|
552
|
+
error_handling.tuple_2elem(figsize, 'figsize')
|
|
553
|
+
error_handling.string(title, 'title')
|
|
554
|
+
fig, ax = plt.subplots(figsize=figsize)
|
|
555
|
+
plt.title(title, fontsize=fs+5)
|
|
556
|
+
map_red = plt.get_cmap('Reds')
|
|
557
|
+
if lims is None:
|
|
558
|
+
lims = [0., np.max(intensity)]
|
|
559
|
+
y_ticks = ['0', 'max']
|
|
560
|
+
else:
|
|
561
|
+
y_ticks = lims
|
|
562
|
+
plt.scatter(self.sys.lat.coor['x'], self.sys.lat.coor['y'], c=intensity, s=s,
|
|
563
|
+
cmap=map_red, vmin=lims[0], vmax=lims[1])
|
|
564
|
+
cbar = plt.colorbar(ticks=lims)
|
|
565
|
+
ax.set_xticks([])
|
|
566
|
+
ax.set_yticks([])
|
|
567
|
+
ax.set_xlim(np.min(self.sys.lat.coor['x'])-1., np.max(self.sys.lat.coor['x'])+1.)
|
|
568
|
+
ax.set_ylim(np.min(self.sys.lat.coor['y'])-1., np.max(self.sys.lat.coor['y'])+1.)
|
|
569
|
+
cbar.ax.set_yticklabels([y_ticks[0], y_ticks[1]])
|
|
570
|
+
cbar.ax.tick_params(labelsize=fs)
|
|
571
|
+
ax.set_aspect('equal')
|
|
572
|
+
fig.set_layout_engine('tight')
|
|
573
|
+
plt.draw()
|
|
574
|
+
return fig
|
|
575
|
+
|
|
576
|
+
def intensity_area(
|
|
577
|
+
self,
|
|
578
|
+
intensity: NDArray,
|
|
579
|
+
s: float = 1000.,
|
|
580
|
+
lw: float = 1.,
|
|
581
|
+
fs: float = 20.,
|
|
582
|
+
plt_hop: bool = False,
|
|
583
|
+
figsize: tuple[float, float] | None = None,
|
|
584
|
+
title: str = r'$|\psi|^2$',
|
|
585
|
+
) -> Figure:
|
|
586
|
+
r'''
|
|
587
|
+
Plot the intensity. Intensity propotional to disk shape.
|
|
588
|
+
|
|
589
|
+
:param intensity: np.array. Intensity.
|
|
590
|
+
:param s: Positive Float. Default value 1000.
|
|
591
|
+
Circle size given by s * intensity.
|
|
592
|
+
:param lw: Positive Float. Default value 1. Hopping linewidths.
|
|
593
|
+
:param fs: Positive Float. Default value 20. Fontsize.
|
|
594
|
+
:param plt_hop: Boolean. Default value False. Plot hoppings.
|
|
595
|
+
:param figsize: Tuple. Default value None. Figure size.
|
|
596
|
+
:param title: String. Default value '$|\psi_{ij}|^2$'. Figure title.
|
|
597
|
+
|
|
598
|
+
:returns:
|
|
599
|
+
* **fig** -- Figure.
|
|
600
|
+
'''
|
|
601
|
+
error_handling.empty_ndarray(self.sys.lat.coor, 'sys.get_lattice')
|
|
602
|
+
error_handling.ndarray(intensity, 'intensity', self.sys.lat.sites)
|
|
603
|
+
error_handling.positive_real(s, 's')
|
|
604
|
+
error_handling.positive_real(fs, 'fs')
|
|
605
|
+
error_handling.boolean(plt_hop, 'plt_hop')
|
|
606
|
+
error_handling.tuple_2elem(figsize, 'figsize')
|
|
607
|
+
error_handling.string(title, 'title')
|
|
608
|
+
fig, ax = plt.subplots()
|
|
609
|
+
ax.set_xlabel('$i$', fontsize=fs)
|
|
610
|
+
ax.set_ylabel('$j$', fontsize=fs)
|
|
611
|
+
ax.set_title(title, fontsize=fs)
|
|
612
|
+
if plt_hop:
|
|
613
|
+
plt.plot([self.sys.lat.coor['x'][self.sys.hop['i'][:]],
|
|
614
|
+
self.sys.lat.coor['x'][self.sys.hop['j'][:]]],
|
|
615
|
+
[self.sys.lat.coor['y'][self.sys.hop['i'][:]],
|
|
616
|
+
self.sys.lat.coor['y'][self.sys.hop['j'][:]]],
|
|
617
|
+
'k', lw=lw)
|
|
618
|
+
for tag, color in zip(self.sys.lat.tags, self.colors):
|
|
619
|
+
plt.scatter(self.sys.lat.coor['x'][self.sys.lat.coor['tag'] == tag],
|
|
620
|
+
self.sys.lat.coor['y'][self.sys.lat.coor['tag'] == tag],
|
|
621
|
+
s=100*s*intensity[self.sys.lat.coor['tag'] == tag],
|
|
622
|
+
c=color, alpha=0.5)
|
|
623
|
+
ax.set_aspect('equal')
|
|
624
|
+
ax.axis('off')
|
|
625
|
+
x_lim = [np.min(self.sys.lat.coor['x'])-2., np.max(self.sys.lat.coor['x'])+2.]
|
|
626
|
+
y_lim = [np.min(self.sys.lat.coor['y'])-2., np.max(self.sys.lat.coor['y'])+2.]
|
|
627
|
+
ax.set_xlim(x_lim)
|
|
628
|
+
ax.set_ylim(y_lim)
|
|
629
|
+
fig.set_layout_engine('tight')
|
|
630
|
+
plt.draw()
|
|
631
|
+
return fig
|
|
632
|
+
|
|
633
|
+
def butterfly(
|
|
634
|
+
self,
|
|
635
|
+
betas: NDArray,
|
|
636
|
+
butterfly: NDArray,
|
|
637
|
+
lw: float = 1.,
|
|
638
|
+
fs: float = 20.,
|
|
639
|
+
lims: tuple[float, float] | None = None,
|
|
640
|
+
title: str = '',
|
|
641
|
+
) -> Figure:
|
|
642
|
+
'''
|
|
643
|
+
Plot energies depending on a parameter.
|
|
644
|
+
|
|
645
|
+
:param betas: np.array. Parameter values.
|
|
646
|
+
:param butterfly: np.array. Eigenvalues.
|
|
647
|
+
:param lw: Positive Float. Default value 1. Hopping linewidths.
|
|
648
|
+
:param fs: Positive Float. Default value 20. Fontsize.
|
|
649
|
+
:param lims: List, lims[0] energy min, lims[1] energy max.
|
|
650
|
+
:param title: Default value ''. Figure title.
|
|
651
|
+
'''
|
|
652
|
+
error_handling.ndarray_empty(betas, 'betas')
|
|
653
|
+
error_handling.ndarray_empty(butterfly, 'butterfly')
|
|
654
|
+
error_handling.positive_real(lw, 'lw')
|
|
655
|
+
error_handling.positive_real(fs, 'fs')
|
|
656
|
+
error_handling.lims(lims)
|
|
657
|
+
error_handling.string(title, 'title')
|
|
658
|
+
i_beta_min = np.argmin(np.abs(betas))
|
|
659
|
+
if lims is None:
|
|
660
|
+
lims = [butterfly[i_beta_min, 0], butterfly[i_beta_min, -1]]
|
|
661
|
+
ind_en = np.argwhere((butterfly[i_beta_min, :] > lims[0]) &
|
|
662
|
+
(butterfly[i_beta_min, :] < lims[1]))
|
|
663
|
+
ind_en = np.ravel(ind_en)
|
|
664
|
+
fig, ax = plt.subplots()
|
|
665
|
+
plt.title('Energies depending on strain', fontsize=fs)
|
|
666
|
+
plt.xlabel(r'$\beta/\beta_{max}$', fontsize=fs)
|
|
667
|
+
plt.ylabel('$E$', fontsize=fs)
|
|
668
|
+
ax.set_title(title, fontsize=fs)
|
|
669
|
+
plt.yticks(np.arange(lims[0], lims[1]+1, (lims[1]-lims[0])/4), fontsize=fs)
|
|
670
|
+
plt.ylim(lims)
|
|
671
|
+
beta_max = max(self.sys.betas)
|
|
672
|
+
plt.xticks([-beta_max, -0.5*beta_max, 0,
|
|
673
|
+
0.5*beta_max, beta_max], fontsize=fs)
|
|
674
|
+
ax.set_xticklabels(('-1', '-1/2', '0', '1/2', '1'))
|
|
675
|
+
plt.xlim([betas[0], betas[-1]])
|
|
676
|
+
for i in ind_en:
|
|
677
|
+
plt.plot(betas, butterfly[:, i], 'b', lw=lw)
|
|
678
|
+
fig.set_layout_engine('tight')
|
|
679
|
+
plt.draw()
|
|
680
|
+
return fig
|
|
681
|
+
|
|
682
|
+
def show(self) -> None:
|
|
683
|
+
"""
|
|
684
|
+
Emulate Matplotlib method plt.show().
|
|
685
|
+
"""
|
|
686
|
+
plt.show()
|
|
687
|
+
|
|
688
|
+
|
|
689
|
+
# Backward-compatible lowercase alias (pre-0.2 API).
|
|
690
|
+
plot = Plot
|