def plot_image(f, img_path, cell_x0, cell_x1, cell_y0, ax, text_y_dist, text, text_pos, fontsize, zoom=0.2, cell_y1=np.nan): """ This function plots images and corresponding text of the task schematic :param f: Figure object :param img_path: Path of image :param cell_x0: Left x-position of area in which it is plotted centrally :param cell_x1: Rigth x-position of area in which it is plotted centrally :param cell_y0: Lower y-position of image -- if cell_y1 = nan :param ax: Plot axis :param text_y_dist: y-position distance to image :param text: Displayed text :param text_pos: Position of printed text (below vs. above) :param fontsize: Text font size :param zoom: Scale of image :param cell_y1: Upper x-position of area in which image is plotted (lower corresponds to cell_y0) :return ax, bbox: Axis object, image coordinates """ # Open image img = Image.open(img_path) # Image zoom factor and axis and coordinates imagebox = OffsetImage(img, zoom=zoom) imagebox.image.axes = ax ab = AnnotationBbox(imagebox, (cell_x0, cell_y0), xybox=None, xycoords='data', boxcoords="offset points", pad=0, frameon=False) ax.add_artist(ab) # Get cell width cell_width = cell_x1 - cell_x0 image_x = cell_x0 + (cell_width / 2) if not np.isnan(cell_y1): cell_height = cell_y1 - cell_y0 image_y = cell_y0 + (cell_height / 2) else: image_y = cell_y0 # Remove image and re-plot at correct coordinates ab.remove() ab = AnnotationBbox(imagebox, (image_x, image_y), xybox=None, xycoords='data', boxcoords="offset points", pad=0, frameon=False) ax.add_artist(ab) # Get image coordinates f.canvas.draw() renderer = f.canvas.renderer # bbox = imagebox.get_window_extent(renderer).inverse_transformed(ax.transAxes) bbox = imagebox.get_window_extent(renderer).inverse_transformed( ax.transData) if text_pos == 'left_below': # Plot text below image x = bbox.x0 y = bbox.y0 - text_y_dist elif text_pos == 'centered_below': # Plot text centrally above image word_length, _, _ = get_text_coords(f, ax, bbox.x0, bbox.y0, text, 6) cell_width = bbox.x1 - bbox.x0 x = center_x(bbox.x0, cell_width, word_length) y = bbox.y0 - text_y_dist else: # Plot text centrally above image word_length, _, _ = get_text_coords(f, ax, bbox.x0, bbox.y0, text, 6) cell_width = bbox.x1 - bbox.x0 x = center_x(bbox.x0, cell_width, word_length, correct_for_length=True) y = bbox.y1 + text_y_dist ax.text(x, y, text, fontsize=fontsize, color='k') return ax, bbox
')\n\nInternational Space Station live Location at ' + time.ctime(t)) # annonating iss icon ab = AnnotationBbox(im, pt, xycoords='data', frameon=False) ax.add_artist(ab) # annonating lngitude and latitude tx = TextArea( f"({append_deg(pt[0], 'W', 'E')}, {append_deg(pt[1], 'S', 'N')})") ab2 = AnnotationBbox(tx, (pt[0], pt[1] - 10), xycoords='data', frameon=False) ax.add_artist(ab2) # plotting past point plt.scatter(past_loc[-1][0], past_loc[-1][1], c='r', s=3, alpha=0.9) plt.pause(5) # TODO: exit if plot is closed - needs to be fixed if not plt.fignum_exists(fig_num): if not os.path.exists('saved_runs'): os.mkdir('saved_runs') loc = os.path.join('saved_runs', f'run{start_time}') print(f'Saving plot as: {loc}') fig.savefig(loc) sys.exit() ab.remove() # remove previous iss icon ab2.remove() # remove previous latitude, longitude annonate
class App_Window(Tkinter.Tk): def __init__(self, parent): Tkinter.Tk.__init__(self, parent) self.parent = parent self.initialize() def initialize(self): font = {'size': 12} matplotlib.rc('font', **font) matplotlib.style.use("dark_background") pixels = [1920, 1080] fig = Figure(figsize=(pixels[0] / 96.0, pixels[1] / 96.0), edgecolor='none', facecolor='k') i0 = 1 i = 14 j = 36 s = 3 # ---------------------------------------------------------------------- # Eixos para os graficos # ---------------------------------------------------------------------- gs1, gs2 = gridspec.GridSpec(i, j), gridspec.GridSpec(i, j) # ---------------------------------------------------------------------- # Grafico de temperatura xaxis compartilhado com os demais graficos graf_temp = fig.add_subplot(gs1[i0 + 3 * s:i0 + 4 * s:11, 0:15]) # Grafico de pressao graf_press = fig.add_subplot(gs1[i0 + 2 * s:i0 + 3 * s:11, 0:15], sharex=graf_temp) # Grafico umidade e precipitacao graf_umid = fig.add_subplot(gs1[i0 + s:i0 + 2 * s, 0:15], sharex=graf_temp) graf_rain = graf_umid.twinx() # Grafico de vento e direcao do vento graf_vento = fig.add_subplot(gs1[i0:i0 + s, 0:15], sharex=graf_temp) # ---------------------------------------------------------------------- # Icone da pressao icon_pres = fig.add_subplot(gs1[i0 + 2 * s:i0 + 3 * s, 16:21], frameon=False) # Icone do vento icon_vent = fig.add_subplot(gs1[i0:i0 + s, 16:18], frameon=False) # Icone de umidade icon_umid = fig.add_subplot(gs1[i0 + s:i0 + 2 * s, 16:18], frameon=False) # Icone de temperatura icon_temp = fig.add_subplot(gs1[i0 + 3 * s:i0 + 4 * s, 16:18], frameon=False) # Icone direcao do vento agora icon_vento_dir = fig.add_subplot(gs2[i0:i0 + s, 19:22], frameon=False, projection='polar') # Icone de precipitacao icon_rain = fig.add_subplot(gs2[i0 + s:i0 + 2 * s, 18:21], frameon=False) # Icone de sensação térmica self.icon_feel = fig.add_subplot(gs2[i0 + 3 * s:i0 + 4 * s, 18:21], frameon=False) # Icone de rajada icon_gust = fig.add_subplot(gs1[i0:4, 23:27], frameon=False) # Icone de windrose icon_rose = fig.add_subplot(gs1[i0:4, 28:32], frameon=False, projection='polar') # ---------------------------------------------------------------------- # Titulo Gráficos self.title_1 = fig.add_subplot(gs1[0, 0:12], frameon=False) # Titulo Icones self.title_2 = fig.add_subplot(gs1[0, 16:21], frameon=False) # Titulo Logos self.title_3 = fig.add_subplot(gs1[-2, 23::], frameon=False) map = fig.add_subplot(gs1[5:-2, 23::]) gs1.update(wspace=0.01, hspace=0.3, left=0.04, top=1, bottom=0.000001) gs2.update(wspace=0.03, hspace=0.75, top=1, bottom=0.000001) # ---------------------------------------------------------------------- # Plota os icones # ---------------------------------------------------------------------- dir_icon = '.\images' zoom_f = 1.6 kw = dict(frameon=False, xycoords="data", boxcoords="data", xy=(0, 0), box_alignment=(0.0, 0.0)) # Desenha os icones de vento img_today = read_png(os.path.join(dir_icon, 'wind.png')) imagebox = OffsetImage(img_today, zoom=0.07 * zoom_f) ab = AnnotationBbox(imagebox, xybox=(0.1, 0.1), **kw) icon_vent.add_artist(ab) # ---------------------------------------------------------------------- # Gerando eixo polar para as setas para o vento directions = ['N', 'NW', 'W', 'SW', 'S', 'SE', 'E', 'NE'] icon_vento_dir.set_theta_zero_location('N') icon_vento_dir.set_theta_direction(1) icon_vento_dir.set_xticklabels(directions) icon_vento_dir.tick_params(axis='x', colors='w') icon_vento_dir.tick_params(axis='y', colors='w') icon_vento_dir.grid(color='w') # Desenha o icone de rajada img_today = read_png(os.path.join(dir_icon, 'rajada.png')) imagebox = OffsetImage(img_today, zoom=0.15 * zoom_f) ab = AnnotationBbox(imagebox, xybox=(0.0, 0.1), **kw) icon_gust.add_artist(ab) icon_gust.set_title(u'Rajada 2 minutos', fontsize=11, x=0.4, y=1, fontweight='bold') # ---------------------------------------------------------------------- # Gerando eixo polar para plot icon_rose.set_theta_zero_location('N') icon_rose.set_theta_direction(1) icon_rose.set_xticklabels(directions) icon_rose.tick_params(axis='x', colors='w') icon_rose.tick_params(axis='y', colors='w') icon_rose.grid(color='w') # Desenha os icones de umidade img_today = read_png(os.path.join(dir_icon, 'humidity.png')) imagebox = OffsetImage(img_today, zoom=0.075 * zoom_f) ab = AnnotationBbox(imagebox, xybox=(0.325, 0.10), **kw) icon_umid.add_artist(ab) # Desenha os icones de precipitacao img_today = read_png(os.path.join(dir_icon, 'rain.png')) imagebox = OffsetImage(img_today, zoom=0.09 * zoom_f) ab = AnnotationBbox(imagebox, xybox=(0.275, 0.0), **kw) icon_rain.add_artist(ab) # Desenha os icones de pressao img_today = read_png(os.path.join(dir_icon, 'pressure.png')) imagebox = OffsetImage(img_today, zoom=0.125 * zoom_f) ab = AnnotationBbox(imagebox, xybox=(0.35, 0.0), **kw) icon_pres.add_artist(ab) # Desenha os icones de temperatura img_today = read_png(os.path.join(dir_icon, 'temp.png')) imagebox = OffsetImage(img_today, zoom=0.11 * zoom_f) ab = AnnotationBbox(imagebox, xybox=(0.22, 0.0), **kw) icon_temp.add_artist(ab) # Desenha o icone de sensacao termica atual img_today = read_png(os.path.join(dir_icon, 'realfeel.png')) imagebox = OffsetImage(img_today, zoom=0.10 * zoom_f) self.ab = AnnotationBbox(imagebox, xybox=(0.3, 0.1), **kw) self.icon_feel.add_artist(self.ab) self.icon_feel.set_title(u'Sensação\nTérmica', fontsize=11, x=0.55, y=-0.2) self.img = itertools.cycle( ['realfeel_cky.png', 'realfeel_fms.png', 'realfeel_fna.png']) # logo Petrobras img_today = read_png(os.path.join(dir_icon, 'Principal_h_cor_RGB.png')) imagebox = OffsetImage(img_today, zoom=0.2) # opcao 1: logo ao lado do credito ab = AnnotationBbox(imagebox, xybox=(0.0, 0.05), **kw) self.title_3.add_artist(ab) # logo Oceanop img_today = read_png(os.path.join(dir_icon, 'oceanop_logo.png')) imagebox = OffsetImage(img_today, zoom=0.4) # opcao 1: logo ao lado do credito ab = AnnotationBbox(imagebox, xybox=(0.8, 0.1), **kw) self.title_3.add_artist(ab) # ---------------------------------------------------------------------- # Cria mapa base # ---------------------------------------------------------------------- # Coordenadas da estacao meteorologica # 22 24 4.02**41 48 29.30 Xest, Yest = -41.808138888889, -22.401116666667 # Coordenadas da janela da imagem 2223.936_4148.723_2224.175_4148.264 Xmin, Xmax = -41.81205, -41.8044 Ymin, Ymax = -22.402916666667, -22.398933333333 # Mapa base com a localizacao da estacao m = Basemap(ax=map, epsg=4326, projection='merc', llcrnrlat=Ymin, urcrnrlat=Ymax, llcrnrlon=Xmin, urcrnrlon=Xmax, resolution='c') imgfile = os.path.join(dir_icon, '2223.936_4148.723_2224.175_4148.264.jpg') img = plt.imread(imgfile) m.imshow(img, origin='upper') # Plota pontos de interesse bprops = dict(boxstyle='round', facecolor='w', alpha=0.35) aprops2 = dict(arrowstyle='simple', connectionstyle='arc3, rad=-0.2', relpos=(0., 1.), facecolor='k', alpha=0.6) map.text(-41.8066588889, -22.40111, 'EDINC', horizontalalignment='center', verticalalignment='center', fontweight='bold', fontsize=16, color='k', bbox=bprops) pest, = map.plot(Xest, Yest, 'ro', markersize=4) map.annotate(u"Estação\nMeteorológica", xy=(Xest, Yest), xycoords='data', xytext=(-41.809, -22.403), size=12, va='top', ha='left', arrowprops=aprops2, bbox=bprops, fontweight='bold') # Insere seta apontando para o norte no canto inferior direito imgfile = read_png(os.path.join(dir_icon, 'north_arrow.png')) imagebox = OffsetImage(imgfile, zoom=0.11) lonmin, lonmax = m.boundarylonmin, m.boundarylonmax latmin, latmax = min(m.boundarylats), max(m.boundarylats) xy = (lonmax - 0.08 * (lonmax - lonmin), latmax - 0.9 * (latmax - latmin)) ab = AnnotationBbox(imagebox, xy, frameon=False, xycoords="data", boxcoords="data", box_alignment=(0.0, 0.0)) map.add_artist(ab) fontdict = { 'color': 'w', 'va': 'center', 'ha': 'center', 'fontsize': 13, 'fontweight': 'bold' } self.i_vent = icon_vent.text(0.5, 0.8, 'NA', fontdict=fontdict) self.i_gust = icon_gust.text(0.5, 0.8, 'NA', fontdict=fontdict) self.i_umid = icon_umid.text(0.5, 0.75, 'NA', fontdict=fontdict) self.i_rain = icon_rain.text(0.5, 0.8, 'NA', fontdict=fontdict) self.i_pres = icon_pres.text(0.2, 0.7, 'NA', fontdict=fontdict) self.i_temp = icon_temp.text(0.25, 0.75, 'NA', fontdict=fontdict) self.i_feel = self.icon_feel.text(0.275, 0.75, 'NA', fontdict=fontdict) # Set icones e titulos axis_icon_names = [ icon_pres, icon_vent, icon_umid, icon_rain, icon_gust, icon_pres, icon_temp, self.icon_feel, self.title_1, self.title_2, self.title_3 ] for i in axis_icon_names: i.set_axis_off() # Set titulos nos graficos graf_vento.set_title(u'Vento [km/h]', x=0.12, y=0.75, fontweight='bold', fontsize=11) graf_press.set_title(u'Pressão Atmosférica [hPa]', x=0.23, y=0.75, fontweight='bold', fontsize=11) graf_umid.set_title(u'Umidade Relativa [%]', x=0.19, y=0.75, fontweight='bold', fontsize=11) graf_temp.set_title(u'Temperatura do Ar [\N{DEGREE SIGN}C]', x=0.205, y=0.75, fontweight='bold', fontsize=11) map.set_title(u'Localização da Estação Meteorólogica', fontsize=15, fontweight='bold', loc='left', y=1.05) self.canvasFig = fig # [0]wind, [1]humi, [2]pres, [3]temp self.cor = ['#4CB050', '#2196F5', '#FF9702', '#F44236'] x, y = [], [] self.line0, = graf_vento.plot(x, y, self.cor[0]) self.line1, = graf_umid.plot(x, y, self.cor[1]) self.line2, = graf_rain.plot(x, y, self.cor[1], linestyle='--') self.line3, = graf_press.plot(x, y, self.cor[2]) self.line4, = graf_temp.plot(x, y, self.cor[3]) icon_vento_dir.axes.yaxis.set_ticklabels([]) icon_rose.axes.yaxis.set_ticklabels([]) self.canvas = FigureCanvasTkAgg(fig, master=self) self.canvas.show() self.canvas.get_tk_widget().pack(side=Tkinter.TOP, fill=Tkinter.BOTH, expand=1) self.canvas._tkcanvas.pack(side=Tkinter.TOP, fill=Tkinter.BOTH, expand=1) self.after(500, self.icon_refresh, icon_vento_dir, icon_rose) self.update() def refreshFigure(self): x = list(timeline) xmin, xmax = date2num(min(timeline)), date2num(max(timeline)) self.line0.set_data(x, np.array(wspd_24h)) self.line1.set_data(x, list(umid_24h)) self.line2.set_data(x, list(rain_24h)) self.line3.set_data(x, list(pres_24h)) self.line4.set_data(x, list(temp_24h)) ax0 = self.canvas.figure.axes[0] # temp ax1 = self.canvas.figure.axes[1] # pres ax2 = self.canvas.figure.axes[2] # umid ax3 = self.canvas.figure.axes[3] # chuva ax4 = self.canvas.figure.axes[4] # vento ax0.set_xlim(min(x), max(x)) try: # temp self.grad0.remove() self.fill0.remove() except: pass self.grad0 = ax0.imshow( get_grad(self.cor[3]), aspect='auto', extent=[xmin, xmax, min(temp_24h), max(temp_24h)], origin='lower') self.fill0 = ax0.axes.fill_between(x, list(temp_24h), max(temp_24h), color='k') ax0.set_ylim(min(temp_24h), max(temp_24h)) try: # pres self.grad1.remove() self.fill1.remove() except: pass self.grad1 = ax1.imshow( get_grad(self.cor[2]), aspect='auto', extent=[xmin, xmax, min(pres_24h), max(pres_24h)], origin='lower') self.fill1 = ax1.axes.fill_between(x, list(pres_24h), max(pres_24h), color='k') ax1.set_ylim(min(pres_24h), max(pres_24h)) try: # umid self.grad2.remove() self.fill2.remove() except: pass self.grad2 = ax2.imshow( get_grad(self.cor[1]), aspect='auto', extent=[xmin, xmax, min(umid_24h), max(umid_24h)], origin='lower') self.fill2 = ax2.axes.fill_between(x, list(umid_24h), max(umid_24h), color='k') ax2.set_ylim(min(umid_24h), max(umid_24h)) ax3.set_ylim([-0.1, np.maximum(1.0, np.round(1.2 * max(rain_24h)))]) try: # wind self.grad4.remove() self.fill4.remove() except: pass self.grad4 = ax4.imshow( get_grad(self.cor[0]), aspect='auto', extent=[xmin, xmax, min(wspd_24h), max(wspd_24h)], origin='lower') self.fill4 = ax4.axes.fill_between(x, np.array(wspd_24h), max(wspd_24h), color='k') ax4.set_ylim(min(wspd_24h), max(wspd_24h)) try: # Stick a cada 20 minutos self.quiver.remove() except: pass self.quiver = stick_plot(date2num(timeline)[::2], np.mean(wspd_24h), np.array(wspd_u_24h)[::2], np.array(wspd_v_24h)[::2], normed=False, color=self.cor[0], alpha=1, width=0.001, headwidth=5, headlength=8, headaxislength=8, ax=ax4) # Plota taxa de precipitacao com legendas ax3.legend((ax2.axes.get_lines()[0], ax3.axes.get_lines()[0]), ['Umidade Relativa (%)', u'Precipitação (mm/hora)'], fontsize=12, loc=1, framealpha=0.5, fancybox=[1, 1, 1, 1]) # Ajuste o ylim do eixo de vento, caso max(wind) < 10 km/h, # limita em 10 km/h if max(wspd_24h) < 10.0: ax4.set_ylim([4, 10.0]) ax4.set_yticks(np.arange(5)) # Corrige formato do eixo y nos graficos de pressao e vento ax1.get_yaxis().set_major_formatter( FuncFormatter(lambda x, p: '%1.1f' % x)) ax4.get_yaxis().set_major_formatter( FuncFormatter(lambda x, p: '%1.1f' % x)) # SET figure ax0.axes.fmt_xdata = DateFormatter('%d/%m/%y %H:%M') ax0.axes.xaxis.set_major_locator(HourLocator(byhour=(0, 6, 12, 18))) ax0.axes.xaxis.set_major_formatter(DateFormatter('%d/%m/%y\n%H:%M')) ax0.axes.xaxis.set_minor_locator(HourLocator(byhour=(3, 9, 15, 21))) ax0.axes.xaxis.set_minor_formatter(DateFormatter('%H:%M')) lines_map = [ax0, ax1, ax2, ax3, ax4] for i in lines_map: i.grid(True) i.yaxis.set_major_locator(MaxNLocator(4)) if i == ax0: for label in ax0.xaxis.get_majorticklabels(): label.set_fontsize(10) label.set_ha('right') label.set_rotation(45) for label in ax0.xaxis.get_minorticklabels(): label.set_fontsize(8) label.set_ha('right') label.set_rotation(45) else: for label in i.xaxis.get_majorticklabels(): label.set_visible(False) for label in i.xaxis.get_minorticklabels(): label.set_visible(False) self.canvas.draw() def icon_refresh(self, icon_vento_dir, icon_rose): try: self.arrow.remove() self.arrow_.remove() except: pass try: self.i_vent.set_text( u'%1.1f km/h \n%1.1f nós' % (wspd_600[0] * 3.6, wspd_600[0] * 3.6 / 1.8520)) self.i_gust.set_text(u'%1.1f km/h \n%1.1f nós' % (raj[0] * 3.6, raj[0] * 3.6 / 1.852)) self.angle = np.arctan2( np.sin(deque(itertools.islice(wdir_600, 0, 119))).mean(), np.cos(deque(itertools.islice(wdir_600, 0, 119))).mean()) % (2 * np.pi) self.arrow = icon_vento_dir.annotate("", xy=(-wdir_600[0], 0), xytext=(-wdir_600[0], 1), arrowprops=dict( arrowstyle='fancy', fc='#4CB050', ec='w'), size=20) self.arrow_ = icon_rose.annotate("", xy=(-self.angle, 0), xytext=(-self.angle, 1), arrowprops=dict( arrowstyle='fancy', fc='#4FADD0', ec='w'), size=20) self.i_umid.set_text(u'%1.1f%%' % umid_600[0]) self.i_pres.set_text(u'%1.1f\nhPa' % pres_600[0]) self.i_temp.set_text(u'%1.1f\n\N{DEGREE SIGN}C' % temp_600[0]) self.i_feel.set_text( u'%1.1f\n\N{DEGREE SIGN}C' % np.round(calc_real_feel(wspd_600[0], temp_600[0]))) self.title_2.set_title(u'Medição Agora:\n%s' % data_now[0], fontweight='bold', y=0.1, fontsize=15) except RuntimeError: pass if data_now[0][-2:] == '05': # Desenha o icone de sensacao termica atual self.ab.remove() img_today = read_png(os.path.join('.\images', self.img.next())) imagebox = OffsetImage(img_today, zoom=0.11 * 1.6) self.ab = AnnotationBbox(imagebox, xybox=(0.3, 0.1), frameon=False, xycoords="data", boxcoords="data", xy=(0, 0), box_alignment=(0.0, 0.0)) self.icon_feel.add_artist(self.ab) if data_now[0][-4:] == '0:05': self.i_rain.set_text(u'%1.1f mm\n acumulado' % np.sum(rain_24h_acu)) if np.size(timeline) > 1 and np.size(timeline) < 6: minutos = np.size(timeline) * 10 self.title_1.set_title(u'Estação Meteorológica do ' + u'OCEANOP\nSéries temporais ' + u'dos últimos ' + '%s minutos' % minutos, fontweight='bold', y=-0.1, loc='left', fontsize=18) self.refreshFigure() if np.size(timeline) > 5: minutos = np.size(timeline) % 6 * 10 self.title_1.set_title(u'Estação Meteorológica do ' + u'OCEANOP\nSéries temporais ' + u'das últimas ' + '%s:%02.f Horas' % (np.size(timeline) / 6, float(minutos)), fontweight='bold', y=-0.1, loc='left', fontsize=18) self.refreshFigure() self.canvas.draw() self.after(500, self.icon_refresh, icon_vento_dir, icon_rose)