2 Visualisation functions.
4 Each function has a detailed docstring.
11 import matplotlib.pyplot
as plt
12 import matplotlib.colors
14 import scipy.interpolate
20 def LIC2_sparse(u,v,points,grid_object,trace_length,kernel='anisotropic_linear',delta_t=3600.):
21 """!Line integral convolution with a sparse noise field. This produces discrete points that flow around the visualisation.
23 LIC is a method for visualising flow fields.
27 * kernel - the convolution kernel. Options are:
29 * 'anisotropic_linear'
37 output = LIC2_sparse(m.zonal_velocity['UVEL'][3,:,:],m.meridional_velocity['VVEL'][3,:,:],
38 5000,m.grid,15*86400,kernel='anisotropic_linear',delta_t=10*3600)
40 white_var_alpha = mitgcm.visualisation.create_cmap_vary_alpha(colour='k')
46 plt.pcolormesh(m.grid['X'][:],m.grid['Yp1'][:],m.meridional_velocity['VVEL'][level,:,:],cmap='winter',vmin=-1,vmax=1)
48 for i in xrange(output.shape[1]):
49 plt.scatter(output[0,i,:],output[1,i,:],
50 c=output[2,i,:],cmap=white_var_alpha,lw=0,vmin=0,vmax=1,s=4)
59 trace_length = float(trace_length)
60 delta_t = float(delta_t)
61 steps_per_trace = int(trace_length/delta_t)
64 if kernel ==
'anisotropic_linear':
65 k = np.ones(steps_per_trace)
66 for i
in xrange(steps_per_trace):
67 k[i] = 1 - float(i)/float(steps_per_trace-1)
74 noise = np.zeros(2*steps_per_trace)
75 noise[steps_per_trace] = 1
77 intensity = np.zeros((steps_per_trace))
78 for i
in xrange(steps_per_trace):
79 intensity[i] = np.sum(k*noise[i:steps_per_trace+i])
80 intensity = intensity/np.max(intensity)
84 k = np.ones(kernel_length)
89 noise = np.zeros(2*steps_per_trace)
90 noise[steps_per_trace] = 1
92 intensity = np.zeros((steps_per_trace))
93 for i
in xrange(steps_per_trace):
94 intensity[i] = np.sum(k*noise[i:steps_per_trace+i])
95 intensity = intensity/np.max(intensity)
98 raise ValueError(
'Valid options for kernel are: anisotropic_linear, box')
101 x_start = (np.random.random_sample(points)*(np.max(grid_object[
'Xp1'][:]) - np.min(grid_object[
'Xp1'][:])) +
102 np.min(grid_object[
'Xp1'][:]))
103 y_start = (np.random.random_sample(points)*(np.max(grid_object[
'Yp1'][:]) - np.min(grid_object[
'Yp1'][:])) +
104 np.min(grid_object[
'Yp1'][:]))
106 output = np.zeros((3,points,steps_per_trace))
108 for i
in xrange(points):
110 grid_object,trace_length,delta_t)
112 output[0,i,:steps_per_trace] = x_stream[:steps_per_trace]
113 output[1,i,:steps_per_trace] = y_stream[:steps_per_trace]
114 output[2,i,:steps_per_trace] = intensity[:steps_per_trace]
119 def LIC2_sparse_animate(u,v,nparticles,grid_object,animation_length,trace_length,kernel='anisotropic_linear',
121 """!Line integral convolution with a sparse noise field. The sparse noise field produces discrete points that travel around with the flow field.
123 This function produces data that can be used to animate a static flow field.
125 LIC is a method for visualising flow fields.
129 * output_matrix = [Variables (this axis has three values: x,y,intensity_ramp),trace_number ,time]
130 * intensity = vector containing the convolved kernel and noise field
135 * kernel - the convolution kernel. Options are:
136 * 'box' - same intensity for the entire trace
137 * 'anisotropic_linear' - intensity ramps up over the trace
144 output,intensity = LIC2_sparse_animate(m.zonal_velocity['UVEL'][1,:,:],
145 m.meridional_velocity['VVEL'][1,:,:],
148 kernel='anisotropic_linear',delta_t=4*3600)
149 white_var_alpha = mitgcm.visualisation.create_cmap_vary_alpha(colour='k')
155 trace_length= len(intensity)
157 for t0 in xrange(output.shape[2]-len(intensity)):
158 for i in xrange(output.shape[0]):
159 plt.scatter(output[i,0,t0:t0+trace_length],output[i,1,t0:t0+trace_length],
160 c = intensity,cmap='winter',lw=0,vmin=0,vmax=1,s=20)
162 filename = '../OLIC animation{:04g}.png'.format(t0)
163 plt.savefig(filename)
172 trace_length = float(trace_length)
173 kernel_length = float(trace_length/4)
174 delta_t = float(delta_t)
175 animation_length = float(animation_length)
176 steps_per_trace = int(trace_length/delta_t)
177 steps_per_kernel = int(kernel_length/delta_t)
178 steps_per_ani = int(animation_length/delta_t)
181 if kernel ==
'anisotropic_linear':
182 k = np.ones(steps_per_kernel)
183 for i
in xrange(steps_per_kernel):
184 k[i] = 1 - float(i)/float(steps_per_kernel-1)
185 k[:int(steps_per_kernel/2.)] = 0
191 noise = np.zeros(steps_per_ani)
192 noise[steps_per_kernel] = 1
194 intensity = np.zeros((steps_per_ani))
195 for i
in xrange(steps_per_ani - steps_per_kernel):
196 intensity[i] = np.sum(k*noise[i:steps_per_kernel+i])
197 intensity = intensity/np.max(intensity)
200 elif kernel ==
'box':
201 k = np.ones(kernel_length)
206 noise = np.zeros((steps_per_trace))
207 noise[int(len(noise)/2)] = 1
209 intensity = np.zeros((steps_per_ani))
210 for i
in xrange(kernel_length):
211 intensity[i] = np.sum(k*noise[i:kernel_length+i])
212 intensity = intensity/np.max(intensity)
215 raise ValueError(
'Valid options for kernel are: anisotropic_linear, box')
220 output = np.zeros((nparticles,2,steps_per_ani))
223 x_start = (np.random.random_sample(nparticles)*(np.max(grid_object[
'Xp1'][:]) - np.min(grid_object[
'Xp1'][:])) +
224 np.min(grid_object[
'Xp1'][:]))
225 y_start = (np.random.random_sample(nparticles)*(np.max(grid_object[
'Yp1'][:]) - np.min(grid_object[
'Yp1'][:])) +
226 np.min(grid_object[
'Yp1'][:]))
228 for i
in xrange(nparticles):
232 grid_object,trace_length,delta_t)
235 output[i,0,:steps_per_trace] = x_stream[:steps_per_trace]
236 output[i,1,:steps_per_trace] = y_stream[:steps_per_trace]
241 x_start = (np.random.random_sample(nparticles)*(np.max(grid_object[
'Xp1'][:]) - np.min(grid_object[
'Xp1'][:])) +
242 np.min(grid_object[
'Xp1'][:]))
243 y_start = (np.random.random_sample(nparticles)*(np.max(grid_object[
'Yp1'][:]) - np.min(grid_object[
'Yp1'][:])) +
244 np.min(grid_object[
'Yp1'][:]))
245 for i
in xrange(nparticles):
248 grid_object,trace_length,delta_t)
250 t0 = int(np.random.random_sample(1)*(steps_per_trace))
253 output[i,0,t0:t0+steps_per_trace] = x_stream[:steps_per_trace]
254 output[i,1,t0:t0+steps_per_trace] = y_stream[:steps_per_trace]
261 for n
in xrange(nparticles):
263 for trace
in xrange(int(np.floor(animation_length/trace_length)-2)):
265 indices = np.where(output[n,0,:]==output[n,1,:])
266 t_ind = indices[0][0]
268 if t_ind+steps_per_trace < steps_per_ani:
270 x_start = (np.random.random_sample(1)*(np.max(grid_object[
'Xp1'][:]) - np.min(grid_object[
'Xp1'][:])) +
271 np.min(grid_object[
'Xp1'][:]))
272 y_start = (np.random.random_sample(1)*(np.max(grid_object[
'Yp1'][:]) - np.min(grid_object[
'Yp1'][:])) +
273 np.min(grid_object[
'Yp1'][:]))
276 grid_object,trace_length,delta_t)
278 output[n,0,t_ind:t_ind+steps_per_trace] = x_stream[:steps_per_trace]
279 output[n,1,t_ind:t_ind+steps_per_trace] = y_stream[:steps_per_trace]
282 return output,intensity[:int(steps_per_kernel/2.)]
286 """!Create a colour map with variable alpha. This can be used to sketch out particles as they move.
288 The only input variable 'coour' defines the colour that is used to create the colour map. It can be any colour code that matplotlib recognises: single letter codes, hex colour string, a standard colour name, or a string representation of a float (e.g. '0.4') for gray on a 0-1 scale."""
290 rgb = matplotlib.colors.colorConverter.to_rgb(colour)
293 newCM = copy.deepcopy(plt.cm.get_cmap(
'bone_r'))
296 alphas = np.abs(np.linspace(0, 1.0, newCM.N))
297 newCM._lut[:-3,-1] = alphas
298 newCM._lut[:,0] = rgb[0]
299 newCM._lut[:,1] = rgb[1]
300 newCM._lut[:,2] = rgb[2]
def LIC2_sparse
Line integral convolution with a sparse noise field.
def create_cmap_vary_alpha
Create a colour map with variable alpha.
def LIC2_sparse_animate
Line integral convolution with a sparse noise field.
def stream2
A two-dimensional streamline solver.