def waveform_trio_features_and_points(audio, feature, point_list, rms=None, peak_envelope=None, figsize=None): # configuring figure and subplots if not figsize: figsize = DEFAULT_FIG_SIZE f = plt.figure(figsize=figsize) axes_list = f.subplots(2, sharex=True) # add waveform trio to first axes _add_waveform_trio_to_axes(axes_list[0], audio, rms, peak_envelope) # add feature _add_curve_to_axes(axes_list[1], feature, label=feature.label) axes_list[1].legend(loc='lower right', fontsize='x-small') _add_points_to_axes(axes_list[1], point_list.time, point_list.get_values(feature)) MultiCursor(f.canvas, axes_list, color='gray', lw=1) f.show()
def waveform_trio_and_features(audio, rms=None, peak_envelope=None, features=(), figsize=None): """ Plot a graph showing curves for the ``audio`` waveform, the ``rms`` and the ``peak_envelope``; followed by a series of graphs, one for each time-series in the tuple `features`. """ if not features: raise ValueError("the features to be plotted were not specified") # configuring figure and subplots if not figsize: figsize = DEFAULT_FIG_SIZE f = plt.figure(figsize=figsize) axes_list = f.subplots(len(features) + 1, sharex=True) plt.subplots_adjust(hspace=0.05) # add audio to first axes _add_waveform_trio_to_axes(axes_list[0], audio, rms, peak_envelope) # add features to the other axes for i, feature in enumerate(features, start=1): _add_curve_to_axes(axes_list[i], feature, label=feature.label) axes_list[i].legend(loc='lower right', fontsize='x-small') MultiCursor(f.canvas, axes_list, color='gray', lw=1) plt.show() return f
def to_XYZ_slice(self, toSlice): from matplotlib.widgets import MultiCursor ''' 1) set MatPLotlibCursor correctly 2) collect the next click 3) (Perhaps reset the cursor) 4) set the variables 5) Update the plot ''' self.MatPlotMultiCursor = None currType = self.varType.get() if currType == toSlice: self.varStatus.set('Already on {}-plane.'.format(toSlice)) return hor, ver = self.toXYZ_horOrVer(toSlice, currType) #print('Hor:',hor,' Ver:',ver) self.MatPlotMultiCursor = MultiCursor(self.MatPlotFig.canvas, (self.MatPlotAx, ), color='k', lw=1, horizOn=hor, vertOn=ver)
def show(Close, Earns): Xl = range(len(Close)) name, rate = 0, 1 fig = plt.figure('定投策略收益率') ax1 = plt.subplot(211) plt.plot(Xl, Close, label='收盘价') ax1.axhline(y=Close[0], color='#d46061', linewidth=1, label='建仓价位%d' % Close[0]) plt.legend(loc='upper left') low, high = 0, 0 ax2 = plt.subplot(212) for Earn in Earns: plt.plot(Xl, Earn[rate], label=Earn[name]) low = min(low, min(Earn[rate])) high = max(high, max(Earn[rate])) plt.ylim(int(low - 5) / 5 * 5, int(high + 5) / 5 * 5) #不同参数比较时固定合理的y坐标范围 ax2.axhline(y=0, color='#d46061', linewidth=1, label='0') # low, high = min(Earn), max(Earn) # mean = sum(Earn) / len(Earn) # ax2.axhline(y=low, color='yellow', linewidth=1, label='min=%0.2f'%low) # ax2.axhline(y=high, color='gray', linewidth=1, label='high=%0.2f'%high) # ax2.axhline(y=mean, color='green', linewidth=1, label='mean=%0.2f'%mean) plt.legend(loc='upper left') # plt.ylim(-25, 15) multi = MultiCursor(fig.canvas, (ax1, ax2), color='r', lw=1) plt.show()
def ShowGraph():# Show Graph to U and I global Um, Im, Fi, P, T, Z t = arange(0, 100, T) fig = figure(0) axU = fig.add_subplot(211) axU.spines['right'].set_color('none') axU.spines['top'].set_color('none') axU.xaxis.set_ticks_position('bottom') axU.spines['bottom'].set_position(('data', 0)) axU.yaxis.set_ticks_position('left') axU.spines['left'].set_position(('data', 0)) axU.set_title('Show Graph to Imax, Umax', fontsize = 25) axU.plot(t, Um*sin(P*t+Fi), color = "blue", linewidth = 2.5, linestyle = "-", Label = "U(t)")# U(t) axU.grid(True) axU.legend(["Umax"]) axU.set_xlim(0, 40) axI = fig.add_subplot(212, sharex = axU) axI.spines['right'].set_color('none') axI.spines['top'].set_color('none') axI.xaxis.set_ticks_position('bottom') axI.spines['bottom'].set_position(('data', 0)) axI.yaxis.set_ticks_position('left') axI.spines['left'].set_position(('data', 0)) axI.plot(t, Im*sin(P*t), color = "green", linewidth = 2.5, linestyle = "-", Label = "I(t)")# I(t) axI.grid(True) axI.legend(["Imax"]) axI.set_xlim(0, 40) multi = MultiCursor(fig.canvas, (axU, axI), color = 'r', lw = 1) show()
def __init__(self, code, index_code = '000001'): self.code = code self.index_code = index_code self.base_color = '#e6daa6' self.k_data, self.d_data, self.i_data = self.read_data() self.date_tickers = self.k_data.time.values self.k_data.time = self.k_data.index self.i_data.time = self.i_data.index self.volumeMin = 0 self.volumeMax = 0 self.priceMin = 0 self.priceMax = 0 self.dateMin = 0 self.dateMax = 0 self.fig = plt.figure(facecolor = self.base_color, figsize = (24, 24)) self.price_ax = plt.subplot2grid((12,12), (0,0), rowspan = 7, colspan = 8, facecolor = self.base_color, fig = self.fig) self.index_ax = plt.subplot2grid((12,12), (7,0), rowspan = 4, colspan = 8, facecolor = self.base_color, sharex = self.price_ax, fig = self.fig) self.volume_ax = plt.subplot2grid((12,12), (11,0), rowspan = 1, colspan = 8, facecolor = self.base_color, sharex = self.price_ax, fig = self.fig) self.dist_ax = plt.subplot2grid((12,12), (0,8), rowspan = 7, colspan = 4, facecolor = self.base_color, sharey = self.price_ax, fig = self.fig) self.press = None self.release = None self.keypress = self.fig.canvas.mpl_connect('key_press_event', self.on_key_press) self.cidpress = self.fig.canvas.mpl_connect('button_press_event', self.on_press) self.cidrelease = self.fig.canvas.mpl_connect('button_release_event', self.on_release) self.multi = MultiCursor(self.fig.canvas, (self.price_ax, self.volume_ax, self.index_ax), color='b', lw=1, horizOn = True, vertOn = True)
def ma_kdj(self): '''对比均线与KDJ绿线,看看能否搞一个新的策略''' show_period = 120 #global lt,wan,qian,bai,shi,ge,zbname,tf logging.info('开始:', time.asctime()) t0 = time.time() series = self.get_series() close = np.cumsum(series).astype(float) fig, axes = plt.subplots(5, 1, sharex=True) #fig.set_tight_layout(True) # 布林线 upperband, middleband, lowerband = ta.BBANDS(close, timeperiod=5, nbdevup=2, nbdevdn=2, matype=0) axes[0].plot(close[-show_period:], 'rd-', markersize = 5) axes[0].plot(upperband[-show_period:], 'y-') axes[0].plot(middleband[-show_period:], 'b-') axes[0].plot(lowerband[-show_period:], 'y-') #策略:金叉死叉 order, earn, ma_fast, ma_slow = strategy.strategy_gold_die(series) axes[1].plot(ma_fast[-show_period:], 'g-') axes[1].plot(ma_slow[-show_period:], 'r-') # 策略:KDJ绿线 order2, earn2, fastk, fastd = strategy.strategy_kdj(series) axes[2].plot(fastk[-show_period:], 'r-') axes[2].plot(fastd[-show_period:], 'g-') # 策略:通道宽度 order, earn, bandwidth, mean = strategy.strategy_bandwidth(series) axes[3].plot(bandwidth[-show_period:], 'r-') axes[3].plot([0,show_period],[mean, mean],'k',alpha=.4) # 策略:正弦变换 order, earn, sine, leadsine = strategy.strategy_ht_sine(series) axes[4].plot(sine[-show_period:], 'r-') axes[4].plot(leadsine[-show_period:], 'g-') title1 = '指标:' + self.wei + '位 ' + self.zbname.get() + ' 同反:' + str(self.tf.get()) axes[0].set_title(title1, fontproperties="SimHei") #axes[1].set_title('金叉死叉', fontproperties="SimHei") #axes[2].set_title('均线', fontproperties="SimHei") #axes[3].set_title('KDJ绿线', fontproperties="SimHei") #axes[4].set_xticks(range(120)) # 120个数据 #axes[4].set_xticklabels(self.get_labels(self.lt.last_period), rotation=35) # 设置x轴标签(13个) #axes[4].xaxis.set_major_locator(MultipleLocator(10)) # 主坐标:间隔10 t = time.time() - t0 logging.info('结束', time.asctime()) logging.info('耗时:{}分{}秒'.format(int(t)//60, int(t)%60)) multi = MultiCursor(fig.canvas, (axes[0], axes[1], axes[2], axes[3], axes[4]), color='b', lw=2) plt.show()
def trend(df): signals = pd.DataFrame(index=df.index) signals['MACDTrendSignal'] = 0 signals['MACDTrendSignal'][26:] = np.where( df['MACD'][26:] >= df['Signal'][26:], 1, 0) signals['action'] = signals['MACDTrendSignal'].diff() signals['MACD'] = df['MACD'] print('MACD is: \n', signals.MACD) fignew = plt.figure() ax1 = fignew.add_subplot(211) df['MACD'].plot(ax=ax1, color='m', marker='o') df['Signal'].plot(ax=ax1, color='y') ax1.plot(signals.loc[signals.action == 1.0].index, signals.MACD[signals.action == 1.0], '^', markersize=10, color='g') ax1.plot(signals.loc[signals.action == -1.0].index, signals.MACD[signals.action == -1.0], 'v', markersize=10, color='r') ax2 = fignew.add_subplot(212, sharex=ax1) df['Close'].plot(ax=ax2) multiC = MultiCursor(fignew.canvas, (ax1, ax2), lw=1) plt.show() return signals
def show(Xl, Close, Earn): global title fig = plt.figure(title) ax1 = plt.subplot(211) plt.plot(Xl, Close, label='收盘价') ax1.axhline(y=Close[0], color='#d46061', linewidth=1, label='建仓价位%d' % Close[0]) plt.legend(loc='upper left') ax2 = plt.subplot(212) plt.plot(Xl, Earn, label='收益率') low, high = min(Earn), max(Earn) mean = sum(Earn) / len(Earn) ax2.axhline(y=0, color='#d46061', linewidth=1, label='0') ax2.axhline(y=low, color='yellow', linewidth=1, label='min=%0.2f' % low) ax2.axhline(y=high, color='gray', linewidth=1, label='high=%0.2f' % high) ax2.axhline(y=mean, color='green', linewidth=1, label='mean=%0.2f' % mean) plt.legend(loc='upper left') # plt.ylim(-25, 15) multi = MultiCursor(fig.canvas, (ax1, ax2), color='r', lw=1) print Earn[-1] plt.show()
def __init__(self): super(ApplicationWindow, self).__init__() # connect to the UI made by QtDesigner self.ui = myMainWindow.Ui_MainWindow() self.ui.setupUi(self) # parameters for computing self.targetDir = '' self.showindicator = True self.mycanvas = MyCanvas( self) # mainAppWindow.ui.mainWidget)#, width=5, height=4, dpi=100) self.mycanvas.mpl_connect('button_press_event', self.on_mousebutton_press) self.mycanvas.mpl_connect('button_release_event', self.on_mousebutton_release) self.mycanvas.mpl_connect('motion_notify_event', self.on_cursor_motion) self.ui.verticalLayout.addWidget(self.mycanvas) self.ui.loadstButton.setDisabled(True) self.dataframe = pd.DataFrame() self.pdfile = 'config\\policyselections' self.multicursor = MultiCursor( self.mycanvas, (self.mycanvas.axes, self.mycanvas.axes1), horizOn=True, color='r', lw=0.5) self.ui.buttonCursor.setText("-")
def simple_visualization(df, name, result): from matplotlib.widgets import Cursor fig = plt.figure() fig.suptitle(name, fontsize=18) ax1 = fig.add_subplot(311) ax1.plot(df.index, df['Close'], color='b', linewidth=2, marker='o', markersize=5) ax1.plot(df.index, df['Bollinger avg'], color='black', linewidth=0.5) ax1.plot(df.index, df['Bollinger Upper'], color='r', linewidth=0.5) ax1.plot(df.index, df['Bollinger Lower'], color='g', linewidth=0.5) #cursor = Cursor(ax1, useblit=True,color='blue', linewidth=2) ax1.fill_between(df.index, df['Bollinger Upper'], df['Bollinger Lower'], color='yellow') ax2 = fig.add_subplot(312, sharex=ax1, facecolor='grey', title='MACD') ax2.plot(df.index, df['MACD'], color='m') ax2.plot(df.index, df['Signal'], color='y') handles, label = ax2.get_legend_handles_labels() ax2.legend(handles, label, loc='lower right', fancybox=True, shadow=True) ax2.bar(df.index, df['MACD Histogram'], color='b') ax3 = fig.add_subplot(313, sharex=ax1, title='RSI') ax3.plot(df.index, df['RSI']) thresh = pd.DataFrame(index=df.index) thresh['Overbought'] = 70 thresh['Oversold'] = 30 ax3.plot(df.index, thresh['Overbought'], '--', color='red') ax3.plot(df.index, thresh['Oversold'], '--', color='green') multiC = MultiCursor(fig.canvas, (ax1, ax2, ax3), lw=1) plt.show()
def add_widget(self, ith_subwidget, widget, ymain=False, connect_slider=False): """ 添加一个能接收消息事件的控件。 Args: ith_subwidget (int.): 子窗口序号。 widget (AxesWidget): 控件。 Returns: AxesWidget. widget """ # 对新创建的Axes做相应的处理 # 并且调整Cursor for plotter in widget.plotters.values(): if plotter.twinx: plotter.ax.format_coord = self._format_coord self.axes.append(plotter.ax) #self._cursor_axes[ith_subwidget] = plotter.ax self._cursor = MultiCursor(self._fig.canvas, self._cursor_axes.values(), color='r', lw=2, horizOn=False, vertOn=True) self._subwidgets[ith_subwidget] = widget if connect_slider: self._slider.add_observer(widget) return widget
def graph_data(self, dpi=100, figsize=(11, 7)): fig, axes = plt.subplots(2, 2, dpi=dpi, figsize=figsize) # Top left axes[0][0].set_title('Sensor & Sensor with α') # Top Right axes[0][1].set_title('Temperature') # Bottom Left # axes[1][0].set_title(str('Final ') + str(self.alpha_divisions) + str(' calculations | α = ') + str(self.final_alpha_number)) axes[1][0].set_title('Final {} calculations | α = {}'.format( self.alpha_divisions, self.final_alpha_number)) # Bottom Right axes[1][1].set_title('{} calculations'.format(len(self.stdev_df))) # Raw sensor data and sensor data with alpha applied (Top left) self.df.plot(kind='line', use_index=True, x=self.time_header, y=[self.target_header, self.final_alpha_number], ax=axes[0][0]) # Raw temperature data (Top right) self.df.plot(kind='line', use_index=True, x=self.time_header, y=self.temp_header, ax=axes[0][1]) guide_line = MultiCursor(fig.canvas, (axes[0][0], axes[0][1]), lw=1, horizOn=False, vertOn=True) # Final alpha calculations with final alpha number highlighted red (Bottom Left) self.stdev_df[:self.alpha_divisions + self.alpha_divisions + 20].plot(kind='scatter', x='ALPHA', y='STDEV', ax=axes[1][0]) self.stdev_df[:1].plot(kind='scatter', x='ALPHA', y='STDEV', color='red', ax=axes[1][0]) # All alpha calculations with final alpha number highlighted red (Bottom Right) self.stdev_df.plot(kind='scatter', x='ALPHA', y='STDEV', ax=axes[1][1]) self.stdev_df[:1].plot(kind='scatter', x='ALPHA', y='STDEV', color='red', ax=axes[1][1]) plt.subplots_adjust(hspace=0.5) plt.show()
def smooth(x, isosbestic, calcium, **kwargs): """Function that smooths the raw data and displays it in a plot. Args : x (arr) = The time data in X isosbestic (arr) = The adjusted isosbestic signal (time fitted to the video) calcium (arr) = The adjusted calcium signal (time fitted to the video) kwargs (dict) = Dictionnary with the parameters Returns : x (arr) = The new time data in X isosbestic_smoothed (arr) = The smoothed isosbestic signal calcium_smoothed (arr) = The smoothed calcium signal """ print("\nStarting smoothing for Isosbestic and Calcium signals !") isosbestic_smoothed = smooth_signal(isosbestic, window_len=kwargs["smoothing_window"])[:-kwargs["smoothing_window"]+1] calcium_smoothed = smooth_signal(calcium, window_len=kwargs["smoothing_window"])[:-kwargs["smoothing_window"]+1] x_max = x[-1] # print("Data length : {0}".format(ut.h_m_s(x_max, add_tags=True))) if kwargs["photometry_pp"]["plots_to_display"]["smoothing"]: xticks, xticklabels, unit = utils.generate_xticks_and_labels(x_max) fig = plt.figure(figsize=(10, 5), dpi=200.) ax0 = plt.subplot(211) p, = ax0.plot(x, isosbestic_smoothed, alpha=0.8, c=kwargs["photometry_pp"]["purple_laser"], lw=kwargs["lw"]) ax0.set_xticks(xticks) ax0.set_xticklabels(xticklabels, fontsize=kwargs["fsl"]) ax0.set_xlim(0, x_max) y_min, y_max, round_factor = utils.generate_yticks(isosbestic_smoothed, 0.1) ax0.set_yticks(np.arange(y_min, y_max+round_factor, round_factor)) ax0.set_yticklabels(["{:.0f}".format(i) for i in np.arange(y_min, y_max+round_factor, round_factor)*1000], fontsize=kwargs["fsl"]) ax0.set_ylim(y_min, y_max) ax0.set_ylabel("mV", fontsize=kwargs["fsl"]) ax0.legend(handles=[p], labels=["isosbestic"], loc=2, fontsize=kwargs["fsl"]) ax0.set_title("Smoothed Isosbestic and Calcium signals", fontsize=kwargs["fst"]) ax0.tick_params(axis='both', which='major', labelsize=kwargs["fsl"]) ax1 = plt.subplot(212, sharex=ax0) b, = ax1.plot(x, calcium_smoothed, alpha=0.8, c=kwargs["photometry_pp"]["blue_laser"], lw=kwargs["lw"]) ax1.set_xticks(xticks) ax1.set_xticklabels(xticklabels, fontsize=kwargs["fsl"]) ax1.set_xlim(0, x_max) y_min, y_max, round_factor = utils.generate_yticks(calcium_smoothed, 0.1) ax1.set_yticks(np.arange(y_min, y_max+round_factor, round_factor)) ax1.set_yticklabels(["{:.0f}".format(i) for i in np.arange(y_min, y_max+round_factor, round_factor)*1000], fontsize=kwargs["fsl"]) ax1.set_ylim(y_min, y_max) ax1.set_ylabel("mV", fontsize=kwargs["fsl"]) ax1.legend(handles=[b], labels=["calcium"], loc=2, fontsize=kwargs["fsl"]) ax1.set_xlabel("Time ({0})".format(unit), fontsize=kwargs["fsl"]) ax1.tick_params(axis='both', which='major', labelsize=kwargs["fsl"]) plt.tight_layout() if kwargs["photometry_pp"]["multicursor"]: multi = MultiCursor(fig.canvas, [ax0, ax1], color='r', lw=1, vertOn=[ax0, ax1]) # FIXME: unused if kwargs["save"]: plt.savefig(os.path.join(kwargs["save_dir"], "Smoothed_Signals.{0}".format(kwargs["extension"])), dpi=200.) return x, isosbestic_smoothed, calcium_smoothed
def plot(self, Ks=None, Ps=None, callput=None): import matplotlib.pyplot as plt from matplotlib.widgets import MultiCursor fig, ax = plt.subplots(1, 2) k_x = np.linspace(self.spot * 0.5, self.spot * 1.5, 200) callput_x = np.vectorize(lambda x: 1 if x > self.forward else -1)(k_x) ax[0].plot(k_x, self.cal_price(k_x, callput_x)) if Ks is not None: KC = list(zip(Ks, callput, Ps)) KC.sort(key=lambda x: x[0]) Ks, Callput, Prices = tuple(zip(*KC)) ax[0].plot(Ks, Prices, 'r.') ax[0].set_title('Fit Market Quote') ax[1].plot(k_x, self.solve_bsm_vol(k_x), label='Python solver') ax[1].set_title('Volatility Curve Comparison') ax[1].legend() cursor = MultiCursor(fig.canvas, (ax[0], ax[1]), horizOn=True, vertOn=True, useblit=True, color='black', lw=1, ls=':') plt.show()
def drawStats2(prices, period): ps2 = [p['close'] for p in prices][-140:-115] ps = [p['close'] for p in prices][-140:-120] phs = [p['high'] for p in prices][-140:-120] pls = [p['low'] for p in prices][-140:-120] l = len(prices) ts = np.arange(20) pz = np.poly1d(np.polyfit(ts, ps, 1)) phz = np.poly1d(np.polyfit(ts, phs, 1)) plz = np.poly1d(np.polyfit(ts, pls, 1)) fig = plt.figure() ax1 = fig.add_subplot(311) ax1.plot(ts, ps, '-', ts, pz(ts), '-', ts, phz(ts), '--', ts, plz(ts), '--') #plt.plot(ts, ps, 'o', label='Original data', linestyle='-', markersize=2) #plt.plot(ts, m * ts + c, 'r', label='Fitted line') #plt.legend() ax2 = fig.add_subplot(312) ax2.plot(ts, (pz(ts) - plz(ts)) - (phz(ts) - pz(ts)), '-') ax2.grid() ts2 = np.arange(len(ps2)) ax3 = fig.add_subplot(313) ax3.plot(ts2, ps2, '-') multi = MultiCursor(fig.canvas, (ax1, ax2), color='r', lw=1, horizOn=False, vertOn=True) plt.show() return
def update_figure(self, measurements, state_means, segment): # Draw plots self.top_axis, tmp_ele = bombo.PlotElevation(self.top_axis, measurements, state_means) self.bottom_axis, tmp_speed = bombo.PlotSpeed(self.bottom_axis, segment) # Add cursor def onclick(event): cursor_anchored.mouse_move(event) self.draw() if platform.system() == "Darwin": # Cursor on both plots but not linked to the trace self.multi = MultiCursor(self.fig.canvas, (self.top_axis, self.bottom_axis), color='r', lw=1, vertOn=True, horizOn=True) elif platform.system() == 'Windows': cursor_anchored = MultiCursorLinkedToTrace(self.top_axis, tmp_ele[0], tmp_ele[1], self.bottom_axis, tmp_speed[0], tmp_speed[1]) self.mpl_connect('motion_notify_event', onclick) # Draw self.fig.set_tight_layout(True) self.draw()
def plot_A_share(self, ticker): self.setting() fig = plt.figure(tight_layout=True) ax1 = fig.add_subplot(5, 2, 1) ax2 = fig.add_subplot(5, 2, 2) ax3 = fig.add_subplot(5, 2, 3) ax4 = fig.add_subplot(5, 2, 4) ax5 = fig.add_subplot(5, 2, 5) ax6 = fig.add_subplot(5, 2, 6) ax7 = fig.add_subplot(5, 2, 7) ax8 = fig.add_subplot(5, 2, 8) ax9 = fig.add_subplot(5, 2, 9) ax10 = fig.add_subplot(5, 2, 10) # 左边 self.close_df(ticker).plot(ax=ax1, sharex=ax5) self.balance_df.plot(ax=ax3) self.cash_df.plot(ax=ax5, sharex=ax5) analysis.get_drawdown_df(self.balance_df).plot(ax=ax9, sharex=ax5) holding_pnl = self.env.recorder.holding_pnl.single_dataframe() holding_pnl.rename(columns=dict(value=f'holding_pnl'), inplace=True) holding_pnl.plot(ax=ax7, sharex=ax5) # for i in self.holding_pnl_df: # i.plot(ax=ax7, sharex=ax5) # 右边 market_value = self.env.recorder.market_value.single_dataframe() market_value.rename(columns=dict(value=f'market_value'), inplace=True) market_value.plot(ax=ax2, sharex=ax5) margin = self.env.recorder.margin.single_dataframe() margin.rename(columns=dict(value=f'margin'), inplace=True) margin.plot(ax=ax4, sharex=ax5) # for i in self.positions_df: # i.plot(ax=ax2, sharex=ax5) # for i in self.margin_df: # i.plot(ax=ax4, sharex=ax5) self.realized_pnl_df.plot(ax=ax6, sharex=ax5, kind='bar') sm.qqplot(self.returns_df['returns'], dist='norm', line='s', ax=ax8, marker='.') self.returns_df[self.returns_df != 0].hist(bins=100, ax=ax10) MultiCursor(fig.canvas, (ax1, ax2, ax3, ax4, ax5, ax6, ax7, ax9), color='r', lw=1) plt.show()
def __call__(self, fig=1, Xdata_are_time=True): """ IMPORTANT : cursor objects (i.e. multi & cid) must be stored as global variables when you call the method like this : multi , cid = PnC(fig=1) """ if type(fig) is int: figobj = plt.figure(fig) elif type(fig) is matplotlib.figure.Figure: figobj = fig print( "INFO : press SPACE to record a X-value, \n press R to Remove the previously recorded one" ) def onclick_discont(event): if event.key == ' ': if Xdata_are_time: ix, iy = matplotlib.dates.num2date( event.xdata).replace(tzinfo=None), event.ydata else: ix, iy = event.xdata, event.ydata print("INFO : X value recorded : ", ix) for ax in figobj.axes: out_bar_list = stats.plot_vertical_bar_ax([ix], ax, "b", linewidth=1) self.ver_bar_stk.append(out_bar_list[0]) self.selectedX.append(ix) plt.draw() elif event.key == 'r' and len(self.selectedX) > 0: last = self.selectedX[-1] self.selectedX.remove(last) #for ax in figobj.axes: # stats.plot_vertical_bar_ax([last],ax,"r") last_bar = self.ver_bar_stk[-1] self.ver_bar_stk.remove(last_bar) last_bar.remove() print("INFO : value removed : ", last) plt.draw() return None multi = MultiCursor(figobj.canvas, figobj.axes, color='k', lw=1) cid = figobj.canvas.mpl_connect('key_press_event', onclick_discont) return multi, cid
def on_leave_axes(self, event): if event.inaxes is self._slider_ax: # 进入后会创建_slider_cursor,离开后复原 axes = [self.axes[i] for i in self._cursor_axes_index.values()] #axes = list(reversed(axes)) # 很奇怪,如果没有按顺序给出,显示会有问题。 self._cursor = MultiCursor(self._fig.canvas, axes, color='r', lw=2, horizOn=False, vertOn=True) event.canvas.draw() log.debug("on_leave_axes")
def clicd3(evt): print(evt.y)#recupere la coordonée selon y print(l3.nearest(evt.y))#reecupere le bouton le plus proche print(evt) fr=l3.nearest(evt.y) #vou[fr][i][0] #s1 = [0, 1, 4, 9, 16, 25, 36, 49, 64, 81] s2 = [] s1 = [] t=[] fig = plt.figure() ax1 = fig.add_subplot(211) ax2 = fig.add_subplot(212, sharex=ax1) for i in range(len(vou[fr]) - 11550): s1.append(vou[fr][i][0]) s2.append((vou[fr][i+1][0] -vou[fr][i][0] )/15) t.append(i) print('att') ax1.plot(t, s1) #ax2.plot(t, s2) if i==11550: del s1[i] ax2.plot(t, s2) #t=np.arange(59) print (t) print (s1) #t = range(i+1) print('bientot') #ax2 = fig.add_subplot(212, sharex=ax1) #ax2.plot(t, s2) multi = MultiCursor(fig.canvas, (ax1, ax2), color='r', lw=1) plt.show() pts = ginput(2) print(pts) x = math.floor(pts[0][0]) x1 = math.floor(pts[1][0]) y = str(s1[x]) v = str(s2[x]) y1 = str(s1[x1]) v1 = str(s2[x1]) ax1.text(0, 50, r'y(t)=' + y, fontsize=15, bbox={'facecolor': 'blue', 'alpha': 0.5, 'pad': 10}) ax2.text(0, 13, r'v(y)=' + v, fontsize=15) ax1.annotate('y(t)=' + y, xy=(x, s1[x]), xytext=(x + 1, s1[x] + 5), arrowprops=dict(facecolor='black', shrink=0.05)) ax2.annotate('v(y)=' + v, xy=(x, s2[x]), xytext=(x + 1, s2[x] + 5), arrowprops=dict(facecolor='black', shrink=0.05)) ax1.text(0, 50, r'y(t)=' + y1, fontsize=15, bbox={'facecolor': 'blue', 'alpha': 0.5, 'pad': 10}) ax2.text(0, 13, r'v(y)=' + v1, fontsize=15) ax1.annotate('y(t)=' + y1, xy=(x1, s1[x1]), xytext=(x1 + 1, s1[x1] + 5), arrowprops=dict(facecolor='black', shrink=0.05)) ax2.annotate('v(y)=' + v1, xy=(x1, s2[x1]), xytext=(x1 + 1, s2[x1] + 5), arrowprops=dict(facecolor='black', shrink=0.05)) plt.show()
def disp(self, new=False): if new: self.proj2.display(figure=self.top_ax, title=self.title) xb = self.top_ax.get_xbound() sidedisplay(self.proj1, self.side_ax) yb = self.side_ax.get_ybound() else: yb = self.side_ax.get_ybound() xb = self.top_ax.get_xbound() self.spec_ax.clear() if self.cursors.value: self.multitop = MultiCursor(self.fig.canvas, (self.spec_ax, self.top_ax), color='r', lw=1, horizOn=False, vertOn=True) self.multiside = MultiCursor(self.fig.canvas, (self.spec_ax, self.side_ax), color='r', lw=1, horizOn=True, vertOn=False) else: self.multitop = None self.multiside = None if self.posview.value: self.data.display(scale=self.scale.value, new_fig=False, figure=self.spec_ax, mpldic={'cmap': 'winter'}) if self.negview.value: self.data.display(scale=-self.scale.value, new_fig=False, figure=self.spec_ax, mpldic={'cmap': 'YlOrRd'}) self.spec_ax.set_xbound(xb) self.spec_ax.set_ybound(yb) self.fig.canvas.header_visible = False for s in ["left", "top", "right"]: self.top_ax.spines[s].set_visible(False) self.top_ax.yaxis.set_visible(False) for s in ["top", "right", "bottom"]: self.side_ax.spines[s].set_visible(False) self.side_ax.xaxis.set_visible(False)
def discont_manu_click(self, fig=1): """ manual discontinuities are both recorded in the "main" discont list and in a new discont_manu list, thus the manual discontinuites can be identified IMPORTANT : cursor objects (multi , cid) must be stored as global variables like this : multi , cid = tsout.discont_manu_click() NOTE : This method was created before point_n_click_plot(): this other one is more complete both has to be merged ASAP !!!!! """ if type(fig) is int: figobj = plt.figure(fig) elif type(fig) is plt.Figure: figobj = fig if not self.bool_discont: self.discont = [] if not self.bool_discont_manu: self.discont_manu = [] print("INFO : press SPACE to record a manual discontinuity") def onclick_discont(event): ix, iy = matplotlib.dates.num2date( event.xdata).replace(tzinfo=None), event.ydata print("INFO : discontinuity recorded : ", ix) for ax in figobj.axes: stats.plot_vertical_bar_ax([ix], ax, "g") # self.bool_discont = True self.bool_discont_manu = True self.discont.append(ix) self.discont = sorted(self.discont) self.discont_manu.append(ix) self.discont_manu = sorted(self.discont_manu) #figobj.show() plt.draw() return None multi = MultiCursor(figobj.canvas, figobj.axes, color='k', lw=1) cid = figobj.canvas.mpl_connect('key_press_event', onclick_discont) return multi, cid
def plot_exit(fig, exit_profit, exit_nbar_best, exit_nbar_worst, profits_more, risks, nbar, binwidth=1): fig.canvas.set_window_title(u'exit info') axescolor = '#f6f6f6' # the axes background color left, width = 0.1, 0.8 rect2 = [left, 0.4, width, 0.4] rect3 = [left, 0.1, width, 0.3] ax1 = fig.add_axes(rect3, axisbg=axescolor) ax2 = fig.add_axes(rect2, axisbg=axescolor, sharex=ax1) if nbar > 0: # plot ax1 profits_more.plot(ax=ax1, kind='bar', grid = False, use_index = False, label=u"%s bar more profits"%nbar) risks.plot(ax=ax1, kind='bar', grid = False, use_index = False, color = 'y', label=u"%s bar risks"%nbar) temp = risks[risks<0] ax1.plot(range(len(temp)), [temp.mean()]*len(temp), 'y--', label=u"av risk: %s"%temp.mean()) temp = profits_more[profits_more>0] ax1.plot(range(len(temp)), [temp.mean()]*len(temp), 'r--', label=u"av profits more: %s"%temp.mean()) ax1.legend(loc='upper left').get_frame().set_alpha(0.5) ax1.annotate(str(np.mean(risks)), xy=(len(exit_profit)/2, np.mean(risks)), xycoords='data', xytext=(-30, -30), textcoords='offset points', color='b', arrowprops=dict(arrowstyle="->", connectionstyle="arc3,rad=.2") ) # plot ax2 for i in xrange(len(exit_profit)): if(exit_nbar_best[i]>exit_profit[i] and exit_profit[i]>0): px21 = ax2.bar(i, exit_profit[i], width=binwidth, color='blue') px22 = ax2.bar(i, exit_nbar_best[i]-exit_profit[i], width=binwidth, color='red', bottom = exit_profit[i]) elif(exit_nbar_best[i]<exit_profit[i] and exit_profit[i]>0 and exit_nbar_best[i]>0): ax2.bar(i, exit_nbar_best[i], width=binwidth, color='red') ax2.bar(i, exit_profit[i]-exit_nbar_best[i], width=binwidth, color='blue', bottom = exit_nbar_best[i]) elif(exit_nbar_best[i]<exit_profit[i] and exit_profit[i]<0): ax2.bar(i, exit_profit[i], width=binwidth, color='red') ax2.bar(i, exit_nbar_best[i]-exit_profit[i], width=binwidth, color='blue', bottom = exit_profit[i]) elif(exit_nbar_best[i]>exit_profit[i] and exit_profit[i]<0 and exit_nbar_best[i]<0): ax2.bar(i, exit_nbar_best[i], width=binwidth, color='red') ax2.bar(i, exit_profit[i]-exit_nbar_best[i], width=binwidth, color='blue', bottom = exit_nbar_best[i]) else: ax2.bar(i, exit_nbar_best[i], width=binwidth, color='red') ax2.bar(i, exit_profit[i], width=binwidth, color='blue') ax2.legend((px21[0], px22[0]), (u'actual profit', u'more profits'),loc='upper left').get_frame().set_alpha(0.5) for ax in ax1, ax2: ax.axhline(color='k') ax.set_xticklabels([]) ax1.set_xlabel("") #ax2.set_title(u"出场相关信息", fontproperties=font_big) multi = MultiCursor(fig.canvas, fig.axes, color='r', lw=1, horizOn=False, vertOn=True) return [ax1, ax2], [multi] else: return [], []
def on_button_multicursor(self, event): from matplotlib.widgets import MultiCursor axes = self.canvas.figure.axes if event.IsChecked() and not self.multicursor and axes: # add multicursor self.multicursor = MultiCursor(self.canvas, axes, color='r', lw=1, horizOn=True, vertOn=True) elif self.multicursor: # remove multicursor self.multicursor.disconnect() self.multicursor = None self.canvas.draw() event.Skip()
def plot_strength_data(path): """ Plots the torque and velocity signals versus time in one subplot and the anatomic position signal versus time in the other subplot. Args: path: A character string with the path to the file containing isokinetic strength test data. Returns: A figure with two subplots """ # Read data if "corrected" in path: data = np.loadtxt(path) else: data = np.loadtxt(path, skiprows=6) time = data[:, 0] torque = data[:, 1] velocity = data[:, 4] angle = abs(data[:, 3]) # Detect selected isokinetic velocity if ("60gs" in path) is True: iso_vel = 60 elif ("120gs" in path) is True: iso_vel = 120 elif ("180gs" in path) is True: iso_vel = 180 # Plot fig1 = plt.figure(figsize=(18, 9)) ax1 = fig1.add_subplot(2, 1, 1) ax2 = fig1.add_subplot(2, 1, 2) # Add a multicursor to all subplotsg multi = MultiCursor(fig1.canvas, (ax1, ax2), color="k", linewidth=1) multi ax1.plot(time, torque, color="tab:blue", label="Torque (Nm)") ax1.plot(time, velocity, color="tab:orange", label="Velocity (°/s)") ax2.plot(time, angle, color="tab:green", label="Anatomical position (°)") ax1.legend(loc="upper right") ax2.legend(loc="upper right") # Add a horizontal line at torque and velocity = 0 ax1.axhline(y=0, color="tab:blue", linestyle="dotted") # Add horizontal lines at the selected isokinetic velocity ax1.axhline(y=iso_vel, color="tab:orange", linestyle="dotted") ax1.axhline(y=-iso_vel, color="tab:orange", linestyle="dotted") title = set_plot_title(path) ax1.set_title(title) plt.tight_layout() plt.show()
def init_layout(self, w_width, *args): # 布局参数 self._w_width_min = 50 self._w_width = w_width self._init_widgets(*args) self._connect() self._cursor = MultiCursor(self._fig.canvas, self.axes, color='r', lw=2, horizOn=False, vertOn=True) return self.axes
def plot_exit(fig, exit_profit, exit_nbar_best, exit_nbar_worst, profits_more, risks, nbar, binwidth=1): # fig.canvas.set_window_title('出场信息') axescolor = '#f6f6f6' # the axes background color left, width = 0.1, 0.8 rect2 = [left, 0.4, width, 0.4] rect3 = [left, 0.1, width, 0.3] ax1 = fig.add_axes(rect3, facecolor=axescolor) ax2 = fig.add_axes(rect2, facecolor=axescolor, sharex=ax1) if nbar > 0: six.print_("**66666") # plot ax1 profits_more.plot(ax=ax1, kind='bar', grid = False, use_index = False, label="%s根最优"%nbar) risks.plot(ax=ax1, kind='bar', grid = False, use_index = False, color = 'y', label="%s根最差"%nbar) temp = risks[risks<0] ax1.plot(range(len(temp)), [temp.mean()]*len(temp), 'y--', label="平均风险: %s"%temp.mean()) temp = profits_more[profits_more>0] ax1.plot(range(len(temp)), [temp.mean()]*len(temp), 'r--', label="平均更优: %s"%temp.mean()) ax1.legend(prop=font, loc='upper left').get_frame().set_alpha(0.5) #ax1.annotate(str(np.mean(risks)), xy=(len(records)/2, np.mean(risks)), xycoords='data', #xytext=(-30, -30), textcoords='offset points', color='b', #arrowprops=dict(arrowstyle="->", #connectionstyle="arc3,rad=.2") #) # plot ax2 for i in xrange(len(exit_profit)): if(exit_nbar_best[i]>exit_profit[i] and exit_profit[i]>0): px21 = ax2.bar(i, exit_profit[i], width=binwidth, color='blue') px22 = ax2.bar(i, exit_nbar_best[i]-exit_profit[i], width=binwidth, color='red', bottom = exit_profit[i]) elif(exit_nbar_best[i]<exit_profit[i] and exit_profit[i]>0 and exit_nbar_best[i]>0): ax2.bar(i, exit_nbar_best[i], width=binwidth, color='red') ax2.bar(i, exit_profit[i]-exit_nbar_best[i], width=binwidth, color='blue', bottom = exit_nbar_best[i]) elif(exit_nbar_best[i]<exit_profit[i] and exit_profit[i]<0): ax2.bar(i, exit_profit[i], width=binwidth, color='red') ax2.bar(i, exit_nbar_best[i]-exit_profit[i], width=binwidth, color='blue', bottom = exit_profit[i]) elif(exit_nbar_best[i]>exit_profit[i] and exit_profit[i]<0 and exit_nbar_best[i]<0): ax2.bar(i, exit_nbar_best[i], width=binwidth, color='red') ax2.bar(i, exit_profit[i]-exit_nbar_best[i], width=binwidth, color='blue', bottom = exit_nbar_best[i]) else: ax2.bar(i, exit_nbar_best[i], width=binwidth, color='red') ax2.bar(i, exit_profit[i], width=binwidth, color='blue') ax2.legend((px21[0], px22[0]), ('实际盈利', '延出最优盈利'),loc='upper left', prop=font).get_frame().set_alpha(0.5) ax2.set_ylabel("交易区间内的盈利", fontproperties = font) for ax in ax1, ax2: #if ax!=ax1: ax.set_xticklabels([]) ax1.set_xlabel("") ax2.set_title("出场相关信息", fontproperties=font_big) multi = MultiCursor(fig.canvas, fig.axes, color='r', lw=1, horizOn=False, vertOn=True) return [ax1, ax2], [multi] else: return [], []
def __init__(self, data, X=None, Y=None): self.data = data self.X = np.arange(self.data.shape[1]) if X is None else X self.Y = np.arange(self.data.shape[0]) if Y is None else Y vmin = np.min(self.data) vmax = np.max(self.data) # Create and displays the figure object. self.fig = plt.figure(figsize=(8,8), frameon=True, tight_layout=True) # Create grid for layout grid = GridSpec(4,4) self.ax_main = self.fig.add_subplot(grid[0:3,0:3]) #self.ax_main.autoscale(enable=True, tight=True) self.ax_main.autoscale(enable=False) self.ax_main.set_xlim(np.min(self.X), np.max(self.X)) self.ax_main.set_ylim(np.min(self.Y), np.max(self.Y)) # Use 'auto' to adjust the aspect ratio to fill the figure window, 'equal' to fix it. self.ax_main.set_aspect('auto', adjustable='box-forced') self.ax_h = self.fig.add_subplot(grid[3,0:3], sharex=self.ax_main) self.ax_h.set_axis_bgcolor('0.8') self.ax_h.autoscale(False) self.ax_h.set_ylim(vmin, vmax) self.ax_v = self.fig.add_subplot(grid[0:3,3], sharey=self.ax_main) self.ax_v.set_axis_bgcolor('0.8') self.ax_v.autoscale(False) self.ax_v.set_xlim(vmax, vmin) self.prev_pt = None self.ax_cb = None self.cursor = MultiCursor(self.fig.canvas, (self.ax_main, self.ax_h, self.ax_v), horizOn=True, vertOn=True, color='white', ls='--', lw=1) self.fig.canvas.mpl_connect('button_press_event', self._plot_clicked) # Setup control buttons btn_grid = GridSpecFromSubplotSpec(4, 1, subplot_spec=grid[3,3]) self.btn_colorbar = Button(self.fig.add_subplot(btn_grid[2,0]), 'Colorbar') self.btn_colorbar.on_clicked(self._plot_colorbar) self.btn_reset = Button(self.fig.add_subplot(btn_grid[3,0]), 'Reset') self.btn_reset.on_clicked(self._plot_reset) # Setup color range sliders self.slider_vmin = Slider(self.fig.add_subplot(btn_grid[0,0]), "vmin", vmin, vmax, valinit=vmin) self.slider_vmin.on_changed(self._plot_rangechanged) self.slider_vmax = Slider(self.fig.add_subplot(btn_grid[1,0]), "vmax", vmin, vmax, valinit=vmax, slidermin=self.slider_vmin) self.slider_vmax.on_changed(self._plot_rangechanged) self.slider_vmin.slidermax = self.slider_vmax self.fig.canvas.draw()
def analyseRelative(year, portfolio): fig1, (ax0, ax1, ax2) = setUpPlotRelative() dataList, pandaFrame = readCsvFiles(portfolio, year) dfNormalized = normalize(dataList) myNormalized = dfNormalized.plot(ax=ax0) dataRelative = relativeData(dfNormalized) myRelativePlot = dataRelative.plot(ax=ax1) multi = MultiCursor(fig1.canvas, (ax0, ax1), color='r', lw=1, horizOn=False, vertOn=True)
def _add(self): if self.show_debug_msg: print('_add()') if float(matplotlib.__version__[0:3])>=1.4: self.multi_cursor.disconnect() self.multi_cursor = MultiCursor(self.fig.canvas, (self.ax1, self.ax2, self.ax3, self.ax4), useblit=True, horizOn=False, vertOn=True, color='g', lw=1) self.span1.disconnect_events() self.span2.disconnect_events() self.span3.disconnect_events() self.span4.disconnect_events() self.span1 = SpanSelector(self.ax1, self.onselectAdd, 'horizontal', useblit=True, rectprops=dict(alpha=0.5, facecolor='green') ) self.span2 = SpanSelector(self.ax2, self.onselectAdd, 'horizontal', useblit=True, rectprops=dict(alpha=0.5, facecolor='green') ) self.span3 = SpanSelector(self.ax3, self.onselectAdd, 'horizontal', useblit=True, rectprops=dict(alpha=0.5, facecolor='green') ) self.span4 = SpanSelector(self.ax4, self.onselectAdd, 'horizontal', useblit=True, rectprops=dict(alpha=0.5, facecolor='green') ) self.mode_label['text'] = 'Mode: ADD' self.mode_label['bg'] = 'green' self.fig.canvas.draw()
class VisualizerWindow: root = [] dataMgr = [] #graphs fig = [] ax1 = [] ax2 = [] ax3 = [] ax4 = [] ylim_ax1 = [] ylim_ax2 = [] ylim_ax3 = [] #data x = [] usage_manual = [] #debug show_debug_msg = False #autosave (-1 for disable) autosave_period = 30 load_autosave_file = False def __init__(self, filename): self.root = Tk.Tk() self.root.wm_title("EMG-Visualization-Tool") self.root.protocol("WM_DELETE_WINDOW", self._quit) if not filename: filename = askopenfilename() if not filename: sys.exit(0) while not os.path.isfile(filename): showerror("File not found", "Sorry, file '{}' was not found, try again".format(filename)) filename = askopenfilename() if not filename: sys.exit(0) if filename[-19:] == '_usage_autosave.pkl': self.autosave_file = filename print('Input file is an Auto-Save file "{}"'.format(self.autosave_file)) filename = filename[:-19] + '.csv' if not os.path.isfile(filename): showerror('Could not find file "{}" (matching to provided auto-save file "{}")'.format(filename, self.autosave_file)) print('Error: matching file not found (expected "{}")'.format(filename)) print('EXIT') sys.exit(0) else: self.load_autosave_file = True else: self.autosave_file = filename.rsplit(".", 1)[0] + "_usage_autosave.pkl" if os.path.isfile(self.autosave_file): print('Auto-Save file "{}" already exists'.format(self.autosave_file)) if askyesno('Auto-Save file found', 'Auto-Save file "{}" found. Load it instead? ("No" will result in automatical overwriting of the file when auto-saving)'.format(self.autosave_file)): self.load_autosave_file = True self.root.wm_title("EMG-Visualization-Tool: {}".format(filename)) self.dataMgr = DataManager(filename) self.csv_out_file = filename.rsplit(".", 1)[0] + "_usage.csv" while os.path.isfile(self.csv_out_file): print('File "{}" already exists'.format(self.csv_out_file)) if askyesno('Overwrite File?', 'File "{}" already exists. Overwrite?'.format(self.csv_out_file)): print('overwriting "{}"'.format(self.csv_out_file)) break else: new_out_file = asksaveasfilename(initialfile=self.csv_out_file) if new_out_file: self.csv_out_file = new_out_file print('New Output file "{}"'.format(self.csv_out_file)) else: sys.exit(0) print("csv-out-file: {}".format(self.csv_out_file)) self.configFrame = Tk.Frame(self.root, height=500, width=400) Tk.Label(self.configFrame, text="\r\nPlot 1").pack() self.plot1_select = ttk.Combobox(self.configFrame, values=self.dataMgr.plot_columns, state="readonly") self.plot1_select.pack() if '"f"' in self.dataMgr.plot_columns: self.plot1_select.current(self.dataMgr.plot_columns.index('"f"')) else: self.plot1_select.current(0) Tk.Label(self.configFrame, text="Plot 2").pack() self.plot2_select = ttk.Combobox(self.configFrame, values=self.dataMgr.plot_columns, state="readonly") self.plot2_select.pack() if '"rmsd"' in self.dataMgr.plot_columns: self.plot2_select.current(self.dataMgr.plot_columns.index('"rmsd"')) else: self.plot2_select.current(0) Tk.Label(self.configFrame, text="Plot 3").pack() self.plot3_select = ttk.Combobox(self.configFrame, values=self.dataMgr.plot_columns, state="readonly") self.plot3_select.pack() if '"beat"' in self.dataMgr.plot_columns: self.plot3_select.current(self.dataMgr.plot_columns.index('"beat"')) else: self.plot3_select.current(0) Tk.Label(self.configFrame, text="\r\nUsage Plot").pack() self.usage_plots = {} for usg in self.dataMgr.usage_columns: if not usg == '"usage_manual"': chkbx_var = Tk.IntVar() chkbx_var.set(1) usg_check = ttk.Checkbutton(self.configFrame, text=usg, variable=chkbx_var) usg_check.pack() self.usage_plots[usg] = chkbx_var Tk.Label(self.configFrame, text="\r\nLoad/copy \"usage_manual\" from").pack() if self.load_autosave_file: Tk.Label(self.configFrame, text="provided Auto-Save file").pack() else: self.usg_man_select = ttk.Combobox(self.configFrame, values=self.dataMgr.usage_columns, state="readonly") self.usg_man_select.pack() if '"usage_manual"' in self.dataMgr.usage_columns: self.usg_man_select.current(self.dataMgr.usage_columns.index('"usage_manual"')) elif '"usage_total"' in self.dataMgr.usage_columns: self.usg_man_select.current(self.dataMgr.usage_columns.index('"usage_total"')) else: if len(self.dataMgr.usage_columns) > 0: self.usg_man_select.current(0) Tk.Label(self.configFrame, text="\r\nJump Column").pack() if len(self.dataMgr.jump_columns) == 0: self.jmp_select = ttk.Combobox(self.configFrame, values=['--none--'], state="readonly") self.jmp_select.current(0) else: self.jmp_select = ttk.Combobox(self.configFrame, values=self.dataMgr.jump_columns, state="readonly") if '"jump_ibi"' in self.dataMgr.jump_columns: self.jmp_select.current(self.dataMgr.jump_columns.index('"jump_ibi"')) else: self.jmp_select.current(0) self.jmp_select.pack() Tk.Label(self.configFrame, text="").pack() button_continue = Tk.Button(self.configFrame, text='Continue', command=self._CfgContinue) button_continue.pack() Tk.Label(self.configFrame, text="").pack() self.loading_label = Tk.Label(self.configFrame, text="") self.loading_label.pack() self.configFrame.pack() self.visualizerFrame = Tk.Frame(self.root) # Figure with Subplots self.fig = plt.figure(figsize=(17,8), dpi=80, tight_layout=True) gs = gridspec.GridSpec(4,1, height_ratios=[3,2,2,1]) self.ax1 = plt.subplot(gs[0]) self.ax2 = plt.subplot(gs[1], sharex=self.ax1) self.ax3 = plt.subplot(gs[2], sharex=self.ax1) self.ax4 = plt.subplot(gs[3], sharex=self.ax1) canvas = FigureCanvasTkAgg(self.fig, master=self.visualizerFrame) canvas.show() canvas.mpl_connect('key_press_event', self.on_key_event) canvas.mpl_connect('button_press_event', self.on_button_event) # GUI Elements self.mode_label = Tk.Label(self.visualizerFrame, text="Mode: ADD", background="green") self.progress_label = Tk.Label(self.visualizerFrame, text="Page {}/{}".format(self.dataMgr.current_page, self.dataMgr.num_pages)) button_prev = Tk.Button(master=self.visualizerFrame, text='Prev', command=self._prev) button_next = Tk.Button(master=self.visualizerFrame, text='Next', command=self._next) button_zoom_in = Tk.Button(master=self.visualizerFrame, text='Zoom In', command=self._zoom_in) button_zoom_out = Tk.Button(master=self.visualizerFrame, text='Zoom Out', command=self._zoom_out) button_add = Tk.Button(master=self.visualizerFrame, text='Add', command=self._add) button_del = Tk.Button(master=self.visualizerFrame, text='Del', command=self._del) saveFrame = Tk.Frame(self.visualizerFrame) button_autosave = Tk.Button(master=saveFrame, text='Auto-Save', command=self._autosave) button_save = Tk.Button(master=saveFrame, text='Save', command=self._save) button_autosave.grid(column=0, row=0) button_save.grid(column=1, row=0) button_quit = Tk.Button(master=self.visualizerFrame, text='Quit', command=self._quit) # Selection self.multi_cursor = MultiCursor(self.fig.canvas, (self.ax1, self.ax2, self.ax3, self.ax4), useblit=True, horizOn=False, vertOn=True, color='g', lw=1) self.span1 = SpanSelector(self.ax1, self.onselectAdd, 'horizontal', useblit=True, rectprops=dict(alpha=0.5, facecolor='green') ) self.span2 = SpanSelector(self.ax2, self.onselectAdd, 'horizontal', useblit=True, rectprops=dict(alpha=0.5, facecolor='green') ) self.span3 = SpanSelector(self.ax3, self.onselectAdd, 'horizontal', useblit=True, rectprops=dict(alpha=0.5, facecolor='green') ) self.span4 = SpanSelector(self.ax4, self.onselectAdd, 'horizontal', useblit=True, rectprops=dict(alpha=0.5, facecolor='green') ) # GUI Layout button_zoom_in.grid(column=0, row=0) button_zoom_out.grid(column=1, row=0) button_prev.grid(column=3, row=0) self.progress_label.grid(column=4, row=0) button_next.grid(column=5, row=0) canvas.get_tk_widget().grid(column=0, row=1, columnspan=6) canvas._tkcanvas.grid(column=0, row=1, columnspan=6) button_add.grid(column=0, row=2) button_del.grid(column=1, row=2) self.mode_label.grid(column=2, row=2, columnspan=2) saveFrame.grid(column=4, row=2) button_quit.grid(column=5, row=2) Tk.mainloop() def _CfgContinue(self): self.loading_label['text'] = 'loading ...' self.loading_label.update() self.plot_names = [self.plot1_select.get(), self.plot2_select.get(), self.plot3_select.get()] self.plot_cols = [] for pn in self.plot_names: self.plot_cols.append(self.dataMgr.header_columns.index(pn)) self.usage_names = [] self.usage_cols = [] for k,v in self.usage_plots.items(): if v.get() == 1: self.usage_names.append(k) self.usage_cols.append(self.dataMgr.header_columns.index(k)) if self.load_autosave_file: usg_manual_col = -1 else: if self.usg_man_select.get() in self.dataMgr.header_columns: usg_manual_col = self.dataMgr.header_columns.index(self.usg_man_select.get()) else: usg_manual_col = -1 if self.jmp_select.get() in self.dataMgr.jump_columns: jmp_col = self.dataMgr.header_columns.index(self.jmp_select.get()) else: jmp_col = -1 [self.x, self.plot_data, self.usage_data, self.usage_manual, self.jump_positions] = self.dataMgr.readData(self.plot_cols,self.usage_cols,self.loading_label, usg_manual_col, jmp_col) if self.load_autosave_file: infile = open(self.autosave_file, 'rb') self.usage_manual = pickle.load(infile) infile.close() self.configFrame.pack_forget() self.visualizerFrame.pack() print("displaying plots") self.ylim_ax1 = self.calc_ylims(self.plot_data[0]) self.ylim_ax2 = self.calc_ylims(self.plot_data[1]) self.ylim_ax3 = self.calc_ylims(self.plot_data[2]) self.loadPage(1) def HMS(seconds, pos): """Customized x-axis ticks Keyword arguments: seconds -- input in secs pos -- somehow required argument (matplotlib) """ seconds = int(seconds) hours = seconds / 3600 seconds -= 3600 * hours minutes = seconds / 60 seconds -= 60 * minutes if hours == 0: if minutes == 0: return "%ds" % (seconds) return "%dm%02ds" % (minutes, seconds) return "%dh%02dm" % (hours, minutes) def calc_ylims(self, data): [cnt, edge] = np.histogram(data, 25) s = len(data) thres = 0.975*s i = 0 j = len(cnt)-1 while True: if cnt[i] < cnt[j]: if s-cnt[i] < thres: break else: s -= cnt[i] i += 1 else: if s-cnt[j] < thres: break else: s -= cnt[j] j -= 1 return [min(0, edge[i]), max(1, edge[j+1])] def plotPage(self): index_low = self.dataMgr.low_Idx() index_high = self.dataMgr.high_Idx() if self.show_debug_msg: print("index_low: {} | index_high: {}".format(index_low, index_high)) self.ax1.clear() self.ax1.xaxis.set_major_formatter(plt.FuncFormatter(self.HMS)) self.ax1.plot(self.x[index_low:index_high], np.array(self.plot_data[0][index_low:index_high])) self.ax1.set_ylim(self.ylim_ax1) self.ax1.set_title(self.plot_names[0]) self.ax2.clear() self.ax2.plot(self.x[index_low:index_high], self.plot_data[1][index_low:index_high]) self.ax2.set_ylim(self.ylim_ax2) self.ax2.set_title(self.plot_names[1]) self.ax3.clear() self.ax3.plot(self.x[index_low:index_high], self.plot_data[2][index_low:index_high]) self.ax3.set_ylim(self.ylim_ax3) self.ax3.set_title(self.plot_names[2]) self.plotUsages() self.fig.canvas.draw() def plotUsages(self): index_low = self.dataMgr.low_Idx() index_high = self.dataMgr.high_Idx() self.ax4.clear() self.ax4.set_ylim(0,len(self.usage_names)+2) self.ax4.set_yticks([], minor=False) colors = ['#483D8B', '#228B22', '#B22222', '#8A2BE2', '#808000', '#FF4500', '#DA70D6', '#FFA500'] self.ax4.fill_between(self.x[index_low:index_high], 0, (len(self.usage_names)+2)*np.array(self.usage_manual[index_low:index_high]), facecolor='#7fbf7f', edgecolor='None') self.ax4.plot(self.jump_positions, [len(self.usage_names)+1]*len(self.jump_positions), 'r*') for u in range(0,len(self.usage_data)): self.ax4.fill_between(self.x[index_low:index_high], u, u+np.array(self.usage_data[u][index_low:index_high]), facecolor=colors[u], edgecolor='None') patches = [mpatches.Patch(color='green', alpha=0.5, label='usage_manual')] for i in range(0,len(self.usage_names)): patches.append(mpatches.Patch(color=colors[i], label=self.usage_names[i])) plt.legend(bbox_to_anchor=(0., 1.0, 1., .102), loc=3, ncol=5, mode="expand", borderaxespad=0., handles=patches) self.ax1.set_xlim(self.dataMgr.low_Xlimit(),self.dataMgr.high_Xlimit()) def onselectAdd(self, xmin, xmax): minIdx = max(0, round(xmin*500)) maxIdx = min(self.dataMgr.file_length-1, round(xmax*500)) if self.show_debug_msg: print("ADD: xmin: {} | xmax: {}".format(xmin, xmax)) print("ADD: minIdx: {} | maxIdx: {}".format(minIdx, maxIdx)) self.usage_manual[minIdx:maxIdx] = 1 self.plotUsages() self.fig.canvas.draw() def onselectDel(self, xmin, xmax): minIdx = max(0, round(xmin*500)) maxIdx = min(self.dataMgr.file_length-1, round(xmax*500)) if self.show_debug_msg: print("DEL: xmin: {} | xmax: {}".format(xmin, xmax)) print("DEL: minIdx: {} | maxIdx: {}".format(minIdx, maxIdx)) self.usage_manual[minIdx:maxIdx] = 0 self.plotUsages() self.fig.canvas.draw() def onselectZoom(self, xmin, xmax): if self.show_debug_msg: print("ZOOM: xmin: {} | xmax: {}".format(xmin, xmax)) self.plotUsages() self.ax1.set_xlim(xmin,xmax) self.fig.canvas.draw() def on_key_event(self, event): if self.show_debug_msg: print('you pressed %s'%event.key) if event.key == 'a': self._prev() elif event.key == 'd': self._next() elif event.key == 'w': self._add() elif event.key == 's': self._del() elif event.key == 'q': self._zoom_in() elif event.key == 'e': self._zoom_out() elif event.key == 'r': self._save() elif event.key == 'f': self._autosave() elif event.key == 'x': self._prevJump() elif event.key == 'c': self._nextJump() elif event.key == 'left': self._prev() elif event.key == 'right': self._next() elif event.key == 'up': self._add() elif event.key == 'down': self._del() def on_button_event(self, event): if self.show_debug_msg: print('you clicked %s'%event.button) if event.button == 3: #right mouse button self._zoom_out() elif event.button == 2: #middle mouse button (scroll wheel) self._zoom_in() def _quit(self): self.root.quit() # stops mainloop self.root.destroy() # this is necessary on Windows to prevent # Fatal Python Error: PyEval_RestoreThread: NULL tstate def _prev(self): if self.show_debug_msg: print('_prev()') if self.dataMgr.current_page > 1: self.loadPage(self.dataMgr.current_page-1) def _next(self): if self.show_debug_msg: print('next()') if self.dataMgr.current_page < self.dataMgr.num_pages: self.loadPage(self.dataMgr.current_page+1) def _prevJump(self): if self.show_debug_msg: print('_prevJump()') if self.dataMgr.current_page > 1: for p in reversed(self.jump_positions): num = self.dataMgr.getPageNumByX(p) if num < self.dataMgr.current_page: self.loadPage(num) break def _nextJump(self): if self.show_debug_msg: print('nextJump()') if self.dataMgr.current_page < self.dataMgr.num_pages: for p in self.jump_positions: num = self.dataMgr.getPageNumByX(p) if num > self.dataMgr.current_page: self.loadPage(num) break def loadPage(self, page_num): if self.autosave_period > -1 and page_num % self.autosave_period == 0: if self.show_debug_msg: print('autosaving on page {}'.format(page_num)) self._autosave() self.dataMgr.current_page = min(max(1, page_num), self.dataMgr.num_pages) if self.show_debug_msg: print('loadPage(): {}'.format(self.dataMgr.current_page)) self.plotPage() self.progress_label["text"] ="Page {}/{}".format(self.dataMgr.current_page, self.dataMgr.num_pages) def _add(self): if self.show_debug_msg: print('_add()') if float(matplotlib.__version__[0:3])>=1.4: self.multi_cursor.disconnect() self.multi_cursor = MultiCursor(self.fig.canvas, (self.ax1, self.ax2, self.ax3, self.ax4), useblit=True, horizOn=False, vertOn=True, color='g', lw=1) self.span1.disconnect_events() self.span2.disconnect_events() self.span3.disconnect_events() self.span4.disconnect_events() self.span1 = SpanSelector(self.ax1, self.onselectAdd, 'horizontal', useblit=True, rectprops=dict(alpha=0.5, facecolor='green') ) self.span2 = SpanSelector(self.ax2, self.onselectAdd, 'horizontal', useblit=True, rectprops=dict(alpha=0.5, facecolor='green') ) self.span3 = SpanSelector(self.ax3, self.onselectAdd, 'horizontal', useblit=True, rectprops=dict(alpha=0.5, facecolor='green') ) self.span4 = SpanSelector(self.ax4, self.onselectAdd, 'horizontal', useblit=True, rectprops=dict(alpha=0.5, facecolor='green') ) self.mode_label['text'] = 'Mode: ADD' self.mode_label['bg'] = 'green' self.fig.canvas.draw() def _del(self): if self.show_debug_msg: print('_del()') if float(matplotlib.__version__[0:3])>=1.4: self.multi_cursor.disconnect() self.multi_cursor = MultiCursor(self.fig.canvas, (self.ax1, self.ax2, self.ax3, self.ax4), useblit=True, horizOn=False, vertOn=True, color='r', lw=1) self.span1.disconnect_events() self.span1.disconnect_events() self.span2.disconnect_events() self.span3.disconnect_events() self.span4.disconnect_events() self.span1 = SpanSelector(self.ax1, self.onselectDel, 'horizontal', useblit=True, rectprops=dict(alpha=0.5, facecolor='red') ) self.span2 = SpanSelector(self.ax2, self.onselectDel, 'horizontal', useblit=True, rectprops=dict(alpha=0.5, facecolor='red') ) self.span3 = SpanSelector(self.ax3, self.onselectDel, 'horizontal', useblit=True, rectprops=dict(alpha=0.5, facecolor='red') ) self.span4 = SpanSelector(self.ax4, self.onselectDel, 'horizontal', useblit=True, rectprops=dict(alpha=0.5, facecolor='red') ) self.mode_label['text'] = 'Mode: DEL' self.mode_label['bg'] = 'red' self.fig.canvas.draw() def _zoom_in(self): if self.show_debug_msg: print('_zoom_in()') if float(matplotlib.__version__[0:3])>=1.4: self.multi_cursor.disconnect() self.multi_cursor = MultiCursor(self.fig.canvas, (self.ax1, self.ax2, self.ax3, self.ax4), useblit=True, horizOn=False, vertOn=True, color='b', lw=1) self.span1.disconnect_events() self.span1.disconnect_events() self.span2.disconnect_events() self.span3.disconnect_events() self.span4.disconnect_events() self.span1 = SpanSelector(self.ax1, self.onselectZoom, 'horizontal', useblit=True, rectprops=dict(alpha=0.5, facecolor='blue') ) self.span2 = SpanSelector(self.ax2, self.onselectZoom, 'horizontal', useblit=True, rectprops=dict(alpha=0.5, facecolor='blue') ) self.span3 = SpanSelector(self.ax3, self.onselectZoom, 'horizontal', useblit=True, rectprops=dict(alpha=0.5, facecolor='blue') ) self.span4 = SpanSelector(self.ax4, self.onselectZoom, 'horizontal', useblit=True, rectprops=dict(alpha=0.5, facecolor='blue') ) self.mode_label['text'] = 'Mode: ZOOM' self.mode_label['bg'] = 'blue' self.fig.canvas.draw() def _zoom_out(self): if self.show_debug_msg: print('_zoom_out()') self.plotUsages() self.fig.canvas.draw() def _save(self): if self.show_debug_msg: print('_save()') savetxt = plt.text(20, 20, 'saving...', fontsize=46, color='r', weight='bold', ha='center', va='top') self.fig.canvas.draw() self.dataMgr.writeCSV(self.csv_out_file, self.usage_manual) savetxt.remove() self.fig.canvas.draw() if os.path.isfile(self.autosave_file): archive_filename = self.autosave_file.rsplit(".", 1)[0] + "_old.pkl" print('renaming autosave file from "{}" to "{}"'.format(self.autosave_file, archive_filename)) if os.path.isfile(archive_filename): os.unlink(archive_filename) os.rename(self.autosave_file, archive_filename) def _autosave(self): if self.show_debug_msg: print('_autosave()') savetxt = plt.text(20, 20, 'autosaving...', fontsize=46, color='r', weight='bold', ha='center', va='top') self.fig.canvas.draw() self.dataMgr.writeAutoSave(self.autosave_file, self.usage_manual) savetxt.remove() self.fig.canvas.draw()
def __init__(self, filename): self.root = Tk.Tk() self.root.wm_title("EMG-Visualization-Tool") self.root.protocol("WM_DELETE_WINDOW", self._quit) if not filename: filename = askopenfilename() if not filename: sys.exit(0) while not os.path.isfile(filename): showerror("File not found", "Sorry, file '{}' was not found, try again".format(filename)) filename = askopenfilename() if not filename: sys.exit(0) if filename[-19:] == '_usage_autosave.pkl': self.autosave_file = filename print('Input file is an Auto-Save file "{}"'.format(self.autosave_file)) filename = filename[:-19] + '.csv' if not os.path.isfile(filename): showerror('Could not find file "{}" (matching to provided auto-save file "{}")'.format(filename, self.autosave_file)) print('Error: matching file not found (expected "{}")'.format(filename)) print('EXIT') sys.exit(0) else: self.load_autosave_file = True else: self.autosave_file = filename.rsplit(".", 1)[0] + "_usage_autosave.pkl" if os.path.isfile(self.autosave_file): print('Auto-Save file "{}" already exists'.format(self.autosave_file)) if askyesno('Auto-Save file found', 'Auto-Save file "{}" found. Load it instead? ("No" will result in automatical overwriting of the file when auto-saving)'.format(self.autosave_file)): self.load_autosave_file = True self.root.wm_title("EMG-Visualization-Tool: {}".format(filename)) self.dataMgr = DataManager(filename) self.csv_out_file = filename.rsplit(".", 1)[0] + "_usage.csv" while os.path.isfile(self.csv_out_file): print('File "{}" already exists'.format(self.csv_out_file)) if askyesno('Overwrite File?', 'File "{}" already exists. Overwrite?'.format(self.csv_out_file)): print('overwriting "{}"'.format(self.csv_out_file)) break else: new_out_file = asksaveasfilename(initialfile=self.csv_out_file) if new_out_file: self.csv_out_file = new_out_file print('New Output file "{}"'.format(self.csv_out_file)) else: sys.exit(0) print("csv-out-file: {}".format(self.csv_out_file)) self.configFrame = Tk.Frame(self.root, height=500, width=400) Tk.Label(self.configFrame, text="\r\nPlot 1").pack() self.plot1_select = ttk.Combobox(self.configFrame, values=self.dataMgr.plot_columns, state="readonly") self.plot1_select.pack() if '"f"' in self.dataMgr.plot_columns: self.plot1_select.current(self.dataMgr.plot_columns.index('"f"')) else: self.plot1_select.current(0) Tk.Label(self.configFrame, text="Plot 2").pack() self.plot2_select = ttk.Combobox(self.configFrame, values=self.dataMgr.plot_columns, state="readonly") self.plot2_select.pack() if '"rmsd"' in self.dataMgr.plot_columns: self.plot2_select.current(self.dataMgr.plot_columns.index('"rmsd"')) else: self.plot2_select.current(0) Tk.Label(self.configFrame, text="Plot 3").pack() self.plot3_select = ttk.Combobox(self.configFrame, values=self.dataMgr.plot_columns, state="readonly") self.plot3_select.pack() if '"beat"' in self.dataMgr.plot_columns: self.plot3_select.current(self.dataMgr.plot_columns.index('"beat"')) else: self.plot3_select.current(0) Tk.Label(self.configFrame, text="\r\nUsage Plot").pack() self.usage_plots = {} for usg in self.dataMgr.usage_columns: if not usg == '"usage_manual"': chkbx_var = Tk.IntVar() chkbx_var.set(1) usg_check = ttk.Checkbutton(self.configFrame, text=usg, variable=chkbx_var) usg_check.pack() self.usage_plots[usg] = chkbx_var Tk.Label(self.configFrame, text="\r\nLoad/copy \"usage_manual\" from").pack() if self.load_autosave_file: Tk.Label(self.configFrame, text="provided Auto-Save file").pack() else: self.usg_man_select = ttk.Combobox(self.configFrame, values=self.dataMgr.usage_columns, state="readonly") self.usg_man_select.pack() if '"usage_manual"' in self.dataMgr.usage_columns: self.usg_man_select.current(self.dataMgr.usage_columns.index('"usage_manual"')) elif '"usage_total"' in self.dataMgr.usage_columns: self.usg_man_select.current(self.dataMgr.usage_columns.index('"usage_total"')) else: if len(self.dataMgr.usage_columns) > 0: self.usg_man_select.current(0) Tk.Label(self.configFrame, text="\r\nJump Column").pack() if len(self.dataMgr.jump_columns) == 0: self.jmp_select = ttk.Combobox(self.configFrame, values=['--none--'], state="readonly") self.jmp_select.current(0) else: self.jmp_select = ttk.Combobox(self.configFrame, values=self.dataMgr.jump_columns, state="readonly") if '"jump_ibi"' in self.dataMgr.jump_columns: self.jmp_select.current(self.dataMgr.jump_columns.index('"jump_ibi"')) else: self.jmp_select.current(0) self.jmp_select.pack() Tk.Label(self.configFrame, text="").pack() button_continue = Tk.Button(self.configFrame, text='Continue', command=self._CfgContinue) button_continue.pack() Tk.Label(self.configFrame, text="").pack() self.loading_label = Tk.Label(self.configFrame, text="") self.loading_label.pack() self.configFrame.pack() self.visualizerFrame = Tk.Frame(self.root) # Figure with Subplots self.fig = plt.figure(figsize=(17,8), dpi=80, tight_layout=True) gs = gridspec.GridSpec(4,1, height_ratios=[3,2,2,1]) self.ax1 = plt.subplot(gs[0]) self.ax2 = plt.subplot(gs[1], sharex=self.ax1) self.ax3 = plt.subplot(gs[2], sharex=self.ax1) self.ax4 = plt.subplot(gs[3], sharex=self.ax1) canvas = FigureCanvasTkAgg(self.fig, master=self.visualizerFrame) canvas.show() canvas.mpl_connect('key_press_event', self.on_key_event) canvas.mpl_connect('button_press_event', self.on_button_event) # GUI Elements self.mode_label = Tk.Label(self.visualizerFrame, text="Mode: ADD", background="green") self.progress_label = Tk.Label(self.visualizerFrame, text="Page {}/{}".format(self.dataMgr.current_page, self.dataMgr.num_pages)) button_prev = Tk.Button(master=self.visualizerFrame, text='Prev', command=self._prev) button_next = Tk.Button(master=self.visualizerFrame, text='Next', command=self._next) button_zoom_in = Tk.Button(master=self.visualizerFrame, text='Zoom In', command=self._zoom_in) button_zoom_out = Tk.Button(master=self.visualizerFrame, text='Zoom Out', command=self._zoom_out) button_add = Tk.Button(master=self.visualizerFrame, text='Add', command=self._add) button_del = Tk.Button(master=self.visualizerFrame, text='Del', command=self._del) saveFrame = Tk.Frame(self.visualizerFrame) button_autosave = Tk.Button(master=saveFrame, text='Auto-Save', command=self._autosave) button_save = Tk.Button(master=saveFrame, text='Save', command=self._save) button_autosave.grid(column=0, row=0) button_save.grid(column=1, row=0) button_quit = Tk.Button(master=self.visualizerFrame, text='Quit', command=self._quit) # Selection self.multi_cursor = MultiCursor(self.fig.canvas, (self.ax1, self.ax2, self.ax3, self.ax4), useblit=True, horizOn=False, vertOn=True, color='g', lw=1) self.span1 = SpanSelector(self.ax1, self.onselectAdd, 'horizontal', useblit=True, rectprops=dict(alpha=0.5, facecolor='green') ) self.span2 = SpanSelector(self.ax2, self.onselectAdd, 'horizontal', useblit=True, rectprops=dict(alpha=0.5, facecolor='green') ) self.span3 = SpanSelector(self.ax3, self.onselectAdd, 'horizontal', useblit=True, rectprops=dict(alpha=0.5, facecolor='green') ) self.span4 = SpanSelector(self.ax4, self.onselectAdd, 'horizontal', useblit=True, rectprops=dict(alpha=0.5, facecolor='green') ) # GUI Layout button_zoom_in.grid(column=0, row=0) button_zoom_out.grid(column=1, row=0) button_prev.grid(column=3, row=0) self.progress_label.grid(column=4, row=0) button_next.grid(column=5, row=0) canvas.get_tk_widget().grid(column=0, row=1, columnspan=6) canvas._tkcanvas.grid(column=0, row=1, columnspan=6) button_add.grid(column=0, row=2) button_del.grid(column=1, row=2) self.mode_label.grid(column=2, row=2, columnspan=2) saveFrame.grid(column=4, row=2) button_quit.grid(column=5, row=2) Tk.mainloop()
def _activate_multicursor(self): self._deactivate_multicursor self.multicursor = MultiCursor(plt.gcf().canvas, ( self.plot_axis_z, self.plot_axis_n, self.plot_axis_e), color="blue", lw=1)
class MisfitGUI: def __init__(self, event, seismogram_generator, project, window_manager, adjoint_source_manager, iteration): # gather basic information -------------------------------------------- plt.figure(figsize=(22, 12)) self.event = event self.project = project self.process_parameters = iteration.get_process_params() self.adjoint_source_manager = adjoint_source_manager self.seismogram_generator = seismogram_generator self.window_manager = window_manager self._current_app_mode = None # setup necessary info for plot layout and buttons -------------------- self.__setup_plots() self.__connect_signals() # read seismograms, show the gui, print basic info on the screen ------ self.next() plt.tight_layout() plt.gcf().canvas.set_window_title("Misfit GUI - Press 'h' for help.") plt.show() def _activate_multicursor(self): self._deactivate_multicursor self.multicursor = MultiCursor(plt.gcf().canvas, ( self.plot_axis_z, self.plot_axis_n, self.plot_axis_e), color="blue", lw=1) def _deactivate_multicursor(self): try: self.multicursor.clear() except: pass try: del self.multicursor except: pass def __setup_plots(self): # Some actual plots. self.plot_axis_z = plt.subplot2grid((6, 20), (0, 0), colspan=18) self.plot_axis_n = plt.subplot2grid((6, 20), (1, 0), colspan=18) self.plot_axis_e = plt.subplot2grid((6, 20), (2, 0), colspan=18) # Append another attribute to the plot axis to be able to later on # identify which component they belong to. self.plot_axis_z.seismic_component = "Z" self.plot_axis_n.seismic_component = "N" self.plot_axis_e.seismic_component = "E" self._activate_multicursor() self.misfit_axis = plt.subplot2grid((6, 20), (3, 0), colspan=11, rowspan=3) self.colorbar_axis = plt.subplot2grid((6, 20), (3, 12), colspan=1, rowspan=3) # self.adjoint_source_axis = plt.subplot2grid((6, 8), (4, 0), # colspan=4, rowspan=1) self.map_axis = plt.subplot2grid((6, 20), (3, 14), colspan=7, rowspan=3) # Plot the map and the beachball. bounds = self.project.domain["bounds"] self.map_obj = visualization.plot_domain( bounds["minimum_latitude"], bounds["maximum_latitude"], bounds["minimum_longitude"], bounds["maximum_longitude"], bounds["boundary_width_in_degree"], rotation_axis=self.project.domain["rotation_axis"], rotation_angle_in_degree=self.project.domain["rotation_angle"], plot_simulation_domain=False, zoom=True) visualization.plot_events([self.event], map_object=self.map_obj) # All kinds of buttons [left, bottom, width, height] self.axnext = plt.axes([0.90, 0.95, 0.08, 0.03]) self.axprev = plt.axes([0.90, 0.90, 0.08, 0.03]) self.axreset = plt.axes([0.90, 0.85, 0.08, 0.03]) self.axautopick = plt.axes([0.90, 0.80, 0.08, 0.03]) self.bnext = Button(self.axnext, 'Next') self.bprev = Button(self.axprev, 'Prev') self.breset = Button(self.axreset, 'Reset Station') self.bautopick = Button(self.axautopick, 'Autoselect') # Axis displaying the current weight self.axweight = plt.axes([0.90, 0.75, 0.08, 0.03]) self._update_current_weight(1.0) def __connect_signals(self): self.bnext.on_clicked(self.next) self.bprev.on_clicked(self.prev) self.breset.on_clicked(self.reset) self.bautopick.on_clicked(self.autoselect_windows) self.plot_axis_z.figure.canvas.mpl_connect('button_press_event', self._onButtonPress) self.plot_axis_n.figure.canvas.mpl_connect('button_press_event', self._onButtonPress) self.plot_axis_e.figure.canvas.mpl_connect('button_press_event', self._onButtonPress) self.plot_axis_e.figure.canvas.mpl_connect('key_release_event', self._onKeyRelease) self.plot_axis_z.figure.canvas.mpl_connect('resize_event', self._on_resize) # Connect the picker. Connecting once is enough. It will still fire for # all axes. self.plot_axis_z.figure.canvas.mpl_connect('pick_event', self._on_pick) def autoselect_windows(self, event): """ Automatically select proper time windows. """ for component in ["Z", "N", "E"]: real_trace = self.data["data"].select(component=component) synth_trace = self.data["synthetics"].select(channel=component) if not real_trace or not synth_trace: continue real_trace = real_trace[0] synth_trace = synth_trace[0] windows = select_windows( real_trace, synth_trace, self.event["latitude"], self.event["longitude"], self.event["depth_in_km"], self.data["coordinates"]["latitude"], self.data["coordinates"]["longitude"], 1.0 / self.process_parameters["lowpass"], 1.0 / self.process_parameters["highpass"]) for idx_start, idx_end in windows: window_start = self.time_axis[int(round(idx_start))] window_end = self.time_axis[int(round(idx_end))] self._onWindowSelected(window_start, window_end - window_start, axis=getattr(self, "plot_axis_%s" % component.lower())) def _on_pick(self, event): artist = event.artist # Use the right mouse button for deleting windows. if event.mouseevent.button == 3: x_min = artist.get_x() x_max = x_min + artist.get_width() artist.remove() self.delete_window(x_min=x_min, x_max=x_max, component=artist.axes.seismic_component) plt.draw() if event.mouseevent.button == 1: self._onWindowSelected(artist.get_x(), artist.get_width(), artist.axes, plot_only=True) def _on_resize(self, *args): plt.tight_layout() def next(self, *args): while True: try: data = self.seismogram_generator.next() except StopIteration: print "* MEASUREMENT PROCESS FINISHED *" return if not data: continue break self.data = data self.checks_and_infos() self.update() def prev(self, *args): while True: try: data = self.seismogram_generator.prev() except StopIteration: return if not data: continue break self.data = data self.checks_and_infos() self.update() def update(self): self.selected_windows = { "Z": [], "N": [], "E": []} self.plot() for trace in self.data["data"]: windows = self.window_manager.get_windows(trace.id) if not windows or "windows" not in windows or \ not windows["windows"]: continue for window in windows["windows"]: self.plot_window( component=windows["channel_id"][-1], starttime=window["starttime"], endtime=window["endtime"], window_weight=window["weight"]) plt.draw() def checks_and_infos(self): # provide some basic screen output ----------------------------------- d = self.data["data"][0] print "============================================" print "station: " + d.stats.network + '.' + d.stats.station # loop through components and check if they are flipped -------------- for comp in {"N", "E", "Z"}: # transcribe traces synth = self.data["synthetics"].select(channel=comp)[0].data try: data = self.data["data"].select(component=comp)[0].data except IndexError: return # compute correlation coefficient -------------------------------- norm = np.sqrt(np.sum(data ** 2)) * np.sqrt(np.sum(synth ** 2)) cc = np.sum(data * synth) / norm # flip traces if correlation coefficient is close to -1 ---------- if cc < (-0.7): self.data["data"].select(component=comp)[0].data = -data print "correlation coefficient below -0.7, data fliped" print "============================================" def delete_window(self, x_min, x_max, component): trace = self.data["data"].select(component=component)[0] starttime = trace.stats.starttime + x_min endtime = trace.stats.starttime + x_max channel_id = trace.id self.window_manager.delete_window(channel_id, starttime, endtime) def plot_window(self, component, starttime, endtime, window_weight): if component == "Z": axis = self.plot_axis_z elif component == "N": axis = self.plot_axis_n elif component == "E": axis = self.plot_axis_e else: raise NotImplementedError trace = self.data["synthetics"][0] ymin, ymax = axis.get_ylim() xmin = starttime - trace.stats.starttime width = endtime - starttime height = ymax - ymin rect = Rectangle((xmin, ymin), width, height, facecolor="0.6", alpha=0.5, edgecolor="0.5", picker=True) axis.add_patch(rect) attached_text = axis.text( x=xmin + 0.02 * width, y=ymax - 0.02 * height, s=str(window_weight), verticalalignment="top", horizontalalignment="left", color="0.4", weight=1000) # Monkey patch to trigger text removal as soon as the rectangle is # removed. def remove(): super(Rectangle, rect).remove() attached_text.remove() rect.remove = remove def reset(self, *args): for trace in self.data["data"]: self.window_manager.delete_windows(trace.id) self.update() def plot(self): self.misfit_axis.cla() self.misfit_axis.set_xticks([]) self.misfit_axis.set_yticks([]) self.colorbar_axis.cla() try: self.misfit_axis.twin_axis.cla() self.misfit_axis.twin_axis.set_xticks([]) self.misfit_axis.twin_axis.set_yticks([]) del self.misfit_axis.twin_axis except: pass try: del self.rect except: pass self.rect = None # Clear all three plot axes. self.plot_axis_z.cla() self.plot_axis_n.cla() self.plot_axis_e.cla() # Set a custom tick formatter. self.plot_axis_z.yaxis.set_major_formatter(FormatStrFormatter("%.3g")) self.plot_axis_n.yaxis.set_major_formatter(FormatStrFormatter("%.3g")) self.plot_axis_e.yaxis.set_major_formatter(FormatStrFormatter("%.3g")) s_stats = self.data["synthetics"][0].stats self.time_axis = np.linspace(0, s_stats.npts * s_stats.delta, s_stats.npts) def plot_trace(axis, component): real_trace = self.data["data"].select(component=component) synth_trace = self.data["synthetics"].select(channel=component) if real_trace: axis.plot(self.time_axis, real_trace[0].data, color="black") if synth_trace: axis.plot(self.time_axis, synth_trace[0].data, color="red") if real_trace: text = real_trace[0].id axis.text( x=0.01, y=0.95, s=text, transform=axis.transAxes, bbox=dict(facecolor='white', alpha=0.5), verticalalignment="top") axis.text( x=0.01, y=0.05, s="Data Scaling Factor: %.3g" % real_trace[0].stats.scaling_factor, transform=axis.transAxes, bbox=dict( facecolor='white', alpha=0.5), verticalalignment="bottom", horizontalalignment="left") else: text = "No data, component %s" % component axis.text( x=0.01, y=0.95, s=text, transform=axis.transAxes, bbox=dict(facecolor='red', alpha=0.5), verticalalignment="top") axis.set_xlim(self.time_axis[0], self.time_axis[-1]) axis.set_ylabel("m/s") axis.grid() plot_trace(self.plot_axis_z, "Z") plot_trace(self.plot_axis_n, "N") plot_trace(self.plot_axis_e, "E") self.plot_axis_e.set_xlabel("Seconds since Event") self.plot_traveltimes() self.plot_raypath() plt.draw() def plot_traveltimes(self): great_circle_distance = locations2degrees( self.event["latitude"], self.event["longitude"], self.data["coordinates"]["latitude"], self.data["coordinates"]["longitude"]) tts = getTravelTimes(great_circle_distance, self.event["depth_in_km"], model="ak135") for component in ["z", "n", "e"]: axis = getattr(self, "plot_axis_%s" % component) ymin, ymax = axis.get_ylim() for phase in tts: if phase["phase_name"].lower().startswith("p"): color = "green" else: color = "red" axis.axvline(x=phase["time"], ymin=-1, ymax=+1, color=color, alpha=0.5) axis.set_ylim(ymin, ymax) def plot_raypath(self): try: self.greatcircle[0].remove() self.greatcircle = None except: pass try: self.station_icon.remove() self.station_icon = None except: pass self.greatcircle = self.map_obj.drawgreatcircle( self.data["coordinates"]["longitude"], self.data["coordinates"]["latitude"], self.event["longitude"], self.event["latitude"], linewidth=2, color='green', ax=self.map_axis) lng, lats = self.map_obj([self.data["coordinates"]["longitude"]], [self.data["coordinates"]["latitude"]]) self.station_icon = self.map_axis.scatter( lng, lats, facecolor="blue", edgecolor="black", zorder=10000, marker="^", s=40) def _onKeyRelease(self, event): """ Fired on all key releases. It essentially is a simple state manager with the key being routed to different places depending on the current application state. """ key = event.key # Default mode is no mode. if self._current_app_mode is None: # Enter help mode. if key == KEYMAP["show help"]: self._current_app_mode = "help" self._axes_to_restore = plt.gcf().axes self.help_axis = plt.gcf().add_axes((0, 0, 1, 1)) self.help_axis.text( 0.5, 0.8, HELP_TEXT, transform=self.help_axis.transAxes, verticalalignment="center", horizontalalignment="center") self.help_axis.set_xticks([]) self.help_axis.set_yticks([]) self._deactivate_multicursor() plt.draw() # Enter weight selection mode. elif key == KEYMAP["set weight"]: self._current_app_mode = "weight_selection" self._current_weight = "" self._update_current_weight("", editing=True) # Navigation elif key == KEYMAP["next station"]: self.next() elif key == KEYMAP["previous station"]: self.prev() elif key == KEYMAP["reset station"]: self.reset() return # Weight selection mode. elif self._current_app_mode == "weight_selection": weight_keys = "0123456789." # Keep typing the new weight. if key in weight_keys: self._current_weight += key self._update_current_weight(self._current_weight, editing=True) # Set the new weight. If that fails, reset it. In any case, leave # the weight selection mode. else: self._current_app_mode = None try: weight = float(self._current_weight) except: self._update_current_weight(self.weight) return self._update_current_weight(weight) # Help selection mode. Any keypress while in it will exit it. elif self._current_app_mode == "help": plt.delaxes(self.help_axis) del self.help_axis for ax in self._axes_to_restore: plt.gcf().add_axes(ax) del self._axes_to_restore plt.tight_layout() self._activate_multicursor() plt.draw() self._current_app_mode = None return def _update_current_weight(self, weight, editing=False): try: self._weight_text.remove() except: pass self._weight_text = self.axweight.text( x=0.5, y=0.5, s="Weight: %s" % str(weight), transform=self.axweight.transAxes, verticalalignment="center", horizontalalignment="center") self.axweight.set_xticks([]) self.axweight.set_yticks([]) if editing: self.axweight.set_axis_bgcolor("red") else: if isinstance(weight, float): self.weight = weight else: msg = "Weight '%s' is not a proper float." % str(weight) warnings.warn(msg) self._update_current_weight(self.weight) self.axweight.set_axis_bgcolor("white") plt.draw() def _onButtonPress(self, event): if event.button != 1: # or event.inaxes != self.plot_axis_z: return # Store the axis. if event.name == "button_press_event": if event.inaxes == self.plot_axis_z: data = self.data["data"].select(component="Z") if not data: return self.rect = WindowSelectionRectangle(event, self.plot_axis_z, self._onWindowSelected) if event.inaxes == self.plot_axis_n: data = self.data["data"].select(component="N") if not data: return self.rect = WindowSelectionRectangle(event, self.plot_axis_n, self._onWindowSelected) if event.inaxes == self.plot_axis_e: data = self.data["data"].select(component="E") if not data: return self.rect = WindowSelectionRectangle(event, self.plot_axis_e, self._onWindowSelected) def _onWindowSelected(self, window_start, window_width, axis, plot_only=False): """ Function called upon window selection. :param plot_only: If True, do not write anything to disk, but only plot. """ # Initialisation ----------------------------------------------------- # Minimum window length is 50 samples. delta = self.data["synthetics"][0].stats.delta if window_width < 50 * delta: plt.draw() return data = self.data["data"].select(component=axis.seismic_component)[0] synth = self.data["synthetics"].select( channel=axis.seismic_component)[0] if not data: plt.draw() return trace = data time_range = trace.stats.endtime - trace.stats.starttime plot_range = axis.get_xlim()[1] - axis.get_xlim()[0] starttime = trace.stats.starttime + (window_start / plot_range) * \ time_range endtime = starttime + window_width / plot_range * time_range if plot_only is not True: self.window_manager.write_window( trace.id, starttime, endtime, self.weight, "cosine", "TimeFrequencyPhaseMisfitFichtner2008") self.plot_window(component=trace.id[-1], starttime=starttime, endtime=endtime, window_weight=self.weight) # window data and synthetics ----------------------------------------- # Decimal percentage of cosine taper (ranging from 0 to 1). Set to the # fraction of the minimum period to the window length. taper_percentage = np.min( [1.0, 1.0 / self. process_parameters["lowpass"] / window_width]) # data data_trimmed = data.copy() data_trimmed.trim(starttime, endtime) data_trimmed.taper(type='cosine', max_percentage=0.5 * taper_percentage) data_trimmed.trim(synth.stats.starttime, synth.stats.endtime, pad=True, fill_value=0.0) # synthetics synth_trimmed = synth.copy() synth_trimmed.trim(starttime, endtime) synth_trimmed.taper(type='cosine', max_percentage=0.5 * taper_percentage) synth_trimmed.trim(synth.stats.starttime, synth.stats.endtime, pad=True, fill_value=0.0) # make time axis t = np.linspace(0, synth.stats.npts * synth.stats.delta, synth.stats.npts) # clear axes of misfit plot ------------------------------------------ self.misfit_axis.cla() self.colorbar_axis.cla() try: self.misfit_axis.twin_axis.cla() self.misfit_axis.twin_axis.set_xticks([]) self.misfit_axis.twin_axis.set_yticks([]) except: pass # set data and synthetics, compute actual misfit --------------------- t = np.require(t, dtype="float64", requirements="C") data_d = np.require(data_trimmed.data, dtype="float64", requirements="C") synth_d = np.require(synth_trimmed.data, dtype="float64", requirements="C") # compute misfit and adjoint source adsrc = adsrc_tf_phase_misfit( t, data_d, synth_d, 1.0 / self.process_parameters["lowpass"], 1.0 / self.process_parameters["highpass"], axis=self.misfit_axis, colorbar_axis=self.colorbar_axis) # plot misfit distribution ------------------------------------------- # Format all the axis. self.misfit_axis.yaxis.set_major_formatter(FormatStrFormatter("%.3f")) self.misfit_axis.twin_axis.yaxis.set_major_formatter( FormatStrFormatter("%.2g")) self.colorbar_axis.yaxis.set_major_formatter( FormatStrFormatter("%.1f")) plt.tight_layout() plt.draw() # write adjoint source to file --------------------------------------- if plot_only is not True: self.adjoint_source_manager.write_adjoint_src( adsrc["adjoint_source"], trace.id, starttime, endtime)