-
Notifications
You must be signed in to change notification settings - Fork 1
/
Copy pathgeneral_utils.jl
428 lines (310 loc) · 11.1 KB
/
general_utils.jl
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
using Printf
"""
tbin(tvector, t)
Returns indmin(abs.(tvector-t)) -- just a shorthand way
for finding, in a vector of time bins tvector, the bin
that corresponds the closest to time t.
"""
function tbin(tvector, t)
return argmin(abs.(tvector.-t))
end
"""
append_to_file(filename, str)
Opens filename, appends str to it, and closes filename.
If filename is not a string but us type Base.PipeEndpoint (an IO stream)
then simply prints to it, without trying to open or close
"""
function append_to_file(filename, str)
if typeof(filename)<:IO
@printf(filename, "%s", str)
else
fstr = open(filename, "a")
@printf(fstr, "%s", str)
close(fstr)
end
end
"""
function print_vector(vec)
Takes a vector and uses @printf to put it on the screen with [%.3f, %.3f] format.
If passed a symbol (which must evaluate to a vector), then prints the string for that symbol,
an equals sign, the vector, and ends by adding a carriage return \n.
"""
function print_vector(vec)
print_vector(STDOUT, vec)
end
"""
function print_vector(fname::String, vec)
Takes a vector and uses @printf to append it to file fname with [%.3f, %.3f] format.
If passed a symbol (which must evaluate to a vector), then prints the string for that symbol,
an equals sign, the vector, and ends by adding a carriage return \n.
"""
function print_vector(fname::String, vec)
ostream = open(fname, "a")
print_vector(ostream, vec)
close(ostream)
end
"""
function print_vector(stream::IO, vec)
Takes a vector and uses @sprintf to put it on stream IO with [%.3f, %.3f] format.
If passed a symbol (which must evaluate to a vector), then prints the string for that symbol,
an equals sign, the vector, and ends by adding a carriage return \n.
"""
function print_vector(stream::IO, vec)
if typeof(vec)==Symbol
mystr = string(vec)
@printf(stream, "%s = ", mystr);
print_vector(stream, eval(vec))
@printf(stream, "\n");
return
end
@printf stream "["
for p in [1:length(vec);]
@printf(stream, "%.3f", vec[p])
if p < length(vec) @printf(stream, ", "); end
end
@printf(stream, "]")
end
"""
function print_vector_g(vec)
Takes a vector and uses @printf to put it on the screen with [%g, %g] format.
If passed a symbol (which must evaluate to a vector), then prints the string for that symbol,
an equals sign, the vector, and ends by adding a carriage return \n.
"""
function print_vector_g(vec)
print_vector_g(STDOUT, vec)
end
"""
function print_vector_g(fname::String, vec)
Takes a vector and uses @printf to append it to file fname with [%g, %g] format.
If passed a symbol (which must evaluate to a vector), then prints the string for that symbol,
an equals sign, the vector, and ends by adding a carriage return \n.
"""
function print_vector_g(fname::String, vec)
ostream = open(fname, "a")
print_vector_g(ostream, vec)
close(ostream)
end
"""
function print_vector_g(stream::IO, vec)
Takes a vector and uses @printf to put it on stream with [%g, %g] format.
If passed a symbol (which must evaluate to a vector), then prints the string for that symbol,
an equals sign, the vector, and ends by adding a carriage return \n.
"""
function print_vector_g(stream::IO, vec)
if typeof(vec)==Symbol
mystr = string(vec)
@printf(stream, "%s = ", mystr);
print_vector_g(stream, eval(vec))
@printf(stream, "\n");
return
end
@printf stream "["
for p in [1:length(vec);]
@printf(stream, "%g", vec[p])
if p < length(vec) @printf(stream, ", "); end
end
@printf(stream, "]")
end
"""
safe_axes(axh; further_params...)
If you're going to make axh the current axes, this function
first makes axh's figure the current figure. Some Julias
break without that.
Any optional keyword-value arguments are passed on to axes()
"""
function safe_axes(axh; further_params...)
figure(axh.figure.number)
PyPlot.axes(axh; Dict(further_params)...)
end
"""
ax = axisWidthChange(factor; lock="c", ax=nothing)
Changes the width of the current axes by a scalar factor.
= PARAMETERS:
- factor The scalar value by which to change the width, for example
0.8 (to make them thinner) or 1.5 (to make them fatter)
= OPTIONAL PARAMETERS:
- lock="c" Which part of the axis to keep fixed. "c", the default does
the changes around the middle; "l" means keep the left edge fixed
"r" means keep the right edge fixed
- ax = nothing If left as the default (nothing), works on the current axis;
otherwise should be an axis object to be modified.
"""
function axisWidthChange(factor; lock="c", ax=nothing)
if ax==nothing; ax=gca(); end
x, y, w, h = ax.get_position().bounds
if lock=="l";
elseif lock=="c" || lock=="m"; x = x + w*(1-factor)/2;
elseif lock=="r"; x = x + w*(1-factor);
else error("I don't know lock type ", lock)
end
w = w*factor;
ax.set_position([x, y, w, h])
return ax
end
"""
ax = axisHeightChange(factor; lock="c", ax=nothing)
Changes the height of the current axes by a scalar factor.
= PARAMETERS:
- factor The scalar value by which to change the height, for example
0.8 (to make them shorter) or 1.5 (to make them taller)
= OPTIONAL PARAMETERS:
- lock="c" Which part of the axis to keep fixed. "c", the default does
the changes around the middle; "b" means keep the bottom edge fixed
"t" means keep the top edge fixed
- ax = nothing If left as the default (nothing), works on the current axis;
otherwise should be an axis object to be modified.
"""
function axisHeightChange(factor; lock="c", ax=nothing)
if ax==nothing; ax=gca(); end
x, y, w, h = ax.get_position().bounds
if lock=="b";
elseif lock=="c" || lock=="m"; y = y + h*(1-factor)/2;
elseif lock=="t"; y = y + h*(1-factor);
else error("I don't know lock type ", lock)
end
h = h*factor;
ax.set_position([x, y, w, h])
return ax
end
"""
ax = axisMove(xd, yd; ax=nothing)
Move an axis within a figure.
= PARAMETERS:
- xd How much to move horizontally. Units are scaled figure units, from
0 to 1 (with 1 meaning the full width of the figure)
- yd How much to move vertically. Units are scaled figure units, from
0 to 1 (with 1 meaning the full height of the figure)
= OPTIONAL PARAMETERS:
- ax = nothing If left as the default (nothing), works on the current axis;
otherwise should be an axis object to be modified.
"""
function axisMove(xd, yd; ax=nothing)
if ax==nothing; ax=gca(); end
x, y, w, h = ax.get_position().bounds
x += xd
y += yd
ax.set_position([x, y, w, h])
return ax
end
"""
[] = remove_xtick_labels(ax=NaN)
Given an axis object, or an array of axes objects, replaces each xtick label
string with the empty string "".
If no axis is passed, uses gca() to work with the current axis.
"""
function remove_xtick_labels(ax=nothing)
if ax==nothing
ax = gca()
end
if typeof(ax) <: Array
for i=1:length(ax)
remove_xtick_labels(ax[i])
end
return
end
nlabels = length(ax.xaxis.get_ticklabels())
newlabels = Array{String,1}(nlabels)
for i=1:length(newlabels);
newlabels[i] = ""
end
ax.xaxis.set_ticklabels(newlabels)
return
end
"""
[] = remove_ytick_labels(ax=NaN)
Given an axis object, or an array of axes objects, replaces each ytick label
string with the empty string "".
If no axis is passed, uses gca() to work with the current axis.
"""
function remove_ytick_labels(ax=nothing)
if ax==nothing
ax = gca()
end
if typeof(ax) <: Array
for i=1:length(ax)
remove_ytick_labels(ax[i])
end
return
end
nlabels = length(ax.yaxis.get_ticklabels())
newlabels = Array{String,1}(nlabels)
for i=1:length(newlabels);
newlabels[i] = ""
end
ax.yaxis.set_ticklabels(newlabels)
return
end
using PyCall
"""
(x, y, w, h) = get_current_fig_position()
Returns the current figure's x, y, width and height position on the screen.
Works only when pygui(true) and when the back end is Tk or QT.
Has been tested only with PyPlot.
"""
function get_current_fig_position()
# if !contains(pystring(plt[:get_current_fig_manager]()), "FigureManagerQT")
try
if occursin("Tk", PyCall.pystring(PyPlot.get_current_fig_manager()))
g = split(plt.get_current_fig_manager().window.geometry(), ['x', '+'])
w = parse(Int64, g[1])
h = parse(Int64, g[2])
x = parse(Int64, g[3])
y = parse(Int64, g[4])
elseif occursin("QT", pystring(plt.get_current_fig_manager()))
x = PyPlot.get_current_fig_manager().window.pos().x()
y = PyPlot.get_current_fig_manager().window.pos().y()
w = PyPlot.get_current_fig_manager().window.width()
h = PyPlot.get_current_fig_manager().window.height()
else
error("Only know how to work with matplotlib graphics backends that are either Tk or QT")
end
return (x, y, w, h)
catch
error("Failed to get current figure position. Is pygui(false) or are you using a back end other than QT or Tk?")
end
end
"""
set_current_fig_position(x, y, w, h)
Sets the current figure's x, y, width and height position on the screen.
Works only when pygui(true) and when the back end is Tk or QT.
Has been tested only with PyPlot.
"""
function set_current_fig_position(x, y, w, h)
# if !contains(pystring(plt[:get_current_fig_manager]()), "FigureManagerQT")
try
if occursin("Tk", PyCall.pystring(PyPlot.get_current_fig_manager()))
PyPlot.get_current_fig_manager().window.geometry(@sprintf("%dx%d+%d+%d", w, h, x, y))
elseif occursin("QT", pystring(plt.get_current_fig_manager()))
PyPlot.get_current_fig_manager().window.setGeometry(x, y, w, h)
else
error("Only know how to work with matplotlib graphics backends that are either Tk or QT")
end
catch
error("Failed to set current figure position. Is pygui(false) or are you using a back end other than QT?")
end
end
"""
C = capture_current_figure_configuration()
Collects the positions of all current figures and
prints out to the screen code, that can be copy-pasted,
that would reproduce that positioning configuration.
# PARAMETERS:
None
# RETURNS:
- C A matrix that is nfigures-by-5 in size. You probably
don't want this, you probably want the text printed to
the screen, but here just in case. Each row will have,
in order: figure number, x, y, width, height
"""
function capture_current_figure_configuration()
@printf("The following code will reproduce your current figure placement:\n\n")
C = zeros(Int64, 0,5)
for f in sort(PyPlot.get_fignums())
figure(f)
x, y, w, h = get_current_fig_position()
@printf("figure(%d); set_current_fig_position(%d, %d, %d, %d) # x, y, width, height\n",
f, x, y, w, h)
C = [C ; [f x y w h]]
end
return C
end