pyTEMlib 0.2025.4.1__py3-none-any.whl → 0.2025.9.1__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.
Potentially problematic release.
This version of pyTEMlib might be problematic. Click here for more details.
- build/lib/pyTEMlib/__init__.py +33 -0
- build/lib/pyTEMlib/animation.py +640 -0
- build/lib/pyTEMlib/atom_tools.py +238 -0
- build/lib/pyTEMlib/config_dir.py +31 -0
- build/lib/pyTEMlib/crystal_tools.py +1219 -0
- build/lib/pyTEMlib/diffraction_plot.py +756 -0
- build/lib/pyTEMlib/dynamic_scattering.py +293 -0
- build/lib/pyTEMlib/eds_tools.py +826 -0
- build/lib/pyTEMlib/eds_xsections.py +432 -0
- build/lib/pyTEMlib/eels_tools/__init__.py +44 -0
- build/lib/pyTEMlib/eels_tools/core_loss_tools.py +751 -0
- build/lib/pyTEMlib/eels_tools/eels_database.py +134 -0
- build/lib/pyTEMlib/eels_tools/low_loss_tools.py +655 -0
- build/lib/pyTEMlib/eels_tools/peak_fit_tools.py +175 -0
- build/lib/pyTEMlib/eels_tools/zero_loss_tools.py +264 -0
- build/lib/pyTEMlib/file_reader.py +274 -0
- build/lib/pyTEMlib/file_tools.py +811 -0
- build/lib/pyTEMlib/get_bote_salvat.py +69 -0
- build/lib/pyTEMlib/graph_tools.py +1153 -0
- build/lib/pyTEMlib/graph_viz.py +599 -0
- build/lib/pyTEMlib/image/__init__.py +37 -0
- build/lib/pyTEMlib/image/image_atoms.py +270 -0
- build/lib/pyTEMlib/image/image_clean.py +197 -0
- build/lib/pyTEMlib/image/image_distortion.py +299 -0
- build/lib/pyTEMlib/image/image_fft.py +277 -0
- build/lib/pyTEMlib/image/image_graph.py +926 -0
- build/lib/pyTEMlib/image/image_registration.py +316 -0
- build/lib/pyTEMlib/image/image_utilities.py +309 -0
- build/lib/pyTEMlib/image/image_window.py +421 -0
- build/lib/pyTEMlib/image_tools.py +699 -0
- build/lib/pyTEMlib/interactive_image.py +1 -0
- build/lib/pyTEMlib/kinematic_scattering.py +1196 -0
- build/lib/pyTEMlib/microscope.py +61 -0
- build/lib/pyTEMlib/probe_tools.py +906 -0
- build/lib/pyTEMlib/sidpy_tools.py +153 -0
- build/lib/pyTEMlib/simulation_tools.py +104 -0
- build/lib/pyTEMlib/test.py +437 -0
- build/lib/pyTEMlib/utilities.py +314 -0
- build/lib/pyTEMlib/version.py +5 -0
- build/lib/pyTEMlib/xrpa_x_sections.py +20976 -0
- pyTEMlib/__init__.py +25 -3
- pyTEMlib/animation.py +31 -22
- pyTEMlib/atom_tools.py +29 -34
- pyTEMlib/config_dir.py +2 -28
- pyTEMlib/crystal_tools.py +129 -165
- pyTEMlib/eds_tools.py +559 -342
- pyTEMlib/eds_xsections.py +432 -0
- pyTEMlib/eels_tools/__init__.py +44 -0
- pyTEMlib/eels_tools/core_loss_tools.py +751 -0
- pyTEMlib/eels_tools/eels_database.py +134 -0
- pyTEMlib/eels_tools/low_loss_tools.py +655 -0
- pyTEMlib/eels_tools/peak_fit_tools.py +175 -0
- pyTEMlib/eels_tools/zero_loss_tools.py +264 -0
- pyTEMlib/file_reader.py +274 -0
- pyTEMlib/file_tools.py +260 -1130
- pyTEMlib/get_bote_salvat.py +69 -0
- pyTEMlib/graph_tools.py +101 -174
- pyTEMlib/graph_viz.py +150 -0
- pyTEMlib/image/__init__.py +37 -0
- pyTEMlib/image/image_atoms.py +270 -0
- pyTEMlib/image/image_clean.py +197 -0
- pyTEMlib/image/image_distortion.py +299 -0
- pyTEMlib/image/image_fft.py +277 -0
- pyTEMlib/image/image_graph.py +926 -0
- pyTEMlib/image/image_registration.py +316 -0
- pyTEMlib/image/image_utilities.py +309 -0
- pyTEMlib/image/image_window.py +421 -0
- pyTEMlib/image_tools.py +154 -915
- pyTEMlib/kinematic_scattering.py +1 -1
- pyTEMlib/probe_tools.py +1 -1
- pyTEMlib/test.py +437 -0
- pyTEMlib/utilities.py +314 -0
- pyTEMlib/version.py +2 -3
- pyTEMlib/xrpa_x_sections.py +14 -10
- {pytemlib-0.2025.4.1.dist-info → pytemlib-0.2025.9.1.dist-info}/METADATA +13 -16
- pytemlib-0.2025.9.1.dist-info/RECORD +86 -0
- {pytemlib-0.2025.4.1.dist-info → pytemlib-0.2025.9.1.dist-info}/WHEEL +1 -1
- pytemlib-0.2025.9.1.dist-info/top_level.txt +6 -0
- pyTEMlib/core_loss_widget.py +0 -721
- pyTEMlib/eels_dialog.py +0 -754
- pyTEMlib/eels_dialog_utilities.py +0 -1199
- pyTEMlib/eels_tools.py +0 -2359
- pyTEMlib/file_tools_qt.py +0 -193
- pyTEMlib/image_dialog.py +0 -158
- pyTEMlib/image_dlg.py +0 -146
- pyTEMlib/info_widget.py +0 -1086
- pyTEMlib/info_widget3.py +0 -1120
- pyTEMlib/low_loss_widget.py +0 -479
- pyTEMlib/peak_dialog.py +0 -1129
- pyTEMlib/peak_dlg.py +0 -286
- pytemlib-0.2025.4.1.dist-info/RECORD +0 -38
- pytemlib-0.2025.4.1.dist-info/top_level.txt +0 -1
- {pytemlib-0.2025.4.1.dist-info → pytemlib-0.2025.9.1.dist-info}/entry_points.txt +0 -0
- {pytemlib-0.2025.4.1.dist-info → pytemlib-0.2025.9.1.dist-info}/licenses/LICENSE +0 -0
|
@@ -0,0 +1,756 @@
|
|
|
1
|
+
import matplotlib.pyplot as plt
|
|
2
|
+
|
|
3
|
+
import matplotlib.patches as patches
|
|
4
|
+
from mpl_toolkits.axes_grid1.anchored_artists import AnchoredSizeBar
|
|
5
|
+
from matplotlib.patches import Circle # , Ellipse, Rectangle
|
|
6
|
+
from matplotlib.collections import PatchCollection
|
|
7
|
+
from matplotlib.lines import Line2D
|
|
8
|
+
|
|
9
|
+
from scipy.interpolate import interp1d
|
|
10
|
+
from scipy.ndimage import map_coordinates, geometric_transform
|
|
11
|
+
|
|
12
|
+
import ase
|
|
13
|
+
import numpy as np
|
|
14
|
+
import sidpy
|
|
15
|
+
|
|
16
|
+
# ##################################
|
|
17
|
+
# Plot Reciprocal Unit Cell in 2D #
|
|
18
|
+
# ##################################
|
|
19
|
+
|
|
20
|
+
|
|
21
|
+
def plot_reciprocal_unit_cell_2D(atoms):
|
|
22
|
+
"""Plot # unit cell in reciprocal space in 2D"""
|
|
23
|
+
|
|
24
|
+
reciprocal_unit_cell = atoms.get_reciprocal_cell()
|
|
25
|
+
|
|
26
|
+
# ignore y direction
|
|
27
|
+
|
|
28
|
+
x = [reciprocal_unit_cell[0, 0], reciprocal_unit_cell[0, 0], reciprocal_unit_cell[1, 0], reciprocal_unit_cell[1, 0]]
|
|
29
|
+
z = [reciprocal_unit_cell[0, 2], reciprocal_unit_cell[2, 2], reciprocal_unit_cell[2, 2], reciprocal_unit_cell[0, 2]]
|
|
30
|
+
|
|
31
|
+
# Plot 2D
|
|
32
|
+
fig = plt.figure()
|
|
33
|
+
ax = plt.gca() # current axis
|
|
34
|
+
|
|
35
|
+
ax.scatter(x, z, c='red', s=80)
|
|
36
|
+
ax.add_patch(
|
|
37
|
+
patches.Rectangle(
|
|
38
|
+
(0, 0), # (x,y)
|
|
39
|
+
reciprocal_unit_cell[0, 0], # width
|
|
40
|
+
reciprocal_unit_cell[2, 2], # height
|
|
41
|
+
fill=False # remove background
|
|
42
|
+
)
|
|
43
|
+
)
|
|
44
|
+
ax.add_patch(
|
|
45
|
+
patches.FancyArrow(0, 0, reciprocal_unit_cell[0, 0], 0, width=0.02,
|
|
46
|
+
color='black',
|
|
47
|
+
head_width=0.08, # Default: 3 * width
|
|
48
|
+
head_length=0.1, # Default: 1.5 * head_width
|
|
49
|
+
length_includes_head=True # Default: False
|
|
50
|
+
)
|
|
51
|
+
)
|
|
52
|
+
ax.add_patch(
|
|
53
|
+
patches.FancyArrow(0, 0, 0, reciprocal_unit_cell[2, 2], width=0.02,
|
|
54
|
+
color='black',
|
|
55
|
+
head_width=0.08, # Default: 3 * width
|
|
56
|
+
head_length=0.1, # Default: 1.5 * head_width
|
|
57
|
+
length_includes_head=True # Default: False
|
|
58
|
+
)
|
|
59
|
+
)
|
|
60
|
+
|
|
61
|
+
plt.xlabel('x 1/nm')
|
|
62
|
+
plt.ylabel('z 1/nm')
|
|
63
|
+
ax.axis('equal')
|
|
64
|
+
# plt.title('Unit Cell in Reciprocal Space of {0}'.format(tags['crystal']) )
|
|
65
|
+
# texfig.savefig("recip_unit_cell")
|
|
66
|
+
# fig.savefig('recip_unit_cell.jpg', dpi=90, bbox_inches='tight')
|
|
67
|
+
plt.show()
|
|
68
|
+
return fig
|
|
69
|
+
|
|
70
|
+
|
|
71
|
+
# ####################
|
|
72
|
+
# Plot SAED Pattern #
|
|
73
|
+
# ####################
|
|
74
|
+
def plotSAED_parameter(gray=False):
|
|
75
|
+
|
|
76
|
+
tags = {'convergence_angle_A-1': 0,
|
|
77
|
+
'background': 'white', # 'white' 'grey'
|
|
78
|
+
'color_map': 'plasma', # ,'cubehelix' #'Greys'#'plasma'
|
|
79
|
+
'color_reflections': 'intensity'}
|
|
80
|
+
|
|
81
|
+
if gray:
|
|
82
|
+
tags['color_map'] = 'gray'
|
|
83
|
+
tags['background'] = '#303030' # 'darkgray'
|
|
84
|
+
tags['color_reflections'] = 'intensity'
|
|
85
|
+
tags['plot_HOLZ'] = 0
|
|
86
|
+
tags['plot_HOLZ_excess'] = 0
|
|
87
|
+
tags['plot_Kikuchi'] = 1
|
|
88
|
+
tags['plot_reflections'] = 1
|
|
89
|
+
|
|
90
|
+
tags['color_Kikuchi'] = 'green'
|
|
91
|
+
|
|
92
|
+
tags['linewidth_HOLZ'] = -1 # -1: linewidth according to intensity (structure factor F^2
|
|
93
|
+
tags['linewidth_Kikuchi'] = -1 # -1: linewidth according to intensity (structure factor F^2
|
|
94
|
+
|
|
95
|
+
tags['label_HOLZ'] = 0
|
|
96
|
+
tags['label_Kikuchi'] = 0
|
|
97
|
+
tags['label_reflections'] = 0
|
|
98
|
+
|
|
99
|
+
tags['label_color'] = 'white'
|
|
100
|
+
tags['label_size'] = 10
|
|
101
|
+
|
|
102
|
+
tags['color_Laue_Zones'] = ['red', 'blue', 'green', 'blue', 'green'] # , 'green', 'red'] #for OLZ give a sequence
|
|
103
|
+
tags['color_zero'] = 'red' # 'None' #'white'
|
|
104
|
+
tags['color_ring_zero'] = 'None' # 'Red' #'white' #, 'None'
|
|
105
|
+
tags['width_ring_zero'] = .2
|
|
106
|
+
|
|
107
|
+
# plotDiffPattern(tags,True)
|
|
108
|
+
tags['plot_rotation'] = 0. # degree
|
|
109
|
+
tags['plot_shift_x'] = -0.0
|
|
110
|
+
tags['plot_shift_y'] = 0.0
|
|
111
|
+
|
|
112
|
+
return tags
|
|
113
|
+
|
|
114
|
+
|
|
115
|
+
########################
|
|
116
|
+
# Plot Kikuchi Pattern #
|
|
117
|
+
########################
|
|
118
|
+
def plotKikuchi(grey=False):
|
|
119
|
+
tags = {'background': 'black', # 'white' 'grey'
|
|
120
|
+
'color_map': 'plasma', # ,'cubehelix'#'Greys'#'plasma'
|
|
121
|
+
'color_reflections': 'intensity',
|
|
122
|
+
'plot_HOLZ': 0,
|
|
123
|
+
'plot_HOLZ_excess': 0,
|
|
124
|
+
'plot_Kikuchi': 1,
|
|
125
|
+
'plot_reflections': 1,
|
|
126
|
+
'label_HOLZ': 0,
|
|
127
|
+
'label_Kikuchi': 0,
|
|
128
|
+
'label_reflections': 0,
|
|
129
|
+
'label_color': 'white',
|
|
130
|
+
'label_size': 10,
|
|
131
|
+
'color_Kikuchi': 'green',
|
|
132
|
+
'linewidth_HOLZ': -1, # -1: linewidth according to intensity (structure factor F^2
|
|
133
|
+
'linewidth_Kikuchi': -1, # -1: linewidth according to intensity (structure factor F^2
|
|
134
|
+
'color_Laue_Zones': ['red', 'blue', 'green', 'blue', 'green'], # , 'green', 'red'] #for OLZ give a sequence
|
|
135
|
+
'color_zero': 'white', # 'None' #'white'
|
|
136
|
+
'color_ring_zero': 'None', # 'Red' #'white' #, 'None'
|
|
137
|
+
'width_ring_zero': 2}
|
|
138
|
+
|
|
139
|
+
if grey:
|
|
140
|
+
tags['color_map'] = 'gray'
|
|
141
|
+
tags['background'] = '#303030' # 'darkgray'
|
|
142
|
+
tags['color_reflections'] = 'intensity'
|
|
143
|
+
|
|
144
|
+
return tags
|
|
145
|
+
|
|
146
|
+
# plotDiffPattern(tags,True)
|
|
147
|
+
|
|
148
|
+
|
|
149
|
+
########################
|
|
150
|
+
# Plot HOLZ Pattern #
|
|
151
|
+
########################
|
|
152
|
+
|
|
153
|
+
def plotHOLZ_parameter(grey=False):
|
|
154
|
+
tags = {'background': 'gray', 'color_map': 'plasma', 'color_reflections': 'intensity', 'plot_HOLZ': 1,
|
|
155
|
+
'plot_HOLZ_excess': 1, 'plot_Kikuchi': 1, 'plot_reflections': 1, 'label_HOLZ': 0, 'label_Kikuchi': 0,
|
|
156
|
+
'label_reflections': 0, 'label_color': 'white', 'label_size': 12, 'color_Kikuchi': 'green',
|
|
157
|
+
'linewidth_HOLZ': 1, 'linewidth_Kikuchi': -1,
|
|
158
|
+
'color_Laue_Zones': ['red', 'blue', 'lightblue', 'green', 'red'], 'color_zero': 'None',
|
|
159
|
+
'color_ring_zero': 'Red', 'width_ring_zero': 2, 'plot_rotation': 0., 'plot_shift_x': -0.0,
|
|
160
|
+
'plot_shift_y': 0.0} # 'white' 'grey'
|
|
161
|
+
|
|
162
|
+
# plotDiffPattern(holz,True)
|
|
163
|
+
return tags
|
|
164
|
+
|
|
165
|
+
|
|
166
|
+
########################
|
|
167
|
+
# Plot CBED Pattern #
|
|
168
|
+
########################
|
|
169
|
+
|
|
170
|
+
def plotCBED_parameter():
|
|
171
|
+
tags = {'background': 'black', 'color_map': 'plasma', 'color_reflections': 'intensity', 'plot_HOLZ': 1,
|
|
172
|
+
'plot_HOLZ_excess': 1, 'plot_Kikuchi': 1, 'plot_reflections': 1, 'label_HOLZ': 0, 'label_Kikuchi': 0,
|
|
173
|
+
'label_reflections': 0, 'label_color': 'white', 'label_size': 10, 'color_Kikuchi': 'green',
|
|
174
|
+
'linewidth_HOLZ': -1, 'linewidth_Kikuchi': -1, 'color_Laue_Zones': ['red', 'blue', 'green'],
|
|
175
|
+
'color_zero': 'white', 'color_ring_zero': 'Red', 'width_ring_zero': 2} # 'white' 'grey'
|
|
176
|
+
|
|
177
|
+
# plotDiffPattern(tags,True)
|
|
178
|
+
return tags
|
|
179
|
+
|
|
180
|
+
########################
|
|
181
|
+
# Plot HOLZ Pattern #
|
|
182
|
+
########################
|
|
183
|
+
|
|
184
|
+
|
|
185
|
+
def circles(x, y, s, c='b', vmin=None, vmax=None, **kwargs):
|
|
186
|
+
"""
|
|
187
|
+
Make a scatter plot of circles.
|
|
188
|
+
Similar to plt.scatter, but the size of circles are in data scale.
|
|
189
|
+
Parameters
|
|
190
|
+
----------
|
|
191
|
+
x, y : scalar or array_like, shape (n, )
|
|
192
|
+
Input data
|
|
193
|
+
s : scalar or array_like, shape (n, )
|
|
194
|
+
Radius of circles.
|
|
195
|
+
c : color or sequence of color, optional, default : 'b'
|
|
196
|
+
`c` can be a single color format string, or a sequence of color
|
|
197
|
+
specifications of length `N`, or a sequence of `N` numbers to be
|
|
198
|
+
mapped to colors using the `cmap` and `norm` specified via kwargs.
|
|
199
|
+
Note that `c` should not be a single numeric RGB or RGBA sequence
|
|
200
|
+
because that is indistinguishable from an array of values
|
|
201
|
+
to be colormapped. (If you insist, use `color` instead.)
|
|
202
|
+
`c` can be a 2-D array in which the rows are RGB or RGBA, however.
|
|
203
|
+
vmin, vmax : scalar, optional, default: None
|
|
204
|
+
`vmin` and `vmax` are used in conjunction with `norm` to normalize
|
|
205
|
+
luminance data. If either are `None`, the min and max of the
|
|
206
|
+
color array is used.
|
|
207
|
+
kwargs : `~matplotlib.collections.Collection` properties
|
|
208
|
+
Eg. alpha, edgecolor(ec), facecolor(fc), linewidth(lw), linestyle(ls),
|
|
209
|
+
norm, cmap, transform, etc.
|
|
210
|
+
Returns
|
|
211
|
+
-------
|
|
212
|
+
paths : `~matplotlib.collections.PathCollection`
|
|
213
|
+
Examples
|
|
214
|
+
--------
|
|
215
|
+
a = np.arange(11)
|
|
216
|
+
circles(a, a, s=a*0.2, c=a, alpha=0.5, ec='none')
|
|
217
|
+
plt.colorbar()
|
|
218
|
+
License
|
|
219
|
+
--------
|
|
220
|
+
This code is under [The BSD 3-Clause License]
|
|
221
|
+
(http://opensource.org/licenses/BSD-3-Clause)
|
|
222
|
+
"""
|
|
223
|
+
|
|
224
|
+
if np.isscalar(c):
|
|
225
|
+
kwargs.setdefault('color', c)
|
|
226
|
+
c = None
|
|
227
|
+
|
|
228
|
+
if 'fc' in kwargs:
|
|
229
|
+
kwargs.setdefault('facecolor', kwargs.pop('fc'))
|
|
230
|
+
if 'ec' in kwargs:
|
|
231
|
+
kwargs.setdefault('edgecolor', kwargs.pop('ec'))
|
|
232
|
+
if 'ls' in kwargs:
|
|
233
|
+
kwargs.setdefault('linestyle', kwargs.pop('ls'))
|
|
234
|
+
if 'lw' in kwargs:
|
|
235
|
+
kwargs.setdefault('linewidth', kwargs.pop('lw'))
|
|
236
|
+
# You can set `facecolor` with an array for each patch,
|
|
237
|
+
# while you can only set `facecolors` with a value for all.
|
|
238
|
+
|
|
239
|
+
zipped = np.broadcast(x, y, s)
|
|
240
|
+
patches = [Circle((x_, y_), s_, picker=True)
|
|
241
|
+
for x_, y_, s_ in zipped]
|
|
242
|
+
collection = PatchCollection(patches, **kwargs)
|
|
243
|
+
if c is not None:
|
|
244
|
+
c = np.broadcast_to(c, zipped.shape).ravel()
|
|
245
|
+
collection.set_array(c)
|
|
246
|
+
collection.set_clim(vmin, vmax)
|
|
247
|
+
|
|
248
|
+
ax = plt.gca()
|
|
249
|
+
ax.add_collection(collection)
|
|
250
|
+
ax.autoscale_view()
|
|
251
|
+
plt.draw_if_interactive()
|
|
252
|
+
if c is not None:
|
|
253
|
+
plt.sci(collection)
|
|
254
|
+
return collection
|
|
255
|
+
|
|
256
|
+
|
|
257
|
+
def cartesian2polar(x, y, grid, r, t, order=3):
|
|
258
|
+
R, T = np.meshgrid(r, t)
|
|
259
|
+
|
|
260
|
+
new_x = R * np.cos(T)
|
|
261
|
+
new_y = R * np.sin(T)
|
|
262
|
+
|
|
263
|
+
ix = interp1d(x, np.arange(len(x)))
|
|
264
|
+
iy = interp1d(y, np.arange(len(y)))
|
|
265
|
+
|
|
266
|
+
new_ix = ix(new_x.ravel())
|
|
267
|
+
new_iy = iy(new_y.ravel())
|
|
268
|
+
|
|
269
|
+
return map_coordinates(grid, np.array([new_ix, new_iy]),
|
|
270
|
+
order=order).reshape(new_x.shape)
|
|
271
|
+
|
|
272
|
+
|
|
273
|
+
def warp(diff, center):
|
|
274
|
+
"""
|
|
275
|
+
Define original polar grid
|
|
276
|
+
|
|
277
|
+
Parameter:
|
|
278
|
+
----------
|
|
279
|
+
diff: sidpy object or numpy ndarray of
|
|
280
|
+
diffraction pattern
|
|
281
|
+
center: list or numpy array of length 2
|
|
282
|
+
coordinates of center in pixel
|
|
283
|
+
|
|
284
|
+
Return:
|
|
285
|
+
------
|
|
286
|
+
numpy array of diffraction pattern in polar coordinates
|
|
287
|
+
|
|
288
|
+
"""
|
|
289
|
+
nx = diff.shape[0]
|
|
290
|
+
ny = diff.shape[1]
|
|
291
|
+
|
|
292
|
+
x = np.linspace(1, nx, nx, endpoint=True) - center[0]
|
|
293
|
+
y = np.linspace(1, ny, ny, endpoint=True) - center[1]
|
|
294
|
+
z = diff
|
|
295
|
+
|
|
296
|
+
# Define new polar grid
|
|
297
|
+
nr = int(min([center[0], center[1], diff.shape[0] - center[0], diff.shape[1] - center[1]]) - 1)
|
|
298
|
+
print(nr)
|
|
299
|
+
nt = 360 * 3
|
|
300
|
+
|
|
301
|
+
r = np.linspace(1, nr, nr)
|
|
302
|
+
t = np.linspace(0., np.pi, nt, endpoint=False)
|
|
303
|
+
return cartesian2polar(x, y, z, r, t, order=3).T
|
|
304
|
+
|
|
305
|
+
|
|
306
|
+
def topolar(img, order=1):
|
|
307
|
+
"""
|
|
308
|
+
Transform img to its polar coordinate representation.
|
|
309
|
+
|
|
310
|
+
order: int, default 1
|
|
311
|
+
Specify the spline interpolation order.
|
|
312
|
+
High orders may be slow for large images.
|
|
313
|
+
"""
|
|
314
|
+
# max_radius is the length of the diagonal
|
|
315
|
+
# from a corner to the mid-point of img.
|
|
316
|
+
max_radius = 0.5 * np.linalg.norm(img.shape)
|
|
317
|
+
|
|
318
|
+
def transform(coords):
|
|
319
|
+
# Put coord[1] in the interval, [-pi, pi]
|
|
320
|
+
theta = 2 * np.pi * coords[1] / (img.shape[1] - 1.)
|
|
321
|
+
|
|
322
|
+
# Then map it to the interval [0, max_radius].
|
|
323
|
+
# radius = float(img.shape[0]-coords[0]) / img.shape[0] * max_radius
|
|
324
|
+
radius = max_radius * coords[0] / img.shape[0]
|
|
325
|
+
|
|
326
|
+
i = 0.5 * img.shape[0] - radius * np.sin(theta)
|
|
327
|
+
j = radius * np.cos(theta) + 0.5 * img.shape[1]
|
|
328
|
+
return i, j
|
|
329
|
+
|
|
330
|
+
polar = geometric_transform(img, transform, order=order)
|
|
331
|
+
|
|
332
|
+
rads = max_radius * np.linspace(0, 1, img.shape[0])
|
|
333
|
+
angs = np.linspace(0, 2 * np.pi, img.shape[1])
|
|
334
|
+
|
|
335
|
+
return polar, (rads, angs)
|
|
336
|
+
|
|
337
|
+
|
|
338
|
+
def plot_ring_pattern(atoms, diffraction_pattern=None, grey=False):
|
|
339
|
+
"""
|
|
340
|
+
Plot of ring diffraction pattern with matplotlib
|
|
341
|
+
|
|
342
|
+
Parameters
|
|
343
|
+
----------
|
|
344
|
+
atoms: dictionary or sidpy.Dataset
|
|
345
|
+
information stored as dictionary either directly or in metadata attribute of sidpy.Dataset
|
|
346
|
+
grey: bool
|
|
347
|
+
plotting in greyscale if True
|
|
348
|
+
|
|
349
|
+
Returns
|
|
350
|
+
-------
|
|
351
|
+
fig: matplotlib figure
|
|
352
|
+
reference to matplotlib figure
|
|
353
|
+
"""
|
|
354
|
+
|
|
355
|
+
if isinstance(atoms, dict):
|
|
356
|
+
tags = atoms
|
|
357
|
+
elif isinstance(atoms, ase.Atoms):
|
|
358
|
+
if 'diffraction' in atoms.info:
|
|
359
|
+
tags = atoms.info['diffraction']
|
|
360
|
+
plot_diffraction_pattern = True
|
|
361
|
+
else:
|
|
362
|
+
raise TypeError('Diffraction information must be in metadata')
|
|
363
|
+
else:
|
|
364
|
+
raise TypeError('Diffraction info must be in sidpy Dataset or dictionary form')
|
|
365
|
+
if diffraction_pattern is not None:
|
|
366
|
+
if not(diffraction_pattern, sidpy.Dataset):
|
|
367
|
+
print('diffraction_pattern must be a sidpy.Dataset \n -> Ignoring this variable')
|
|
368
|
+
diffraction_pattern = None
|
|
369
|
+
d = tags['Ring_Pattern']['allowed']['g norm']
|
|
370
|
+
label = tags['Ring_Pattern']['allowed']['label']
|
|
371
|
+
if 'label_color' not in tags:
|
|
372
|
+
tags['label_color'] = 'navy'
|
|
373
|
+
if 'profile color' not in tags:
|
|
374
|
+
tags['profile color'] = 'navy'
|
|
375
|
+
if 'ring color' not in tags:
|
|
376
|
+
tags['ring color'] = 'red'
|
|
377
|
+
if 'label_size' not in tags:
|
|
378
|
+
tags['label_size'] = 10
|
|
379
|
+
if 'profile height' not in tags:
|
|
380
|
+
tags['profile height'] = 5
|
|
381
|
+
if 'plot_scalebar' not in tags:
|
|
382
|
+
tags['plot_scalebar'] = False
|
|
383
|
+
|
|
384
|
+
fg, ax = plt.subplots(1, 1)
|
|
385
|
+
|
|
386
|
+
# ###
|
|
387
|
+
# plot arcs of the rings
|
|
388
|
+
# ###
|
|
389
|
+
for i in range(len(d)):
|
|
390
|
+
pac = patches.Arc((0, 0), d[i] * 2, d[i] * 2, angle=0, theta1=45, theta2=360, color=tags['ring color'])
|
|
391
|
+
ax.add_patch(pac)
|
|
392
|
+
|
|
393
|
+
####
|
|
394
|
+
# show image in background
|
|
395
|
+
####
|
|
396
|
+
if plot_diffraction_pattern is not None:
|
|
397
|
+
plt.imshow(diffraction_pattern, extent=diffraction_pattern.get_extent(), cmap='gray')
|
|
398
|
+
|
|
399
|
+
ax.set_aspect("equal")
|
|
400
|
+
|
|
401
|
+
# fg.canvas.draw()
|
|
402
|
+
|
|
403
|
+
if tags['plot_scalebar']:
|
|
404
|
+
def f(axis):
|
|
405
|
+
l = axis.get_majorticklocs()
|
|
406
|
+
return len(l) > 1 and (l[1] - l[0])
|
|
407
|
+
|
|
408
|
+
sizex = f(ax.xaxis)
|
|
409
|
+
labelx = str(sizex) + ' 1/nm'
|
|
410
|
+
scalebar = AnchoredSizeBar(ax.transData, sizex, labelx, loc=3,
|
|
411
|
+
pad=0.5, color='white', frameon=False)
|
|
412
|
+
# size_vertical=.2, fill_bar = True) # will be implemented in matplotlib 2.1
|
|
413
|
+
|
|
414
|
+
ax.add_artist(scalebar)
|
|
415
|
+
ax.axis('off')
|
|
416
|
+
|
|
417
|
+
# ####
|
|
418
|
+
# plot profile
|
|
419
|
+
# ####
|
|
420
|
+
|
|
421
|
+
y = tags['Ring_Pattern']['profile_y']
|
|
422
|
+
y = y / y.max() * tags['profile height']
|
|
423
|
+
x = tags['Ring_Pattern']['profile_x']
|
|
424
|
+
ax.plot(x, y, c=tags['profile color'])
|
|
425
|
+
|
|
426
|
+
ax.plot([0, x[-1]], [0, 0], c=tags['profile color'])
|
|
427
|
+
|
|
428
|
+
if 'experimental profile_y' in tags:
|
|
429
|
+
yy = tags['experimental profile_y']
|
|
430
|
+
yy = yy / yy.max() * tags['profile height']
|
|
431
|
+
xx = tags['experimental profile_x']
|
|
432
|
+
ax.plot(xx, yy, c=tags['experimental profile color'])
|
|
433
|
+
|
|
434
|
+
if 'plot_image_FOV' in tags:
|
|
435
|
+
max_d = tags['plot_image_FOV'] / 2 + tags['plot_shift_x']
|
|
436
|
+
else:
|
|
437
|
+
max_d = d.max()
|
|
438
|
+
for i in range(len(d)):
|
|
439
|
+
if d[i] < max_d:
|
|
440
|
+
plt.text(d[i] - .2, -.5, label[i], fontsize=tags['label_size'], color=tags['label_color'], rotation=90)
|
|
441
|
+
|
|
442
|
+
if 'plot_FOV' in tags:
|
|
443
|
+
l = -tags['plot_FOV'] / 2
|
|
444
|
+
r = tags['plot_FOV'] / 2
|
|
445
|
+
t = -tags['plot_FOV'] / 2
|
|
446
|
+
b = tags['plot_FOV'] / 2
|
|
447
|
+
plt.xlim(l, r)
|
|
448
|
+
plt.ylim(t, b)
|
|
449
|
+
|
|
450
|
+
fg.show()
|
|
451
|
+
return fg
|
|
452
|
+
|
|
453
|
+
|
|
454
|
+
def plot_diffraction_pattern(atoms, diffraction_pattern=None, grey=False):
|
|
455
|
+
"""
|
|
456
|
+
Plot of spot diffraction pattern with matplotlib
|
|
457
|
+
Plot of spot diffraction pattern with matplotlib
|
|
458
|
+
|
|
459
|
+
Parameters
|
|
460
|
+
----------
|
|
461
|
+
atoms: dictionary or ase.Atoms object
|
|
462
|
+
information stored as dictionary either directly or in info attribute of ase.Atoms object
|
|
463
|
+
diffraction_pattern: None or sidpy.Dataset
|
|
464
|
+
diffraction pattern in background
|
|
465
|
+
grey: bool
|
|
466
|
+
plotting in greyscale if True
|
|
467
|
+
|
|
468
|
+
Returns
|
|
469
|
+
-------
|
|
470
|
+
fig: matplotlib figure
|
|
471
|
+
reference to matplotlib figure
|
|
472
|
+
"""
|
|
473
|
+
|
|
474
|
+
if isinstance(atoms, dict):
|
|
475
|
+
tags_out = atoms
|
|
476
|
+
|
|
477
|
+
elif isinstance(atoms, ase.Atoms):
|
|
478
|
+
if 'diffraction' in atoms.info:
|
|
479
|
+
tags_out = atoms.info['diffraction']
|
|
480
|
+
plot_diffraction_pattern = True
|
|
481
|
+
else:
|
|
482
|
+
raise TypeError('Diffraction information must be in info dictionary of ase.Atoms object')
|
|
483
|
+
else:
|
|
484
|
+
raise TypeError('Diffraction info must be in ase.Atoms object or dictionary form')
|
|
485
|
+
|
|
486
|
+
if 'output' not in atoms.info:
|
|
487
|
+
return
|
|
488
|
+
|
|
489
|
+
# Get information from dictionary
|
|
490
|
+
HOLZ = tags_out['HOLZ']
|
|
491
|
+
ZOLZ = tags_out['allowed']['ZOLZ']
|
|
492
|
+
# Kikuchi = tags_out['Kikuchi']
|
|
493
|
+
|
|
494
|
+
Laue_Zone = tags_out['allowed']['Laue_Zone']
|
|
495
|
+
|
|
496
|
+
label = tags_out['allowed']['label']
|
|
497
|
+
hkl_label = tags_out['allowed']['hkl']
|
|
498
|
+
|
|
499
|
+
angle = np.radians(atoms.info['output']['plot_rotation']) # mrad
|
|
500
|
+
c = np.cos(angle)
|
|
501
|
+
s = np.sin(angle)
|
|
502
|
+
r_mat = np.array([[c, -s, 0], [s, c, 0], [0, 0, 1]])
|
|
503
|
+
|
|
504
|
+
# HOLZ and Kikuchi lines coordinates in Hough space
|
|
505
|
+
LC = tags_out['Laue_circle']
|
|
506
|
+
gd = np.dot(tags_out['HOLZ']['g_deficient'] + LC, r_mat)
|
|
507
|
+
ge = np.dot(tags_out['HOLZ']['g_excess'], r_mat)
|
|
508
|
+
points = np.dot(tags_out['allowed']['g'] + LC, r_mat)
|
|
509
|
+
|
|
510
|
+
theta = tags_out['HOLZ']['theta'] + angle
|
|
511
|
+
|
|
512
|
+
if 'thickness' not in tags_out:
|
|
513
|
+
tags_out['thickness'] = 0.
|
|
514
|
+
if tags_out['thickness'] > 0.1:
|
|
515
|
+
intensity = np.real(tags_out['allowed']['Ig'])
|
|
516
|
+
else:
|
|
517
|
+
intensity = tags_out['allowed']['intensities']
|
|
518
|
+
|
|
519
|
+
radius = atoms.info['experimental']['convergence_angle_A-1']
|
|
520
|
+
|
|
521
|
+
if radius < 0.1:
|
|
522
|
+
radiusI = 2
|
|
523
|
+
else:
|
|
524
|
+
radiusI = radius
|
|
525
|
+
# Beginning and ends of HOLZ lines
|
|
526
|
+
max_length = radiusI * 1.3
|
|
527
|
+
h_xp = gd[:, 0] + max_length * np.cos(np.pi - theta)
|
|
528
|
+
h_yp = gd[:, 1] + max_length * np.sin(np.pi - theta)
|
|
529
|
+
h_xm = gd[:, 0] - max_length * np.cos(np.pi - theta)
|
|
530
|
+
h_ym = gd[:, 1] - max_length * np.sin(np.pi - theta)
|
|
531
|
+
|
|
532
|
+
# Beginning and ends of excess HOLZ lines
|
|
533
|
+
max_length = radiusI * .8
|
|
534
|
+
e_xp = ge[:, 0] + max_length * np.cos(np.pi - theta)
|
|
535
|
+
e_yp = ge[:, 1] + max_length * np.sin(np.pi - theta)
|
|
536
|
+
e_xm = ge[:, 0] - max_length * np.cos(np.pi - theta)
|
|
537
|
+
e_ym = ge[:, 1] - max_length * np.sin(np.pi - theta)
|
|
538
|
+
|
|
539
|
+
# Beginning and ends of Kikuchi lines
|
|
540
|
+
if 'max_length' not in tags_out['Kikuchi']:
|
|
541
|
+
tags_out['Kikuchi']['max_length'] = 20
|
|
542
|
+
max_length = tags_out['Kikuchi']['max_length']
|
|
543
|
+
|
|
544
|
+
gd = tags_out['Kikuchi']['g_deficient']
|
|
545
|
+
theta = tags_out['Kikuchi']['theta']
|
|
546
|
+
k_xp = gd[:, 0] + max_length * np.cos(np.pi - theta)
|
|
547
|
+
k_yp = gd[:, 1] + max_length * np.sin(np.pi - theta)
|
|
548
|
+
k_xm = gd[:, 0] - max_length * np.cos(np.pi - theta)
|
|
549
|
+
k_ym = gd[:, 1] - max_length * np.sin(np.pi - theta)
|
|
550
|
+
|
|
551
|
+
if atoms.info['output']['linewidth_Kikuchi'] < 0:
|
|
552
|
+
if len(intensity[ZOLZ]) > 0:
|
|
553
|
+
intensity_kikuchi = intensity * 4. / intensity[ZOLZ].max()
|
|
554
|
+
else:
|
|
555
|
+
intensity_kikuchi = intensity
|
|
556
|
+
else:
|
|
557
|
+
intensity_kikuchi = np.ones(len(intensity)) * atoms.info['output']['linewidth_Kikuchi']
|
|
558
|
+
|
|
559
|
+
if atoms.info['output']['linewidth_HOLZ'] < 0:
|
|
560
|
+
intensity_holz = np.log(intensity + 1)
|
|
561
|
+
|
|
562
|
+
if tags_out['HOLZ']['HOLZ'].any():
|
|
563
|
+
pass # intensity_holz = intensity/intensity[tags_out['HOLZ']['HOLZ']].max()*4.
|
|
564
|
+
else:
|
|
565
|
+
intensity_holz = np.ones(len(intensity)) * atoms.info['output']['linewidth_HOLZ']
|
|
566
|
+
|
|
567
|
+
# #######
|
|
568
|
+
# Plot #
|
|
569
|
+
# #######
|
|
570
|
+
# cms = mpl.cm
|
|
571
|
+
# cm = cms.plasma#jet#, cms.gray, cms.autumn]
|
|
572
|
+
cm = plt.get_cmap(atoms.info['output']['color_map'])
|
|
573
|
+
|
|
574
|
+
# fig = plt.figure()
|
|
575
|
+
fig = plt.figure()
|
|
576
|
+
|
|
577
|
+
ax = plt.gca()
|
|
578
|
+
if 'background' not in atoms.info['output']:
|
|
579
|
+
atoms.info['output']['background'] = None
|
|
580
|
+
if atoms.info['output']['background'] is not None:
|
|
581
|
+
ax.set_facecolor(atoms.info['output']['background'])
|
|
582
|
+
|
|
583
|
+
if diffraction_pattern is not None:
|
|
584
|
+
plt.imshow(diffraction_pattern, extent=diffraction_pattern.get_extent([0, 1]), cmap='gray')
|
|
585
|
+
|
|
586
|
+
ix = np.argsort((points ** 2).sum(axis=1))
|
|
587
|
+
p = points[ix]
|
|
588
|
+
inten = intensity[ix]
|
|
589
|
+
reflection = hkl_label[ix]
|
|
590
|
+
laue_color = []
|
|
591
|
+
|
|
592
|
+
labelP = ''
|
|
593
|
+
lineLabel = []
|
|
594
|
+
|
|
595
|
+
def onpick(event):
|
|
596
|
+
if isinstance(event.artist, Line2D):
|
|
597
|
+
thisline = event.artist
|
|
598
|
+
ind = ax.lines.index(thisline)
|
|
599
|
+
print(ind, len(points), ind - len(points))
|
|
600
|
+
# ind = ind- len(points)
|
|
601
|
+
h, k, l = lineLabel[ind]
|
|
602
|
+
|
|
603
|
+
if Laue_Zone[ind] > 0:
|
|
604
|
+
labelP = 'Laue Zone %1d; HOLZ line: [%1d,%1d,%1d]' % (Laue_Zone[ind], h, k, l)
|
|
605
|
+
else:
|
|
606
|
+
labelP = 'Kikuchi line: [%1d,%1d,%1d]' % (h, k, l)
|
|
607
|
+
# print(labelP)
|
|
608
|
+
|
|
609
|
+
elif isinstance(event.artist, Circle):
|
|
610
|
+
print('Circle')
|
|
611
|
+
|
|
612
|
+
else:
|
|
613
|
+
ind = event.ind[0]
|
|
614
|
+
h, k, l = reflection[ind]
|
|
615
|
+
|
|
616
|
+
print('Reflection: [%1d,%1d,%1d]' % (h, k, l))
|
|
617
|
+
|
|
618
|
+
for i in range(int(Laue_Zone.max()) + 1):
|
|
619
|
+
if i < len(atoms.info['output']['color_Laue_Zones']):
|
|
620
|
+
laue_color.append(atoms.info['output']['color_Laue_Zones'][i])
|
|
621
|
+
else:
|
|
622
|
+
laue_color.append(atoms.info['output']['color_Laue_Zones'][-1])
|
|
623
|
+
|
|
624
|
+
if 'plot_labels' not in atoms.info['output']:
|
|
625
|
+
atoms.info['output']['plot_labels'] = True
|
|
626
|
+
if atoms.info['output']['plot_reflections']:
|
|
627
|
+
if radius < 0.01:
|
|
628
|
+
if atoms.info['output']['color_reflections'] == 'intensity':
|
|
629
|
+
for i in range(len(points)):
|
|
630
|
+
ax.scatter(points[i, 0], points[i, 1], c=np.log(intensity[i] + 1), cmap=cm, s=100)
|
|
631
|
+
|
|
632
|
+
if atoms.info['output']['plot_labels']:
|
|
633
|
+
plt.text(points[i, 0], points[i, 1], label[i], fontsize=10)
|
|
634
|
+
else:
|
|
635
|
+
for i in range(len(Laue_Zone)):
|
|
636
|
+
color = laue_color[int(Laue_Zone[i])]
|
|
637
|
+
ax.scatter(points[i, 0], points[i, 1], c=color, cmap=cm, s=100)
|
|
638
|
+
if atoms.info['output']['plot_labels']:
|
|
639
|
+
plt.text(points[i, 0], points[i, 1], label[i], fontsize=8)
|
|
640
|
+
|
|
641
|
+
ax.scatter(LC[0], LC[1], c=atoms.info['output']['color_zero'], s=100)
|
|
642
|
+
radius = .2
|
|
643
|
+
else:
|
|
644
|
+
ix = np.argsort((points ** 2).sum(axis=1))
|
|
645
|
+
p = points[ix]
|
|
646
|
+
inten = intensity[ix]
|
|
647
|
+
if atoms.info['output']['color_reflections'] == 'intensity':
|
|
648
|
+
circles(p[:, 0], p[:, 1], s=radius, c=np.log(inten + 1), cmap=cm, alpha=0.9, edgecolor=None, picker=5)
|
|
649
|
+
else:
|
|
650
|
+
for i in range(len(Laue_Zone)):
|
|
651
|
+
color = laue_color[int(Laue_Zone[i])]
|
|
652
|
+
circles(p[i, 0], p[i, 1], s=radius, c=color, cmap=cm, alpha=0.9, edgecolor='', picker=5) #
|
|
653
|
+
plt.text(points[i, 0], points[i, 1], label[i], fontsize=8)
|
|
654
|
+
|
|
655
|
+
if 'plot_dynamically_allowed' not in atoms.info['output']:
|
|
656
|
+
atoms.info['output']['plot_dynamically_allowed'] = False
|
|
657
|
+
if 'plot_forbidden' not in atoms.info['output']:
|
|
658
|
+
atoms.info['output']['plot_forbidden'] = False
|
|
659
|
+
|
|
660
|
+
if atoms.info['output']['plot_dynamically_allowed']:
|
|
661
|
+
if 'dynamically_allowed' not in atoms.info['diffraction']['forbidden']:
|
|
662
|
+
print('To plot dynamically allowed reflections you must run the get_dynamically_allowed function of '
|
|
663
|
+
'kinematic_scattering library first!')
|
|
664
|
+
else:
|
|
665
|
+
points = atoms.info['diffraction']['forbidden']['g']
|
|
666
|
+
dynamically_allowed = atoms.info['diffraction']['forbidden']['dynamically_allowed']
|
|
667
|
+
dyn_allowed = atoms.info['diffraction']['forbidden']['g'][dynamically_allowed, :]
|
|
668
|
+
dyn_label = atoms.info['diffraction']['forbidden']['hkl'][dynamically_allowed, :]
|
|
669
|
+
|
|
670
|
+
color = laue_color[0]
|
|
671
|
+
ax.scatter(dyn_allowed[:, 0], dyn_allowed[:, 1], c='blue', alpha=0.4, s=70)
|
|
672
|
+
if atoms.info['output']['plot_labels']:
|
|
673
|
+
for i in range(len(dyn_allowed)):
|
|
674
|
+
plt.text(dyn_allowed[i, 0], dyn_allowed[i, 1], dyn_label[i], fontsize=8)
|
|
675
|
+
if atoms.info['output']['plot_forbidden']:
|
|
676
|
+
forbidden_g = atoms.info['diffraction']['forbidden']['g'][np.logical_not(dynamically_allowed), :]
|
|
677
|
+
forbidden_hkl = atoms.info['diffraction']['forbidden']['hkl'][np.logical_not(dynamically_allowed), :]
|
|
678
|
+
ax.scatter(forbidden_g[:, 0], forbidden_g[:, 1], c='orange', alpha=0.4, s=70)
|
|
679
|
+
if atoms.info['output']['plot_labels']:
|
|
680
|
+
for i in range(len(forbidden_g)):
|
|
681
|
+
plt.text(forbidden_g[i, 0], forbidden_g[i, 1], forbidden_hkl[i], fontsize=8)
|
|
682
|
+
elif atoms.info['output']['plot_forbidden']:
|
|
683
|
+
forbidden_g = atoms.info['diffraction']['forbidden']['g']
|
|
684
|
+
forbidden_hkl = atoms.info['diffraction']['forbidden']['hkl']
|
|
685
|
+
ax.scatter(forbidden_g[:, 0], forbidden_g[:, 1], c='orange', alpha=0.4, s=70)
|
|
686
|
+
if atoms.info['output']['plot_labels']:
|
|
687
|
+
for i in range(len(forbidden_g)):
|
|
688
|
+
plt.text(forbidden_g[i, 0], forbidden_g[i, 1], forbidden_hkl[i], fontsize=8)
|
|
689
|
+
|
|
690
|
+
k = 0
|
|
691
|
+
if atoms.info['output']['plot_HOLZ']:
|
|
692
|
+
for i in range(len(h_xp)):
|
|
693
|
+
if tags_out['HOLZ']['HOLZ'][i]:
|
|
694
|
+
color = laue_color[int(Laue_Zone[i])]
|
|
695
|
+
if atoms.info['output']['plot_HOLZ']:
|
|
696
|
+
# plot HOLZ lines
|
|
697
|
+
line, = plt.plot((h_xp[i], h_xm[i]), (h_yp[i], h_ym[i]), c=color, linewidth=intensity_holz[i],
|
|
698
|
+
picker=5)
|
|
699
|
+
if atoms.info['output']['label_HOLZ']: # Add indices
|
|
700
|
+
plt.text(h_xp[i], h_yp[i], label[i], fontsize=8)
|
|
701
|
+
lineLabel.append(hkl_label[i])
|
|
702
|
+
# print(i, hkl_label[i], intensity_holz[i])
|
|
703
|
+
|
|
704
|
+
if atoms.info['output']['plot_HOLZ_excess']:
|
|
705
|
+
line, = plt.plot((e_xp[i], e_xm[i]), (e_yp[i], e_ym[i]), c=color, linewidth=intensity_holz[i])
|
|
706
|
+
lineLabel.append(hkl_label[i])
|
|
707
|
+
|
|
708
|
+
if atoms.info['output']['label_HOLZ']: # Add indices
|
|
709
|
+
plt.text(e_xp[i], e_yp[i], label[i], fontsize=8)
|
|
710
|
+
|
|
711
|
+
elif atoms.info['output']['label_Kikuchi']: # Add indices
|
|
712
|
+
if ZOLZ[i]:
|
|
713
|
+
plt.text(k_xp[i], k_yp[i], label[i], fontsize=atoms.info['output']['label_size'],
|
|
714
|
+
color=atoms.info['output']['label_color'])
|
|
715
|
+
lineLabel.append(hkl_label[i])
|
|
716
|
+
if atoms.info['output']['plot_Kikuchi']:
|
|
717
|
+
# Beginning and ends of Kikuchi lines
|
|
718
|
+
if atoms.info['output']['label_Kikuchi']:
|
|
719
|
+
label_kikuchi = []
|
|
720
|
+
for i in range(len(label)):
|
|
721
|
+
if ZOLZ[i]:
|
|
722
|
+
label_kikuchi.append(label[i])
|
|
723
|
+
for i in range(len(k_xp)):
|
|
724
|
+
line, = plt.plot((k_xp[i], k_xm[i]), (k_yp[i], k_ym[i]), c=atoms.info['output']['color_Kikuchi'],
|
|
725
|
+
linewidth=2)
|
|
726
|
+
if atoms.info['output']['label_Kikuchi']: # Add indices
|
|
727
|
+
plt.text(k_xp[i], k_yp[i], label[i], fontsize=atoms.info['output']['label_size'],
|
|
728
|
+
color=atoms.info['output']['label_color'])
|
|
729
|
+
|
|
730
|
+
def format_coord(x, y):
|
|
731
|
+
return labelP + 'x=%1.4f, y=%1.4f' % (x, y)
|
|
732
|
+
|
|
733
|
+
ax.format_coord = format_coord
|
|
734
|
+
|
|
735
|
+
if atoms.info['output']['color_ring_zero'] != 'None':
|
|
736
|
+
ring = plt.Circle(LC, radius, color=atoms.info['output']['color_ring_zero'], fill=False, linewidth=2)
|
|
737
|
+
ax.add_artist(ring)
|
|
738
|
+
# print(ring)
|
|
739
|
+
if atoms.info['output']['color_zero'] != 'None':
|
|
740
|
+
circle = plt.Circle(LC, radius, color=atoms.info['output']['color_zero'], linewidth=2)
|
|
741
|
+
ax.add_artist(circle)
|
|
742
|
+
|
|
743
|
+
plt.axis('equal')
|
|
744
|
+
if 'plot_FOV' in tags_out:
|
|
745
|
+
l = -tags_out['plot_FOV'] / 2
|
|
746
|
+
r = tags_out['plot_FOV'] / 2
|
|
747
|
+
t = -tags_out['plot_FOV'] / 2
|
|
748
|
+
b = tags_out['plot_FOV'] / 2
|
|
749
|
+
plt.xlim(l, r)
|
|
750
|
+
plt.ylim(t, b)
|
|
751
|
+
|
|
752
|
+
fig.canvas.mpl_connect('pick_event', onpick)
|
|
753
|
+
# texfig.savefig("HOLZ")
|
|
754
|
+
|
|
755
|
+
# plt.title( tags_out['crystal'])
|
|
756
|
+
plt.show()
|