def add_to_array(arr, area, time, bufr, savedir='/tmp', name=None, mode='L', resize=None, ptsize=None, save=False): """Add synoptical reports from stations to provided geolocated image array """ # Create array image arrshp = arr.shape[:2] print(np.nanmin(arr), np.nanmax(arr)) arr_img = Image(arr, mode=mode) # arr_img = Image(channels=[arr[:, :, 0], arr[:, :, 1], arr[:, :, 2]], # mode='RGB') arr_img.stretch('crude') arr_img.invert() arr_img.colorize(maskcol) arr_img.invert() # Import bufr stations = read_synop(bufr, 'visibility') currentstations = stations[time.strftime("%Y%m%d%H0000")] lats = [i[2] for i in currentstations] lons = [i[3] for i in currentstations] vis = [i[4] for i in currentstations] # Create array for synop parameter visarr = np.empty(arrshp) visarr.fill(np.nan) x, y = (area.get_xy_from_lonlat(lons, lats)) vis_ma = np.ma.array(vis, mask=x.mask) if ptsize: xpt = np.array([]) ypt = np.array([]) for i, j in zip(x, y): xmesh, ymesh = np.meshgrid(np.linspace(i - ptsize, i + ptsize, ptsize * 2 + 1), np.linspace(j - ptsize, j + ptsize, ptsize * 2 + 1)) xpt = np.append(xpt, xmesh.ravel()) ypt = np.append(ypt, ymesh.ravel()) vispt = np.ma.array([np.full(((ptsize * 2 + 1, ptsize * 2 + 1)), p) for p in vis_ma]) visarr[ypt.astype(int), xpt.astype(int)] = vispt.ravel() else: visarr[y.compressed(), x.compressed()] = vis_ma.compressed() visarr_ma = np.ma.masked_invalid(visarr) station_img = Image(visarr_ma, mode='L') station_img.colorize(vis_colset) station_img.merge(arr_img) if resize is not None: station_img.resize((arrshp[0] * resize, arrshp[1] * resize)) if name is None: timestr = time.strftime("%Y%m%d%H%M") name = "fog_filter_example_stations_{}.png".format(timestr) if save: savepath = os.path.join(savedir, name) station_img.save(savepath) return(station_img)
def plot(data, text, minmax=None, transpose=False, filename=None, position=(-16.743860721,64.915348712,712.4), tilt=None, target_position=None, target_name="", vfov=18.5, tick_distance=50.0): if transpose: data = data.transpose() if minmax is None: rainbow.set_range(data.min(),data.max()) else: rainbow.set_range(minmax[0],minmax[1]) img = Image(data, mode="L") img.colorize(rainbow) img = img.pil_image() # Decoration dc = DecoratorAGG(img) dc.align_bottom() #dc.add_logo("/home/sat/dev/pydecorate/logos/VI_Logo_Transp.png") #dc.add_logo("Nicarnica-Aviation-22-oct-300x102.png") try: dc.add_logo("/home/master/bin/futurevolc_logo.png", height=47) dc.add_logo("/home/master/bin/nicarnica_logo.png") dc.add_logo("/home/master/bin/vi_logo.png") except IOError: dc.add_logo("bin/futurevolc_logo.png", height=47) dc.add_logo("bin/nicarnica_logo.png") dc.add_logo("bin/vi_logo.png") dc.add_text(text, font=font) tick_space = 5.0 #dc.add_scale(rainbow, extend=True, unit='°C', tick_marks=tick_space, minor_tick_marks=tick_space) # target distance and km/px ny = data.shape[0] nx = data.shape[1] distance = distance_longlat(target_position,position) # plot grid lines, texts = prepare_graticule(nx, ny, distance=distance, vfov=vfov, tilt=tilt, tick_distance=tick_distance, height=position[2],target_height=target_position[2], target_name=target_name) draw_lines(img, lines) draw_texts(img, texts) if filename == None: img.show() else: img.save(filename, "JPEG", quality=90)
def _create_colorbar_image( colormap, minval, maxval, scale_height, scale_width, is_vertical ): if TImage is None: raise ImportError( "Missing 'trollimage' dependency. Required colorbar creation." ) if is_vertical: linedata = np.ones((scale_width, 1)) * np.arange( minval, maxval, float(maxval - minval) / scale_height ) linedata = linedata.transpose() else: linedata = np.ones((scale_height, 1)) * np.arange( minval, maxval, float(maxval - minval) / scale_width ) timg = TImage(linedata, mode="L") timg.colorize(colormap) return timg.pil_image()
def _add_scale(self, colormap, title=None, **kwargs): # synchronize kwargs into style self.set_style(**kwargs) # sizes, current xy and margins x = self.style['cursor'][0] y = self.style['cursor'][1] mx = self.style['margins'][0] my = self.style['margins'][1] x_size, y_size = self.image.size # horizontal/vertical? is_vertical = False if self.style['propagation'][1] != 0: is_vertical = True # left/right? is_right = False if self.style['alignment'][0] == 1.0: is_right = True # top/bottom? is_bottom = False if self.style['alignment'][1] == 1.0: is_bottom = True # adjust new size based on extend (fill space) style, if self.style['extend']: if self.style['propagation'][0] == 1: self.style['width'] = (x_size - x) elif self.style['propagation'][0] == -1: self.style['width'] = x if self.style['propagation'][1] == 1: self.style['height'] = (y_size - y) elif self.style['propagation'][1] == -1: self.style['height'] = y # set scale spacer for units and other x_spacer = 0 y_spacer = 0 if self.style['unit']: if is_vertical: y_spacer = 40 else: x_spacer = 40 # draw object draw = self._get_canvas(self.image) # draw base px = (self.style['propagation'][0] + self.style['newline_propagation'][0]) py = (self.style['propagation'][1] + self.style['newline_propagation'][1]) x1 = x + px * self.style['width'] y1 = y + py * self.style['height'] self._draw_rectangle(draw, [x, y, x1, y1], **self.style) # scale dimensions scale_width = self.style['width'] - 2 * mx - x_spacer scale_height = self.style['height'] - 2 * my - y_spacer # generate color scale image obj inset by margin size mx my, from trollimage.image import Image as TImage #### THIS PART TO BE INGESTED INTO A COLORMAP FUNCTION #### minval, maxval = colormap.values[0], colormap.values[-1] if is_vertical: linedata = np.ones((scale_width, 1)) * np.arange( minval, maxval, float(maxval - minval) / scale_height) linedata = linedata.transpose() else: linedata = np.ones((scale_height, 1)) * np.arange( minval, maxval, float(maxval - minval) / scale_width) timg = TImage(linedata, mode="L") timg.colorize(colormap) scale = timg.pil_image() ########################################################### # finalize (must be before paste) self._finalize(draw) # paste scale onto image pos = (min(x, x1) + mx, min(y, y1) + my) self.image.paste(scale, pos) # reload draw object draw = self._get_canvas(self.image) # draw tick marks val_steps = _round_arange2(minval, maxval, self.style['tick_marks']) minor_steps = _round_arange(minval, maxval, self.style['minor_tick_marks']) ffra, fpow = _optimize_scale_numbers(minval, maxval, self.style['tick_marks']) form = "%" + "." + str(ffra) + "f" last_x = x + px * mx last_y = y + py * my ref_w, ref_h = self._draw_text(draw, (0, 0), form % (val_steps[0]), dry_run=True, **self.style) if is_vertical: # major offset_start = val_steps[0] - minval offset_end = val_steps[-1] - maxval y_steps = py * (val_steps - minval - offset_start - offset_end ) * scale_height / (maxval - minval) + y + py * my y_steps = y_steps[::-1] for i, ys in enumerate(y_steps): self._draw_line(draw, [(x + px * mx, ys), (x + px * (mx + scale_width / 3.0), ys)], **self.style) if abs(ys - last_y) > ref_h: self._draw_text( draw, (x + px * (mx + 2 * scale_width / 3.0), ys), (form % (val_steps[i])).strip(), **self.style) last_y = ys # minor y_steps = py * (minor_steps - minval) * \ scale_height / (maxval - minval) + y + py * my y_steps = y_steps[::-1] for i, ys in enumerate(y_steps): self._draw_line(draw, [(x + px * mx, ys), (x + px * (mx + scale_width / 6.0), ys)], **self.style) else: # major x_steps = px * (val_steps - minval) * \ scale_width / (maxval - minval) + x + px * mx for i, xs in enumerate(x_steps): self._draw_line(draw, [(xs, y + py * my), (xs, y + py * (my + scale_height / 3.0))], **self.style) if abs(xs - last_x) > ref_w: self._draw_text( draw, (xs, y + py * (my + 2 * scale_height / 3.0)), (form % (val_steps[i])).strip(), **self.style) last_x = xs # minor x_steps = px * (minor_steps - minval) * \ scale_width / (maxval - minval) + x + px * mx for i, xs in enumerate(x_steps): self._draw_line(draw, [(xs, y + py * my), (xs, y + py * (my + scale_height / 6.0))], **self.style) # draw unit and/or power if set if self.style['unit']: # calculate position if is_vertical: if is_right: x_ = x - mx - scale_width / 2.0 else: x_ = x + mx + scale_width / 2.0 y_ = y + my + scale_height + y_spacer / 2.0 else: x_ = x + mx + scale_width + x_spacer / 2.0 if is_bottom: y_ = y - my - scale_height / 2.0 else: y_ = y + my + scale_height / 2.0 # draw marking self._draw_text(draw, (x_, y_), self.style['unit'], **self.style) if title: # calculate position tw, th = draw.textsize(title, self.style['font']) if is_vertical: # TODO: Rotate the text? if is_right: x = x - mx - scale_width - tw else: x = x + mx + scale_width + tw y = y + my + scale_height / 2.0 else: x = x + mx + scale_width / 2.0 if is_bottom: y = y - my - scale_height - th else: y = y + my + scale_height + th self._draw_text(draw, (x, y), title, **self.style) # finalize self._finalize(draw)
imgarr = np.array(local_scene["IR_108"].data) imgarr = gaussian_filter(imgarr, sigma=1) img = Timage(imgarr, mode="L") #black = greys #black.colors[0] = np.array([0.,0.,0.]) #black.set_range(-40 + 273.15, 30 + 273.15) greys.set_range(-30 + 273.15, 30 + 273.15) #spectral.set_range(-90 + 273.15, -40.00001 + 273.15) #my_cm = spectral + greys setvak = cmap_from_text("setvak_rev.rgb", norm=True) setvak_new = setvak.colors[:,:3] setvak.colors = setvak_new setvak.set_range(-73 + 273.15, -30.00001 + 273.15) my_cm = setvak + greys img.colorize(my_cm) tmpFile = "/tmp/colir.png" img.save(tmpFile) outputFile = "/var/tmp/cll/out/PY_colir-ch_"+yearS+monthS+dayS+hourS+minS+".png" #background = Image.open(bgFile) foreground = Image.open(tmpFile) #background = background.convert("RGBA") #img_enhancer = ImageEnhance.Brightness(foreground) #imgN = img_enhancer.enhance(1.5) #foreground.putalpha(imgN.convert('L')) foreground = foreground.convert("RGBA") foreground.save(tmpFile)
def add_to_image(image, area, time, bufr, savedir='/tmp', name=None, bgimg=None, resize=None, ptsize=None, save=False): """Add synoptical visibility reports from station data to provided geolocated image array """ arrshp = image.shape[:2] # Add optional background image if bgimg is not None: # Get background image bg_img = Image(bgimg.squeeze(), mode='L', fill_value=None) bg_img.stretch("crude") bg_img.convert("RGB") # bg_img.invert() image.merge(bg_img) # Import bufr stations = read_synop(bufr, 'visibility') currentstations = stations[time.strftime("%Y%m%d%H0000")] lats = [i[2] for i in currentstations] lons = [i[3] for i in currentstations] vis = [i[4] for i in currentstations] # Create array for synop parameter visarr = np.empty(arrshp) visarr.fill(np.nan) # Red - Violet - Blue - Green vis_colset = Colormap((0, (228 / 255.0, 26 / 255.0, 28 / 255.0)), (1000, (152 / 255.0, 78 / 255.0, 163 / 255.0)), (5000, (55 / 255.0, 126 / 255.0, 184 / 255.0)), (10000, (77 / 255.0, 175 / 255.0, 74 / 255.0))) x, y = (area.get_xy_from_lonlat(lons, lats)) vis_ma = np.ma.array(vis, mask=x.mask) if ptsize: xpt = np.array([]) ypt = np.array([]) for i, j in zip(x, y): xmesh, ymesh = np.meshgrid( np.linspace(i - ptsize, i + ptsize, ptsize * 2 + 1), np.linspace(j - ptsize, j + ptsize, ptsize * 2 + 1)) xpt = np.append(xpt, xmesh.ravel()) ypt = np.append(ypt, ymesh.ravel()) vispt = np.ma.array( [np.full(((ptsize * 2 + 1, ptsize * 2 + 1)), p) for p in vis_ma]) visarr[ypt.astype(int), xpt.astype(int)] = vispt.ravel() else: visarr[y.compressed(), x.compressed()] = vis_ma.compressed() visarr_ma = np.ma.masked_invalid(visarr) station_img = Image(visarr_ma, mode='L') station_img.colorize(vis_colset) image.convert("RGB") station_img.merge(image) if resize is not None: station_img.resize((arrshp[0] * resize, arrshp[1] * resize)) if name is None: timestr = time.strftime("%Y%m%d%H%M") name = "fog_filter_example_stations_{}.png".format(timestr) if save: savepath = os.path.join(savedir, name) station_img.save(savepath) return (station_img)
if save_black_white_png: local_scene.save_dataset('lscl', './lscl_' + area + '.png') print(dir(local_scene.save_dataset)) print('display ./lscl_' + area + '.png &') # save png file for SATLive ############################## if area == "cosmo1x150" or area == "cosmo1": png_file = start_time.strftime('/data/cinesat/out/MSG_lscl-' + area + '_%y%m%d%H%M.png') from trollimage.colormap import spectral, greys, ylorrd, rdgy imgarr = np.array(local_scene['lscl'].data) from trollimage.image import Image as Timage img = Timage(imgarr, mode="L") img.colorize(rdgy.reverse()) img.save(png_file) # local_scene.save_dataset( 'lscl', png_file ) from pyresample.utils import load_area swiss = load_area("/opt/users/hau/monti-pytroll/etc/areas.def", area) from pycoast import ContourWriterAGG cw = ContourWriterAGG('/opt/users/common/shapes') cw.add_borders_to_file(png_file, swiss, outline="green", resolution='i', level=3, width=2)
#bgimg = germ_scene[10.8].as_image() bgimg = germ_scene.image.ir108() fls_img, fogmask = germ_scene.image.fls_day(elevation_ger.image_data, cot_ger.image_data, reff_ger.image_data, cwp_ger.image_data) snow_rgb = germ_scene.image.snow() daymicro_rgb = germ_scene.image.day_microphysics() overview = germ_scene.image.overview() # Merge masked and colorized fog clouds with backgrund infrared image bgimg.convert("RGB") fls_img = Image(fls_img.channels[0], mode='L') fls_img.colorize(fogcol) fls_img.merge(bgimg) ele_img = Image(ele_img.channels[0], mode='L') #cwp_img = Image(cwp_img.channels[0], mode='L') #cwp_masked = np.ma.array(cwp_ger.image_data, mask=fogmask) #print(np.histogram(cwp_masked.compressed())) #ele_img.show() #cwp_img.show() #overview.show() #fls_img.show() #snow_rgb.show() #daymicro_rgb.show() ele_img.save("/tmp/fog_example_msg_ger_elevation_{}.png".format( time.strftime("%Y%m%d%H%M"))) cot_img.save("/tmp/fog_example_msg_ger_cot_{}.png".format(
def _add_scale(self, colormap, title=None, **kwargs): # synchronize kwargs into style self.set_style(**kwargs) # sizes, current xy and margins x = self.style['cursor'][0] y = self.style['cursor'][1] mx = self.style['margins'][0] my = self.style['margins'][1] x_size, y_size = self.image.size # horizontal/vertical? is_vertical = False if self.style['propagation'][1] != 0: is_vertical = True # left/right? is_right = False if self.style['alignment'][0] == 1.0: is_right = True # top/bottom? is_bottom = False if self.style['alignment'][1] == 1.0: is_bottom = True # adjust new size based on extend (fill space) style, if self.style['extend']: if self.style['propagation'][0] == 1: self.style['width'] = (x_size - x) elif self.style['propagation'][0] == -1: self.style['width'] = x if self.style['propagation'][1] == 1: self.style['height'] = (y_size - y) elif self.style['propagation'][1] == -1: self.style['height'] = y # set scale spacer for units and other x_spacer = 0 y_spacer = 0 if self.style['unit']: if is_vertical: y_spacer = 40 else: x_spacer = 40 # draw object draw = self._get_canvas(self.image) # draw base px = (self.style['propagation'][0] + self.style['newline_propagation'][0]) py = (self.style['propagation'][1] + self.style['newline_propagation'][1]) x1 = x + px * self.style['width'] y1 = y + py * self.style['height'] self._draw_rectangle(draw, [x, y, x1, y1], **self.style) # scale dimensions scale_width = self.style['width'] - 2 * mx - x_spacer scale_height = self.style['height'] - 2 * my - y_spacer # generate color scale image obj inset by margin size mx my, from trollimage.image import Image as TImage #### THIS PART TO BE INGESTED INTO A COLORMAP FUNCTION #### minval, maxval = colormap.values[0], colormap.values[-1] if is_vertical: linedata = np.ones( (scale_width, 1)) * np.arange(minval, maxval, float(maxval - minval) / scale_height) linedata = linedata.transpose() else: linedata = np.ones( (scale_height, 1)) * np.arange(minval, maxval, float(maxval - minval) / scale_width) timg = TImage(linedata, mode="L") timg.colorize(colormap) scale = timg.pil_image() ########################################################### # finalize (must be before paste) self._finalize(draw) # paste scale onto image pos = (min(x, x1) + mx, min(y, y1) + my) self.image.paste(scale, pos) # reload draw object draw = self._get_canvas(self.image) # draw tick marks val_steps = _round_arange2(minval, maxval, self.style['tick_marks']) minor_steps = _round_arange( minval, maxval, self.style['minor_tick_marks']) ffra, fpow = _optimize_scale_numbers( minval, maxval, self.style['tick_marks']) form = "%" + "." + str(ffra) + "f" last_x = x + px * mx last_y = y + py * my ref_w, ref_h = self._draw_text( draw, (0, 0), form % (val_steps[0]), dry_run=True, **self.style) if is_vertical: # major offset_start = val_steps[0] - minval offset_end = val_steps[-1] - maxval y_steps = py * (val_steps - minval - offset_start - offset_end) * scale_height / (maxval - minval) + y + py * my y_steps = y_steps[::-1] for i, ys in enumerate(y_steps): self._draw_line( draw, [(x + px * mx, ys), (x + px * (mx + scale_width / 3.0), ys)], **self.style) if abs(ys - last_y) > ref_h: self._draw_text( draw, (x + px * (mx + 2 * scale_width / 3.0), ys), (form % (val_steps[i])).strip(), **self.style) last_y = ys # minor y_steps = py * (minor_steps - minval) * \ scale_height / (maxval - minval) + y + py * my y_steps = y_steps[::-1] for i, ys in enumerate(y_steps): self._draw_line( draw, [(x + px * mx, ys), (x + px * (mx + scale_width / 6.0), ys)], **self.style) else: # major x_steps = px * (val_steps - minval) * \ scale_width / (maxval - minval) + x + px * mx for i, xs in enumerate(x_steps): self._draw_line( draw, [(xs, y + py * my), (xs, y + py * (my + scale_height / 3.0))], **self.style) if abs(xs - last_x) > ref_w: self._draw_text( draw, (xs, y + py * (my + 2 * scale_height / 3.0)), (form % (val_steps[i])).strip(), **self.style) last_x = xs # minor x_steps = px * (minor_steps - minval) * \ scale_width / (maxval - minval) + x + px * mx for i, xs in enumerate(x_steps): self._draw_line( draw, [(xs, y + py * my), (xs, y + py * (my + scale_height / 6.0))], **self.style) # draw unit and/or power if set if self.style['unit']: # calculate position if is_vertical: if is_right: x_ = x - mx - scale_width / 2.0 else: x_ = x + mx + scale_width / 2.0 y_ = y + my + scale_height + y_spacer / 2.0 else: x_ = x + mx + scale_width + x_spacer / 2.0 if is_bottom: y_ = y - my - scale_height / 2.0 else: y_ = y + my + scale_height / 2.0 # draw marking self._draw_text(draw, (x_, y_), self.style['unit'], **self.style) if title: # calculate position tw, th = draw.textsize(title, self.style['font']) if is_vertical: # TODO: Rotate the text? if is_right: x = x - mx - scale_width - tw else: x = x + mx + scale_width + tw y = y + my + scale_height / 2.0 else: x = x + mx + scale_width / 2.0 if is_bottom: y = y - my - scale_height - th else: y = y + my + scale_height + th self._draw_text(draw, (x, y), title, **self.style) # finalize self._finalize(draw)
def _add_scale(self, colormap, **kwargs): # synchronize kwargs into style self.set_style(**kwargs) gamma = kwargs.get('gamma', 1.0) # sizes, current xy and margins x=self.style['cursor'][0] y=self.style['cursor'][1] mx=self.style['margins'][0] my=self.style['margins'][1] x_size,y_size = self.image.size #print('Cursor', x, y) # horizontal/vertical? is_vertical = False if self.style['propagation'][1] != 0: is_vertical = True # left/right? is_right = False if self.style['alignment'][0] == 1.0: is_right = True # top/bottom? is_bottom = False if self.style['alignment'][1] == 1.0: is_bottom = True #print('ISBOTTO: '+is_bottom) # adjust new size based on extend (fill space) style, if self.style['extend']: if self.style['propagation'][0] == 1: self.style['width'] = (x_size - x) elif self.style['propagation'][0] == -1: self.style['width'] = x if self.style['propagation'][1] == 1: self.style['height'] = (y_size - y) elif self.style['propagation'][1] == -1: self.style['height'] = y # set scale spacer for units and other x_spacer = 0 y_spacer = 0 if self.style['unit']: if is_vertical: y_spacer = 40 else: x_spacer = 40 # draw object draw = self._get_canvas(self.image) # draw base px = (self.style['propagation'][0] + self.style['newline_propagation'][0]) py = (self.style['propagation'][1] + self.style['newline_propagation'][1]) x1 = x + px*self.style['width'] y1 = y + py*self.style['height'] self._draw_rectangle(draw,[x,y,x1,y1],**self.style) # scale dimensions scale_width = self.style['width'] - 2*mx - x_spacer scale_height = self.style['height'] - 2*my - y_spacer # generate color scale image obj inset by margin size mx my, from trollimage.image import Image as TImage #### THIS PART TO BE INGESTED INTO A COLORMAP FUNCTION #### minval,maxval = colormap.values[0],colormap.values[-1] if is_vertical: #linedata = np.ones((scale_width/2.0,1)) * np.arange(minval,maxval,(maxval-minval)/scale_height) #linedata = np.ones((scale_width/2.0,1))**gamma *np.linspace(minval, maxval, scale_width) linedata = np.ones((scale_width/2,1))*(np.linspace(0,1,scale_height)**(1.0 / gamma) *(maxval-minval)+minval) linedata = linedata.transpose() else: #linedata = np.ones((scale_height/2.0,1)) * np.arange(minval,maxval,(maxval-minval)/scale_width) #linedata = np.ones((scale_height/2.0,1))**gamma *np.linspace(minval, maxval, scale_width) linedata = np.ones((scale_height/2,1))*(np.linspace(0,1,scale_width)**(1.0 / gamma) *(maxval-minval)+minval) timg = TImage(linedata,mode="L") print(kwargs.get('palettize')) if kwargs.get('palettize', False): timg.palettize(colormap) else: timg.colorize(colormap) scale = timg.pil_image() ########################################################### # finalize (must be before paste) self._finalize(draw) # paste scale onto image pos =(min(x,x1)+mx,min(y,y1)+my) self.image.paste(scale,pos) # reload draw object draw = self._get_canvas(self.image) # draw tick marks val_steps = _round_arange2( minval, maxval , self.style['tick_marks'] ) minor_steps = _round_arange( minval, maxval , self.style['minor_tick_marks'] ) ffra, fpow = _optimize_scale_numbers( minval, maxval, self.style['tick_marks'] ) form = "%"+"."+str(ffra)+"f" last_x = x+px*mx last_y = y+py*my ref_w, ref_h = self._draw_text(draw, (0,0), form%(val_steps[0]), dry_run=True, **self.style) #tick_length=10 tick_length=round(scale_height*0.20) #print('scale_height: '+str(scale_height)) if is_vertical: # major offset_start = val_steps[0] - minval offset_end = val_steps[-1] - maxval y_steps = py*(val_steps - minval - offset_start - offset_end)*scale_height/(maxval-minval)+y+py*my y_steps = y_steps[::-1] for i, ys in enumerate(y_steps): self._draw_line(draw,[(x+px*mx,ys),(x+px*(mx+scale_width/3.0),ys)],**self.style) if abs(ys-last_y)>ref_h: self._draw_text(draw,(x+px*(mx+2*scale_width/3.0),ys), (form%(val_steps[i])).strip(), **self.style) last_y = ys # minor y_steps = py*(minor_steps - minval)*scale_height/(maxval-minval)+y+py*my y_steps = y_steps[::-1] for i, ys in enumerate(y_steps): self._draw_line(draw,[(x+px*mx,ys),(x+px*(mx+scale_width/6.0),ys)],**self.style) else: # major x_steps = px*(val_steps - minval)*scale_width/(maxval-minval)+x+px*mx #print(x_steps) #print(y, py,(my+2*scale_height/3.0)) for i, xs in enumerate(x_steps): #self._draw_line(draw,[(xs,y+py*my+scale_height/2.0-tick_length/2.0),(xs,y+py*(my+scale_height/2.0+tick_length/2.0))],**self.style) self._draw_line(draw,[(xs,y+py*(my+scale_height/2.0-tick_length/2.0)),(xs,y+py*(my+scale_height/2.0+tick_length/2.0))],**self.style) #print(abs(xs-last_x),xs,last_x, ref_w) #print((form%(val_steps[i])).strip()) if abs(xs-last_x)>ref_w or xs==last_x: center_y=y+py*(my+scale_height/2.0) font_height=self.style['font'].getmetrics()[0] #self._draw_text(draw,(xs, y+py*(my+2*scale_height/3.0)), (form%(val_steps[i])).strip(), **self.style) self._draw_text(draw,(xs, center_y+tick_length/2.0+font_height/2.0), (form%(val_steps[i])).strip(), **self.style) last_x = xs # minor x_steps = px*(minor_steps - minval)*scale_width/(maxval-minval)+x+px*mx for i, xs in enumerate(x_steps): self._draw_line(draw,[(xs,y+py*(my+scale_height/2.0-tick_length/4.0)),(xs,y+py*(my+scale_height/2.0+tick_length/4.0))],**self.style) # self._draw_line(draw,[(xs,y+py*my),(xs,y+py*(my+scale_height/6.0))],**self.style) # draw unit and/or power if set if self.style['unit']: # calculate position if is_vertical: if is_right: x = x - mx - scale_width/2.0 else: x = x + mx + scale_width/2.0 y = y + my + scale_height + y_spacer/2.0 else: x = x + mx + scale_width + x_spacer/2.0 if is_bottom: y = y - my - scale_height/2.0 else: y = y + my + scale_height/2.0 # draw marking self._draw_text(draw,(x,y),self.style['unit'],**self.style) # finalize self._finalize(draw)