7
7
8
8
class UntiltPlane (object ):
9
9
"""Level the plane if the sample is tilted.
10
-
10
+
11
11
Left click on the image to select the points which will be used to create
12
12
the offset plane. On right-click, this plane will be substracted from
13
13
your image's original data, and the image will be redrawn with updated values.
14
14
Attention: The resulting data will always have zero as its' minimal value.
15
15
That is because after substracting the plane, we also substract the minimum
16
16
of that result.
17
17
Important Note: There is a strong assumption that the offset plane is linear.
18
-
18
+
19
19
Parameters:
20
20
-----------
21
21
data: 2D numpy.ndarray
22
- Your input data. NaNs are fine.
22
+ Your input data. NaNs are fine.
23
23
a, b, c: floats
24
24
The initial parameters of the flat offset plane.
25
25
Defaults: `a = np.nanmin(data)`, `b = 0`, `c = 0`
26
26
ftol: float
27
27
What precision of the fit is satisfactory? Default is 1e-10
28
28
**kwargs:
29
29
Arguments passed on to matplotlib.figure
30
-
30
+
31
31
Output:
32
32
----------
33
33
corrected_data: numpy.ndarray
34
34
The updated ("untilted") values of your input array.
35
35
plane_params: tuple(float, float, float)
36
36
The tuple of fitted plane parameters (a, b, c). You can also recover them
37
37
as `a`, `b` and `c`
38
-
39
-
40
-
38
+
39
+
40
+
41
41
Example:
42
42
---------
43
43
```
44
44
# You just need to run something like:
45
45
>>>my_untilter = UntiltPlane(data)
46
46
# Then, if you want to recover the corrected data:
47
- >>>corrected_data = my.untilter .corrected_data
47
+ >>>corrected_data = my_untilter .corrected_data
48
48
# If you wish to reconstruct the offset plane:
49
49
>>>a, b, c = my_untilter.plan_params
50
50
>>>offset_plane = np.fromfunction(lambda y, x: a + b*x + c*y, data.shape)
51
51
```
52
52
"""
53
-
53
+
54
54
def __init__ (self , data , a = "min" , b = 0 , c = 0 , ftol = 1e-10 , ** kwargs ):
55
-
56
- self .data = data
55
+
56
+ self .data = data
57
57
if a == "min" :
58
58
self .a = np .nanmin (self .data )
59
59
else :
@@ -66,12 +66,12 @@ def __init__(self, data, a="min", b=0, c=0, ftol=1e-10, **kwargs):
66
66
self .plane_data = []
67
67
self .my_points = []
68
68
69
-
69
+
70
70
figsize = kwargs .pop ("figsize" , (12 , 8 ))
71
71
facecolor = kwargs .pop ("facecolor" , "oldlace" )
72
72
self .fig , self .aximg = plt .subplots (figsize = figsize , facecolor = facecolor ,
73
73
** kwargs )
74
-
74
+
75
75
self .img = self .aximg .imshow (self .data , cmap = "cividis" )
76
76
self .aximg .tick_params (top = True , labeltop = True , bottom = False , labelbottom = False )
77
77
self .aximg .set_title ("Left-click to assign the points that will define\n " +
@@ -82,7 +82,7 @@ def __init__(self, data, a="min", b=0, c=0, ftol=1e-10, **kwargs):
82
82
83
83
def flat_plane_z (self , y , x ):
84
84
return self .a + self .b * x + self .c * y
85
-
85
+
86
86
def optimize_flat_plane_z (self , independent_coords , a , b , c ):
87
87
x = independent_coords [:, 0 ]
88
88
y = independent_coords [:, 1 ]
@@ -105,15 +105,15 @@ def onclick(self, event):
105
105
elif event .button != 1 :
106
106
self .fig .canvas .mpl_disconnect (self .cid )
107
107
self .detilt ()
108
-
108
+
109
109
def detilt (self ):
110
110
"""Remove the points, fit the (linear) plane, and update the image"""
111
-
111
+
112
112
# Remove all the points:
113
113
for point in self .my_points :
114
114
point .remove ()
115
115
self .my_points = []
116
-
116
+
117
117
clicked_data = np .array (self .plane_data )
118
118
independent_coords = clicked_data [:, :2 ]
119
119
measured_z = clicked_data [:, 2 ]
@@ -127,18 +127,18 @@ def detilt(self):
127
127
initial_guess ,
128
128
method = "lm" ,
129
129
ftol = self .ftol )
130
-
131
-
130
+
131
+
132
132
self .a , self .b , self .c = self .plane_params
133
133
base_plane = np .fromfunction (self .flat_plane_z , self .data .shape )
134
134
self .corrected_data = self .data - base_plane
135
135
# Correct the offset (not sure whether we should do this or not)
136
136
self .corrected_data -= np .nanmin (self .corrected_data )
137
-
137
+
138
138
im_min , im_max = 0 , np .nanmax (self .corrected_data )
139
139
gs = gridspec .GridSpec (1 ,2 )
140
140
self .aximg .set_position (gs [0 ].get_position (self .fig ))
141
- self .aximg .set_subplotspec (gs [0 ])
141
+ self .aximg .set_subplotspec (gs [0 ])
142
142
self .axcorr = self .fig .add_subplot (gs [1 ])
143
143
self .axcorr .imshow (self .corrected_data , cmap = "cividis" )
144
144
self .axcorr .tick_params (top = True , labeltop = True , bottom = False , labelbottom = False )
0 commit comments