@@ -14,13 +14,15 @@ def render_2d(params, result, exporter=None):
14
14
if pil_image is None :
15
15
return np .zeros ((10 , 10 ))
16
16
17
- pil_image = render_2d_arrows (params , result , pil_image , im_scale , aa_scale , display_image )
17
+ pil_image , disp_params = render_2d_arrows (params , result , pil_image , im_scale , aa_scale , display_image , return_scale = True )
18
18
19
19
if aa_scale == 2 :
20
20
pil_image = pil_image .resize ([pil_image .width // 2 , pil_image .height // 2 ])
21
21
aa_scale = 1
22
22
23
23
pil_image = render_2d_scalebar (params , result , pil_image , im_scale , aa_scale )
24
+ if disp_params != None :
25
+ pil_image = render_2d_colorbar (params , result , pil_image , im_scale , aa_scale , scale_max = disp_params ["scale_max" ], colormap = disp_params ["colormap" ])
24
26
25
27
pil_image = render_2d_time (params , result , pil_image )
26
28
@@ -76,16 +78,23 @@ def project_data(R, field, skip=1):
76
78
77
79
mesh , field , params_arrows , name = get_mesh_arrows (params , result )
78
80
81
+ if params_arrows is None :
82
+ scale_max = None
83
+ else :
84
+ scale_max = params_arrows ["scale_max" ] if not params_arrows ["autoscale" ] else None
85
+ colormap = params_arrows ["colormap" ]
86
+ skip = params_arrows ["skip" ]
87
+ alpha = params_arrows ["arrow_opacity" ]
88
+
79
89
if mesh is None :
80
90
if return_scale :
91
+ if scale_max is None :
92
+ return pil_image , None
93
+ else :
94
+ return pil_image , {"scale_max" : scale_max , "colormap" : colormap }
81
95
return pil_image , None
82
96
return pil_image
83
97
84
- scale_max = params_arrows ["scale_max" ] if not params_arrows ["autoscale" ] else None
85
- colormap = params_arrows ["colormap" ]
86
- skip = params_arrows ["skip" ]
87
- alpha = params_arrows ["arrow_opacity" ]
88
-
89
98
if field is not None :
90
99
# rescale and offset
91
100
scale = 1e6 / display_image [1 ][0 ]
@@ -133,7 +142,7 @@ def project_data(R, field, skip=1):
133
142
headlength = params ["2D_arrows" ]["headlength" ],
134
143
headheight = params ["2D_arrows" ]["headheight" ])
135
144
if return_scale :
136
- return pil_image , scale_max
145
+ return pil_image , { " scale_max" : scale_max , "colormap" : colormap }
137
146
return pil_image
138
147
139
148
@@ -166,6 +175,22 @@ def getBarParameters(pixtomu, scale=1):
166
175
size_in_um = mu , color = "w" , unit = "µm" )
167
176
return pil_image
168
177
178
+ def render_2d_colorbar (params , result , pil_image , im_scale , aa_scale , colormap = "viridis" , scale_max = 1 ):
179
+ pil_image = add_colorbar (pil_image , scale = 1 ,
180
+ colormap = colormap ,#params["colorbar"]["colorbar"],
181
+ #bar_width=params["colorbar"]["bar_width"] * aa_scale,
182
+ #bar_height=params["colorbar"]["bar_height"] * aa_scale,
183
+ #tick_height=params["colorbar"]["tick_height"] * aa_scale,
184
+ #tick_count=params["colorbar"]["tick_count"],
185
+ #min_v=params["scalebar"]["min_v"],
186
+ max_v = scale_max ,#params["colorbar"]["max_v"],
187
+ #offset_x=params["colorbar"]["offset_x"] * aa_scale,
188
+ #offset_y=params["colorbar"]["offset_y"] * aa_scale,
189
+ #fontsize=params["colorbar"]["fontsize"] * aa_scale,
190
+ )
191
+
192
+ return pil_image
193
+
169
194
170
195
def render_2d_time (params , result , pil_image ):
171
196
data = result .get_data_structure ()
@@ -245,6 +270,63 @@ def add_text(pil_image, text, position, fontsize=18):
245
270
image .text ((x , y ), text , color , font = font )
246
271
return pil_image
247
272
273
+ def add_colorbar (pil_image ,
274
+ colormap = "viridis" ,
275
+ bar_width = 150 ,
276
+ bar_height = 10 ,
277
+ tick_height = 5 ,
278
+ tick_count = 3 ,
279
+ min_v = 0 ,
280
+ max_v = 10 ,
281
+ offset_x = 15 ,
282
+ offset_y = - 10 ,
283
+ scale = 1 , fontsize = 16 , color = "w" ):
284
+ cmap = plt .get_cmap (colormap )
285
+ if offset_x < 0 :
286
+ offset_x = pil_image .size [0 ] + offset_x
287
+ if offset_y < 0 :
288
+ offset_y = pil_image .size [1 ] + offset_y
289
+
290
+ color = tuple ((matplotlib .colors .to_rgba_array (color )[0 , :3 ] * 255 ).astype ("uint8" ))
291
+ if pil_image .mode != "RGB" :
292
+ color = int (np .mean (color ))
293
+
294
+ colors = np .zeros ((bar_height , bar_width , 3 ), dtype = np .uint8 )
295
+ for i in range (bar_width ):
296
+ c = plt .get_cmap (cmap )(int (i / bar_width * 255 ))
297
+ colors [:, i , :] = [c [0 ] * 255 , c [1 ] * 255 , c [2 ] * 255 ]
298
+ pil_image .paste (Image .fromarray (colors ), (offset_x , offset_y - bar_height ))
299
+
300
+ image = ImageDraw .ImageDraw (pil_image )
301
+ import matplotlib .ticker as ticker
302
+
303
+ font_size = int (
304
+ round (fontsize * scale * 4 / 3 )) # the 4/3 appears to be a factor of "converting" screel dpi to image dpi
305
+ try :
306
+ font = ImageFont .truetype ("arial" , font_size ) # ImageFont.truetype("tahoma.ttf", font_size)
307
+ except IOError :
308
+ font = ImageFont .truetype ("times" , font_size )
309
+
310
+ locator = ticker .MaxNLocator (nbins = tick_count - 1 )
311
+ #tick_positions = locator.tick_values(min_v, max_v)
312
+ tick_positions = np .linspace (min_v , max_v , tick_count )
313
+ for i , pos in enumerate (tick_positions ):
314
+ x0 = offset_x + (bar_width - 2 ) / (tick_count - 1 ) * i
315
+ y0 = offset_y - bar_height - 1
316
+
317
+ image .rectangle ([x0 , y0 - 5 , x0 + 1 , y0 ])
318
+
319
+ text = "%d" % pos
320
+ length_number = image .textlength (text , font = font )
321
+ height_number = image .textbbox ((0 , 0 ), text , font = font )[3 ]
322
+
323
+ x = x0 - length_number * 0.5 + 1
324
+ y = y0 - height_number - tick_height - 3
325
+ # draw the text for the number and the unit
326
+ image .text ((x , y ), text , color , font = font )
327
+ #image.rectangle([pil_image.size[0]-10, 0, pil_image.size[0], 10], fill="w")
328
+ return pil_image
329
+
248
330
def add_scalebar (pil_image , scale , image_scale , width , xpos , ypos , fontsize , pixel_width , size_in_um , color = "w" , unit = "µm" ):
249
331
image = ImageDraw .ImageDraw (pil_image )
250
332
pixel_height = width
0 commit comments