def log(self, message): """ This method displays the message including a timestamp. It further stores the log message, including the timestamp, in the internal storage. =========== Parameters: =========== message : `string` The log message to be displayed ======== Returns: ======== (nothing) """ curtime = int(time.time() - self.time0) # compute h, m, s curh = curtime // 3600 curm = mod(curtime // 60, 60) curs = mod(curtime, 60) timestring = 'time: %02i:%02i:%02i' % (curh, curm, curs) logstring = ' '.join([timestring, message]) self.logstrings.append(logstring) print logstring
def _grad_theta(psi, xxx_todo_changeme1): """ Compute the 1D gradient of a scalar field in the theta direction on a unit- radius spherical shell. Assumes psi is a 2D array with theta changing along axis 1. We use central differences for interior points, one-sided differences for exterior points, and address simple periodic boundaries. """ (phi,theta) = xxx_todo_changeme1 dphi = p.diff(phi,axis=0) dtheta = p.diff(theta,axis=1) # pre-allocate output grid dpsidtheta = p.zeros(theta.shape) # use weighted central differences to compute theta gradient on the interior dpsidtheta[:,1:-1] = (((p.diff(psi[:,:-1],axis=1) / dtheta[:,:-1]**2 + p.diff(psi[:,1:],axis=1) / dtheta[:,1:]**2) / (1/dtheta[:,:-1] + 1/dtheta[:,1:]) ) ) # compute theta gradients at exterior points if p.mod(theta[0,0],2*p.pi) == p.mod(theta[0,-1],2*p.pi): # use weighted central differences to compute gradient if periodic boundary dpsidtheta[:,[0,-1]] = p.tile(((p.diff(psi[:,:2],axis=1) / dtheta[:,0]**2 + p.diff(psi[:,-2:],axis=1) / dtheta[:,-1]**2) / (1/dtheta[:,0] + 1/dtheta[:-1]) ), (1,2) ) else: # use one-sided difference to compute gradient if not a periodic boundary dpsidtheta[:,-1] = (p.diff(psi[:,-2:],axis=1).T / dtheta[:,-1]) dpsidtheta[:,0] = (p.diff(psi[:,:2],axis=1).T / dtheta[:,0]) return dpsidtheta
def title_hours(current_data): from pylab import title, mod t = current_data.t hours = int(t / 3600.) tmin = mod(t, 3600.) min = int(tmin / 60.) tsec = mod(tmin, 60.) sec = int(mod(tmin, 60.)) timestr = '%s:%s:%s' % (hours, str(min).zfill(2), str(sec).zfill(2)) title('%s after earthquake' % timestr)
def haversine (latlong1, latlong2, r): deltaLatlong = latlong1 - latlong2 dLat = deltaLatlong[0] dLon = deltaLatlong[1] lat1 = latlong1[0] lat2 = latlong2[0] a = (sin (dLat/2) * sin (dLat/2) + sin (dLon/2) * sin (dLon/2) * cos (lat1) * cos (lat2)) c = 2 * arctan2 (sqrt (a), sqrt (1-a)) d = r * c # initial bearing y = sin (dLon) * cos (lat2) x = (cos (lat1)*sin (lat2) - sin (lat1)*cos (lat2)*cos (dLon)) b1 = arctan2 (y, x); # final bearing dLon = -dLon dLat = -dLat tmp = lat1 lat1 = lat2 lat2 = tmp y = sin (dLon) * cos (lat2) x = (cos (lat1) * sin (lat2) - sin (lat1) * cos (lat2) * cos (dLon)) b2 = arctan2 (y, x) b2 = mod ((b2 + pi), 2*pi) return (d, b1, b2)
def haversine(latlong1, latlong2, r): deltaLatlong = latlong1 - latlong2 dLat = deltaLatlong[0] dLon = deltaLatlong[1] lat1 = latlong1[0] lat2 = latlong2[0] a = (sin(dLat / 2) * sin(dLat / 2) + sin(dLon / 2) * sin(dLon / 2) * cos(lat1) * cos(lat2)) c = 2 * arctan2(sqrt(a), sqrt(1 - a)) d = r * c # initial bearing y = sin(dLon) * cos(lat2) x = (cos(lat1) * sin(lat2) - sin(lat1) * cos(lat2) * cos(dLon)) b1 = arctan2(y, x) # final bearing dLon = -dLon dLat = -dLat tmp = lat1 lat1 = lat2 lat2 = tmp y = sin(dLon) * cos(lat2) x = (cos(lat1) * sin(lat2) - sin(lat1) * cos(lat2) * cos(dLon)) b2 = arctan2(y, x) b2 = mod((b2 + pi), 2 * pi) return (d, b1, b2)
def upper_phases(phases, sep=pi, return_indices=False): """ returns only phases in the "upper half": x if pi <= x mod (2*pi) < 2 *pi *NOTE* by choosing "sep=0", this function returns the _lower_ phases instead! :args: phases: an iterable object, interpreted as phases to sort sep (float, default: pi): the separation between "low" and "high". Note that the intervals will be "wrapped around 2 pi", and will always be of width pi. This is equivalently to shifting every element of phases by -x (-pi) return_indices (bool): return indices instead of values """ if not return_indices: up = [x for x in phases if mod(x - sep + pi, 2.*pi) >= pi] else: up = [idx for idx, x in enumerate(phases) if mod(x - sep + pi, 2.*pi) >= pi] return up
def _generate_feature_development_plots(self, important_features): """ This function generates the actual histogram plot""" # Everything is done class-wise for label in important_features.keys(): # Axis limits are determined by the global maxima (minVal, maxVal) = (important_features[label].min(0).min(0), important_features[label].max(0).max(0)) nr_chans = pylab.shape(important_features[label])[0] myFig = pylab.figure() myFig.set_size_inches((40,nr_chans)) for i_chan in range(nr_chans): ax = myFig.add_subplot(nr_chans, 1, i_chan+1) # cycle line colors if (pylab.mod(i_chan,2) == 0): myCol = '#000080' else: myCol = '#003EFF' # plot features and black zero-line pylab.plot(important_features[label][i_chan,:],color=myCol) pylab.plot(range(len(important_features[label][i_chan,:])), pylab.zeros(len(important_features[label][i_chan,:])), 'k--') pylab.ylim((minVal,maxVal)) xmax = pylab.shape(important_features[label])[1] pylab.xlim((0,xmax)) # draw vertical dashed line every 20 epochs for vertical_line_position in range(0,xmax+1,20): pylab.axvline(x=vertical_line_position, ymin=0, ymax=1, color='k', linestyle='--') # write title above uppermost subplot if i_chan+1 == 1: pylab.title('Feature development: Amplitudes of %s Epochs' % label, fontsize=40) # adjust the axes, i.e. remove upper and right, # shift the left to avoid overlaps, # and lower axis only @ bottom subplot if i_chan+1 < nr_chans: self._adjust_spines(ax,['left'],i_chan) else: self._adjust_spines(ax,['left', 'bottom'],i_chan) pylab.xlabel('Number of Epoch', fontsize=36) # Write feature name next to the axis pylab.ylabel(self.corr_important_feat_names[i_chan], fontsize=20, rotation='horizontal') # remove whitespace between subplots etc. myFig.subplots_adjust(bottom=0.03,left=0.08,right=0.97, top=0.94,wspace=0,hspace=0) self.feature_development_plot[label] = myFig
def upper_phases(phases, sep=pi, return_indices=False): """ returns only phases in the "upper half": x if pi <= x mod (2*pi) < 2 *pi *NOTE* by choosing "sep=0", this function returns the _lower_ phases instead! :args: phases: an iterable object, interpreted as phases to sort sep (float, default: pi): the separation between "low" and "high". Note that the intervals will be "wrapped around 2 pi", and will always be of width pi. This is equivalently to shifting every element of phases by -x (-pi) return_indices (bool): return indices instead of values """ if not return_indices: up = [x for x in phases if mod(x - sep + pi, 2. * pi) >= pi] else: up = [ idx for idx, x in enumerate(phases) if mod(x - sep + pi, 2. * pi) >= pi ] return up
def _grad_phi(psi, xxx_todo_changeme): """ Compute the 1D gradient of a scalar field in the phi direction on a unit- radius spherical shell. Assumes psi is a 2D array with phi changing along axis 0. We use central differences for interior points, one-sided differences for exterior points, and address simple periodic boundaries. """ (phi,theta) = xxx_todo_changeme dphi = p.diff(phi,axis=0) dtheta = p.diff(theta,axis=1) # pre-allocate output grid dpsidphi = p.zeros(phi.shape) # use weighted central differences to compute gradient on the interior dpsidphi[1:-1,:] = (((p.diff(psi[:-1,:],axis=0) / dphi[:-1,:]**2 + p.diff(psi[1:,:],axis=0) / dphi[1:,:]**2) / (1/dphi[:-1,:] + 1/dphi[1:,:]) ) * 1./p.sin(theta[1:-1,:]) ) # compute phi gradients at exterior points if p.mod(phi[0,0],2*p.pi) == p.mod(phi[-1,0],2*p.pi): # use weighted central differences to compute gradient if periodic boundary dpsidphi[[0,-1],:] = p.tile(((p.diff(psi[:2,:],axis=0) / dphi[0,:]**2 + p.diff(psi[-2:,:],axis=0) / dphi[-1,:]**2) / (1/dphi[0,:] + 1/dphi[-1,:]) ) * 1./p.sin(theta[0,:]), (2,1) ) else: # use one-sided difference to compute gradient if not a periodic boundary dpsidphi[-1,:] = (p.diff(psi[-2:,:],axis=0) / dphi[-1,:] / p.sin(theta[-1,:]) ) dpsidphi[0,:] = (p.diff(psi[:2,:],axis=0) / dphi[0,:] / p.sin(theta[0,:]) ) return dpsidphi
def genIm(self, dlg, imb, mdh): pixelSize = dlg.getPixelSize() if not pylab.mod(pylab.log2(pixelSize/self.visFr.QTGoalPixelSize), 1) == 0:#recalculate QuadTree to get right pixel size self.visFr.QTGoalPixelSize = pixelSize self.visFr.Quads = None self.visFr.GenQuads() qtWidth = self.visFr.Quads.x1 - self.visFr.Quads.x0 qtWidthPixels = pylab.ceil(qtWidth/pixelSize) im = pylab.zeros((qtWidthPixels, qtWidthPixels)) QTrend.rendQTa(im, self.visFr.Quads) return im[(imb.x0/pixelSize):(imb.x1/pixelSize),(imb.y0/pixelSize):(imb.y1/pixelSize)]
def diff_f(x, fs=1.): """ A Fourier-based differentiator *changed 02 / 2014* The signal is "periodified", that is it is reflected and concatenated with the original signal. The resulting signal has no discontinuities and no trend. (Code added but disabled; not functional; comment below is still up to date) *HINT* A Fourier series implicitly assumes that the data is a window of a periodicit signal with the window length as period. This implies that if the first and the last point of the data are not 'close', a jump is assumed, which will be reflected in a 'jump' of the derivative at the beginning and the end of the signal. To circumvent this, the baseline is separated and derived separately. =========== Parameters: =========== a : *array* (1D) The array which should be integrated fs : *float* sampling time of the data ======== Returns: ======== y : *array* (1D) The integrated array """ #xp = hstack([x, x[::-1]]) #return diff_f0(xp)[:len(x)] if True: baseline0 = linspace(x[0], x[-1], len(x), endpoint=True) x0 = x - baseline0 baseline1 = 0 * baseline0 if mod(len(x), 2) == 0: baseline1 = -1.* (2. * fft.fft(x0)[len(x0) / 2].real / float(len(x0)) * arange(len(x0))) x0 = x0 - baseline1 # x0 can now be integrated and differentiated using diff_f0, int_f0 baseline = baseline0 + baseline1 return diff_f0(x0, float(fs)) + (baseline[1] - baseline[0]) * fs
def diff_f(x, fs=1.): """ A Fourier-based differentiator *changed 02 / 2014* The signal is "periodified", that is it is reflected and concatenated with the original signal. The resulting signal has no discontinuities and no trend. (Code added but disabled; not functional; comment below is still up to date) *HINT* A Fourier series implicitly assumes that the data is a window of a periodicit signal with the window length as period. This implies that if the first and the last point of the data are not 'close', a jump is assumed, which will be reflected in a 'jump' of the derivative at the beginning and the end of the signal. To circumvent this, the baseline is separated and derived separately. =========== Parameters: =========== a : *array* (1D) The array which should be integrated fs : *float* sampling time of the data ======== Returns: ======== y : *array* (1D) The integrated array """ #xp = hstack([x, x[::-1]]) #return diff_f0(xp)[:len(x)] if True: baseline0 = linspace(x[0], x[-1], len(x), endpoint=True) x0 = x - baseline0 baseline1 = 0 * baseline0 if mod(len(x), 2) == 0: baseline1 = -1. * (2. * fft.fft(x0)[len(x0) / 2].real / float(len(x0)) * arange(len(x0))) x0 = x0 - baseline1 # x0 can now be integrated and differentiated using diff_f0, int_f0 baseline = baseline0 + baseline1 return diff_f0(x0, float(fs)) + (baseline[1] - baseline[0]) * fs
def readhistograms( self ): ################################################################################## # # Reads all histograms into a list of numpy arrays # ################################################################################## self.fobj.seek(0) # go back to beginning because 'DataOffset' is measured from there. binarydata = self.fobj.read() self.curves = [] for i,curve in enumerate( self.curveheaders ): # This will typically be waaay too long and will be padded with zeros because it # can accomodate up to 2**16 histogram bins but our laser rep rate is ~76MHz, so # if you were set at 4ps resolution, that would only require 1/76MHz/4ps ~ 3281 bins # # It's worth noting that when we wrap the curve (move data from before laser to after), # there is going to be some small error in the timing because the number of bins will # not be an exact integer. This error will be at most the resolution, which is likely # to be either really small compared to the lifetime of the emitter or, if the lifetime # is really short, the fluorescence will have decayed before the end of the un-wrapped # curve. The only time this could be an issue is if the lifetime is really short and # the peak in lifetime occurrs at the very end of the un-wrapped curve. Then you should # insert enough BNC cable to bring the peak back toward the front of the un-wrapped curve. zeropadded = pylab.np.array( struct.unpack_from( "="+str(curve['Channels'])+"l", binarydata, offset=curve['DataOffset'] ), dtype=pylab.np.int ) nbins = 1.0/self.curveheaders[0]['InpRate0']/self.curveheaders[0]['Resolution']/1.0e-9 nfullbins = pylab.floor( nbins ) npartialbins = pylab.mod( nbins, 1 ) if npartialbins > 0.0: # I think in this case (which is almost always the case), the first bin is sometimes # the 'partial' bin, and the last bin is sometimes the 'partial' bin. So we'll delete them. # (or uncomment other line to add them.) ###zeropadded[0] += zeropadded[ nfullbins ] # add the partial bin to the first bin self.curves.append( zeropadded[1:nfullbins] ) else: self.curves.append( zeropadded[:nfullbins] ) self.raw_curves = self.curves[:]
def plot_mtx(m, beats=4,tick=0.25, **kwargs): """ Plot piano-roll matrix """ figure() kwargs.setdefault('cmap',cm.ocean_r) imshow(m,aspect='auto',origin='bottom',**kwargs) nr,nc = m.shape xt = arange(0,nc,beats/tick) xticks(xt,arange(1,len(xt)+1)) grid(axis='x',linestyle='--') pc=['C','C#','D','Eb','E','F','F#','G','G#','A','Bb','B'] yt = arange(0,nr+1) yticks(yt,array(pc)[mod(yt,12)],fontsize=6) #grid(axis='y') staff_lines = array([4,7,11,14,17]) staff_lines = array([staff_lines+12,staff_lines+36,staff_lines+60,staff_lines+84,staff_lines+108]).flatten() plot(c_[zeros(len(staff_lines)),nc*ones(len(staff_lines))].T,c_[staff_lines,staff_lines].T,'k')
def int_f0(x, fs=1.): """ returns the 'basic' fourier integration of a signal """ # define frequencies T = len(x) / float(fs) freqs = 1. / T * arange(len(x)) freqs[len(freqs) // 2 + 1:] -= float(fs) spec = fft.fft(x) spec_i = zeros_like(spec, dtype=complex) # exclude frequency 0 - it cannot be integrated spec_i[1:] = spec[1:] / (2j * pi* freqs[1:]) if mod(len(x), 2) == 0: spec_i[len(x) // 2] = 0. sig_d = fft.ifft(spec_i) return sig_d.real
def int_f0(x, fs=1.): """ returns the 'basic' fourier integration of a signal """ # define frequencies T = len(x) / float(fs) freqs = 1. / T * arange(len(x)) freqs[len(freqs) // 2 + 1:] -= float(fs) spec = fft.fft(x) spec_i = zeros_like(spec, dtype=complex) # exclude frequency 0 - it cannot be integrated spec_i[1:] = spec[1:] / (2j * pi * freqs[1:]) if mod(len(x), 2) == 0: spec_i[len(x) // 2] = 0. sig_d = fft.ifft(spec_i) return sig_d.real
def _adjust_spines(self,ax,spines,i_chan): """ Essentially, removes most of the axes in the feature development plots. Also produces the alternating shift of the left axes. """ for loc, spine in ax.spines.iteritems(): if loc in spines: if ((loc=='left') and (pylab.mod(i_chan,2) == 0)): spine.set_position(('outward',5)) else: spine.set_position(('outward',30)) # outward by 10 points else: spine.set_color('none') # don't draw spine ax.yaxis.set_ticks_position('left') if 'bottom' in spines: ax.xaxis.set_ticks_position('bottom') for tick in ax.xaxis.get_major_ticks(): tick.label1.set_fontsize(30) else: ax.xaxis.set_ticks([]) # no xaxis ticks
def cullonce(self,resolution,evenoddchoice): x=self['x']; difx=numpy.diff(x); difx=numpy.hstack((difx,resolution*2)); I1=range(len(x)); I=numpy.core.logical_or(difx>resolution, pylab.mod(I1,2)==evenoddchoice); #I=[]; #i=0; #while i <len(difx): # I.append(i); # if difx[i]<resolution: # i=i+2; # else: # i=i+1; #I.append(len(x)-1); #I=numpy.array(I); #print "shape before",x.shape self['x']=self['x'][I]; self['y']=self['y'][I];
def diff_f0(x, fs=1.): """ returns the 'basic' fourier derivative of a signal """ # define frequencies T = len(x) / float(fs) freqs = 1. / T * arange(len(x)) freqs[len(freqs) // 2 + 1:] -= float(fs) spec = fft.fft(x) spec_i = spec * (2j * pi* freqs) # if an even number of frames is recorded, an alternating signal (the # highest single frequency) cannot be 'sampled' -> set to 0. # for example: consider x = [0 1], making this a periodic function will # give [0 1 0 1 0 1], and at each point its derivative is 0 because of # symmetry arguments if mod(len(x), 2) == 0: spec_i[len(x) // 2] = 0. sig_d = fft.ifft(spec_i) return sig_d.real
def diff_f0(x, fs=1.): """ returns the 'basic' fourier derivative of a signal """ # define frequencies T = len(x) / float(fs) freqs = 1. / T * arange(len(x)) freqs[len(freqs) // 2 + 1:] -= float(fs) spec = fft.fft(x) spec_i = spec * (2j * pi * freqs) # if an even number of frames is recorded, an alternating signal (the # highest single frequency) cannot be 'sampled' -> set to 0. # for example: consider x = [0 1], making this a periodic function will # give [0 1 0 1 0 1], and at each point its derivative is 0 because of # symmetry arguments if mod(len(x), 2) == 0: spec_i[len(x) // 2] = 0. sig_d = fft.ifft(spec_i) return sig_d.real
def _adjust_spines(self, ax, spines, i_chan): """ Essentially, removes most of the axes in the feature development plots. Also produces the alternating shift of the left axes. """ for loc, spine in ax.spines.iteritems(): if loc in spines: if ((loc == 'left') and (pylab.mod(i_chan, 2) == 0)): spine.set_position(('outward', 5)) else: spine.set_position(('outward', 30)) # outward by 10 points else: spine.set_color('none') # don't draw spine ax.yaxis.set_ticks_position('left') if 'bottom' in spines: ax.xaxis.set_ticks_position('bottom') for tick in ax.xaxis.get_major_ticks(): tick.label1.set_fontsize(30) else: ax.xaxis.set_ticks([]) # no xaxis ticks
def q0(self,x): #============================== """Evaluate initial condition""" if self.bcLeft==2: #Periodic BCs x=pl.mod(x-self.xlower,self.xupper-self.xlower)+self.xlower # Eventually: a case statement for different values of self.ic #C5 Newton polynomial: x0=self.x0 a=self.a q=pl.array([0.,0.]) mat=self.getmat(x) z=self.z[mat] if abs(x-x0)<=a: q[0]=(x-x0-a)**6 * (x-x0+a)**6/a**12 q[1]=q[0]/z #Purely right-going since Z=1 return q
def q0(self, x): #============================== """Evaluate initial condition""" if self.bcLeft == 2: #Periodic BCs x = pl.mod(x - self.xlower, self.xupper - self.xlower) + self.xlower # Eventually: a case statement for different values of self.ic #C5 Newton polynomial: x0 = self.x0 a = self.a q = pl.array([0., 0.]) mat = self.getmat(x) z = self.z[mat] if abs(x - x0) <= a: q[0] = (x - x0 - a)**6 * (x - x0 + a)**6 / a**12 q[1] = q[0] / z #Purely right-going since Z=1 return q
def add_to_legend(self, linefmt, textstr): """ adds an item to the legend and draws the legend note: the legend itself is stored in <object>.legend_entries Parameters: ----------- linefmt : *dict* properties of the line to draw textstr : *str* text of the legend entry Returns: -------- (None) """ # compute position for legend_entry: le_row = mod(len(self.legend_entries), self.layout['legend_rows']) le_col = len(self.legend_entries) // self.layout['legend_rows'] # print 'row / col: ', le_row, le_col # legend margins lm = self.layout.get('legend_margins', (2, 2, 10, 10)) inner_width = ( float(self.haxes * self.width - lm[2] - lm[3]) / (self.haxes * self.width)) #print 'inner width:', inner_width inner_height = float(self.legendheight * self.height - lm[0] - lm[1]) / (self.legendheight * self.height) btmline = float(lm[0]) / (self.legendheight * self.height) lmargin = float(lm[2]) / (self.haxes * self.width) #lm #print 'btmline: ', btmline #print 'lmargin: ', lmargin fontheight = (float(self.layout.get('legend_fontsize', 10.)) * 25.4 / 72. / (self.legendheight * self.height)) # abs. #print 'fontheight:', fontheight line_x = (lmargin + (float(le_col) / float(self.layout['legend_cols'] + 1.)) / inner_width) lsp = self.layout.get('legend_textvspace', 1.2) times_fh = lsp * float(self.layout['legend_rows'] - le_row) line_y = btmline + fontheight * times_fh - fontheight / 2. line_length = (float(self.layout.get('legend_linelength', 8.)) / (self.haxes * self.width)) line_text_sep = (float(self.layout.get('legend_line_text_sep', 1.)) / (self.haxes * self.width)) self.legline = [[line_x, line_x + line_length], [line_y, line_y]] self.legendax.plot(*self.legline, **linefmt) self.legend_entries.append(self.legendax.text( line_x + line_length + line_text_sep, line_y - fontheight / 4., textstr, va='baseline', ha='left', fontsize=self.layout.get('legend_fontsize', 10))) self.legendax.set_xlim(0, 1) self.legendax.set_ylim(0, 1) self.legendax.set_xticks([]) self.legendax.set_yticks([])
def _generate_feature_development_plots(self, important_features): """ This function generates the actual histogram plot""" # Everything is done class-wise for label in important_features.keys(): # Axis limits are determined by the global maxima (minVal, maxVal) = (important_features[label].min(0).min(0), important_features[label].max(0).max(0)) nr_chans = pylab.shape(important_features[label])[0] myFig = pylab.figure() myFig.set_size_inches((40, nr_chans)) for i_chan in range(nr_chans): ax = myFig.add_subplot(nr_chans, 1, i_chan + 1) # cycle line colors if (pylab.mod(i_chan, 2) == 0): myCol = '#000080' else: myCol = '#003EFF' # plot features and black zero-line pylab.plot(important_features[label][i_chan, :], color=myCol) pylab.plot( range(len(important_features[label][i_chan, :])), pylab.zeros(len(important_features[label][i_chan, :])), 'k--') pylab.ylim((minVal, maxVal)) xmax = pylab.shape(important_features[label])[1] pylab.xlim((0, xmax)) # draw vertical dashed line every 20 epochs for vertical_line_position in range(0, xmax + 1, 20): pylab.axvline(x=vertical_line_position, ymin=0, ymax=1, color='k', linestyle='--') # write title above uppermost subplot if i_chan + 1 == 1: pylab.title( 'Feature development: Amplitudes of %s Epochs' % label, fontsize=40) # adjust the axes, i.e. remove upper and right, # shift the left to avoid overlaps, # and lower axis only @ bottom subplot if i_chan + 1 < nr_chans: self._adjust_spines(ax, ['left'], i_chan) else: self._adjust_spines(ax, ['left', 'bottom'], i_chan) pylab.xlabel('Number of Epoch', fontsize=36) # Write feature name next to the axis pylab.ylabel(self.corr_important_feat_names[i_chan], fontsize=20, rotation='horizontal') # remove whitespace between subplots etc. myFig.subplots_adjust(bottom=0.03, left=0.08, right=0.97, top=0.94, wspace=0, hspace=0) self.feature_development_plot[label] = myFig
#convert to arrays pval_array = numpy.array(pval_list) mean_diff_array = numpy.array(mean_diff_list) t = df.data['t'] #pylab.plot(t,mean_diff_array, colours['l']) figureno = songcounter+1 print "figure",figureno ax = pylab.subplot(4,4,figureno) pylab.plot(t,mean_diff_array, colours['l']) thistitle=pylab.title("%s"%(df.metadata['artist']), fontsize=10) if pylab.mod(figureno,4)==1: # left-most subfigure pylab.ylabel('Mean difference', fontsize=10) if figureno>12: # bottom-most subfigure pylab.xlabel('Time (s)', fontsize=10) # draw a horizontal line at y=0 pylab.axhline(y=0.0, linestyle='-', color='k') # draw a blue line over sections for which instrumental was more arousing for timesteps in lyrics_lower_during: # timesteps is a list of consecutive timesteps during which lyrics were lower pylab.plot(t[timesteps],mean_diff_array[timesteps], colours['i']) # put big coloured dots on the points for which p < 0.005 for i,pval in enumerate(pval_array): if pval<0.005: if mean_diff_array[i]<0:
def QuiverPlotDict(longitude, colatitude, scalars, vectors, plotOpts1=None, plotOpts2=None, longTicks=None, longLabels=None, colatTicks=None, colatLabels=None, northPOV=True, useMesh=False, plotColorBar=True, plotQuiverKey=True, userAxes=None): """ Wrapper to produce well-labeled polar plot of a vector field overlaid on a color-coded scalar field. Inputs - first is a dictionary holding a 2D meshgrid of longitudes (azimuth) - second is a dictionary holding a 2D meshgrid of colatitudes (radius) - third is dictionary holding a 2D array of a scalar field whose elements are located at coordinates specified in the first and second arguments; as per MIX convention: dim1 = longitudes, dim2=colatitudes - fourth is a 2-tuple of 2D arrays of local {long,colat} direction vector components whose elements are located at coordinates specified in the first and second arguments; dim1 = longitudes, dim2=colatitudes Keywords - plotOpts1 - dictionary holding various optional parameters for tweaking the scalar field appearance 'colormap': string specifying a colormap for surface or contourf plots FIXME: this should be an actual colormap object, NOT just the name of a standard colormap 'min': minimum data value mapped to colormap 'max': maximum data value mapped to colormap 'format_str': format string for min/max labels 'numContours': number of contours between min and max 'numTicks': number of ticks in colorbar - plotOpts2 - dictionary holding various optional parameters for tweaking the vector field appearance 'scale': floating point number specifying how many data unit vector arrows will fit across the width of the plot; default is for max. vector amplitude to be 1/10th plot width 'width': floating point number specifying the width of an arrow shaft as a fraction of plot width 'pivot': should be one of: 'tail' - pivot about tail (default) 'middle' - pivot about middle 'tip' - pivot about tip 'color': color of arrow - longTicks - where to place 'longitude' ticks in radians - longLabels - labels to place at longTicks - colatTicks - where to place 'colatiude' ticks in 'colatitude' units - colatLabels- labels to place at colatTicks - northPOV - if True, assume a POV above north pole, otherwise assume POV below south pole (this does NOT transform data, but only corrects the plot axes to match the POV; it is up to the user to ensure proper inputs) - useMesh - if True, plot scalar field as surface plot, not filled contours (should be quicker in theory, but seems to be much slower) - plotColorBar- if True, plot a colorbar - plotQuiverKey- if True, plot and label a scaled arrow outside the plot - userAxes - FIXME: it currently does nothing, although if None (default), this function creates a new figure...this is almost contrary to normal Matplotlib behavior. Outputs Reference to a matplotlib.axes.PolarAxesSubplot object """ # if user supplies axes use them other wise create our own polar axes if userAxes == None: ax = p.axes(polar=True) else: ax = userAxes # use longitude for azimuthal dimension # NOTE: polar plots have methods to set the 0 direction, BUT they do not # handle vector fields properly (or rather, the vector field plot # routines are not written correctly for polar projections)...we # simply add pi/2, and make all the proper transformations below theta = longitude['data'].copy() + p.pi / 2 # use colatitude for radial dimension r = colatitude['data'].copy() # adjust r so colatitudes increase from 0->pi/2, then decrease from pi/2->pi; # a corresponding adjustment is made to the vrs vector field below gt90 = r > p.pi / 2 r[gt90] = p.pi - r[gt90] # Draw Polar grids with 0 longitude pointing up, correcting for POV if longTicks == None: longTicks = [elem * p.pi / 180 for elem in [0, 90, 180, 270]] # if longTicks was not passed, quietly ignore any longLabels passed longLabels = [ r'0' + '\xb0', r'90' + '\xb0', r'180' + '\xb0', r'270' + '\xb0' ] else: longTicks = [elem for elem in longTicks] if northPOV: longTicks = [elem + p.pi / 2 for elem in longTicks] else: longTicks = [ p.mod(p.arctan2(p.sin(elem), -p.cos(elem)) - p.pi / 2, 2 * p.pi) for elem in longTicks ] if longLabels == None: thetaLines, thetaLabels = p.thetagrids( [elem * 180 / p.pi for elem in longTicks]) else: thetaLines, thetaLabels = p.thetagrids( [elem * 180 / p.pi for elem in longTicks], longLabels) p.setp(thetaLabels, fontsize=10, color='0.4') if colatTicks == None: # let Matplotlib determine colatTicks # if longTicks was not passed, quietly ignore any longLabels passed colatLabels = None if colatLabels == None: rhoLines, rhoLabels = p.rgrids() else: rhoLines, rhoLabels = p.rgrids(colatTicks, colatLabels) p.setp(rhoLabels, fontsize=10, color='gray') p.axis([0, 2.0 * n.pi, 0, r.max()], 'tight') # if scalars is False (or None, or empty, etc.), skip and proceed to quiver plot if scalars: # PROCESS PLOT OPTIONS FOR FIRST (SCALAR) INPUT if plotOpts1 == None: plotOpts1 = {} # if colormap is supplied use it if 'colormap' in plotOpts1: cmap1 = eval('p.cm.' + plotOpts1['colormap']) else: cmap1 = None # default is used # if limits are given use them, if not use the variables min/max values if 'min' in plotOpts1: lower1 = plotOpts1['min'] else: lower1 = scalars['data'].min() if 'max' in plotOpts1: upper1 = plotOpts1['max'] else: upper1 = scalars['data'].max() # if format string for max/min is given use otherwise do default if 'format_str' in plotOpts1: format_str1 = plotOpts1['format_str'] else: format_str1 = '%.2f' # if number of contours is given use it otherwise do 51 if 'numContours' in plotOpts1: ncontours1 = plotOpts1['numContours'] else: ncontours1 = 51 # if number of ticks is given use it otherwise do 51 if 'numTicks' in plotOpts1: nticks1 = plotOpts1['numTicks'] else: nticks1 = 11 contours1 = n.linspace(lower1, upper1, ncontours1) ticks1 = n.linspace(lower1, upper1, nticks1) var1 = scalars['data'] if (useMesh): p.pcolor(theta, r, var1, cmap=cmap1, vmin=lower1, vmax=upper1) else: p.contourf(theta, r, var1, contours1, extend='both', cmap=cmap1) if (plotColorBar): cb1 = p.colorbar(pad=0.075, ticks=ticks1) cb1.set_label(scalars['name'] + ' [' + scalars['units'] + ']') cb1.solids.set_rasterized(True) p.annotate(('min: ' + format_str1 + '\nmax: ' + format_str1) % (var1.min(), var1.max()), (0.65, -.05), textcoords='axes fraction', annotation_clip=False) # if vectors is False (or None, or empty, etc.), skip quiver plot if vectors: # copy 'longitudinal' component of directional vector to polar theta component vts = vectors[0]['data'].copy() # copy 'colatitudinal' component of directional vector to polar r component vrs = vectors[1]['data'].copy() # adjust vrs to accomodate vectors positioned at r > pi/2 vrs[gt90] = -vrs[gt90] # PROCESS PLOT OPTIONS FOR SECOND (VECTOR) INPUT if plotOpts2 == None: plotOpts2 = {} # use scale if given, otherwise max. magnitude generates arrow 1/10 plot-width if 'scale' in plotOpts2: scale = plotOpts2['scale'] else: scale = p.sqrt(vrs**2 + vts**2).max() / 0.1 # use width if given, otherwise default is .0025 plot-width if 'width' in plotOpts2: width = plotOpts2['width'] else: width = .0025 # use pivot if given, otherwise default is 'tail' if 'pivot' in plotOpts2: pivot = plotOpts2['pivot'] else: pivot = 'tail' # use color if given, otherwise default is black if 'color' in plotOpts2: color2 = plotOpts2['color'] else: color2 = 'k' # consider adding options to control spacing of vector field arrows # interpolate to a polar grid that alleviates some of the so-called # "pole problem" described by Randall (2011 Online notes) -EJR 12/2013 for j in range(r[0, :].size): if r[0, j] == 0: # if radius==0, there should be only one unique vector, so just # use the first element r_tmp = 0 theta_tmp = theta[0, j] vr_tmp = vrs[0, j] vt_tmp = vts[0, j] else: # OK, it took the better part of a day to determine that a "bug" # was nothing more than me neglecting to ensure that the known x's # were monotonically increasing in calls to p.interp()...ARGH!!! # # Now, this whole business of allowing colatitudes that are greater # than pi/2 needs to be re-visited, since it is likely to lead to # even bigger problems if/when someone attempts to pass colatitudes # from both hemispheres simultaneously..then again, I would like to # eventually supercede this function with one based on the BASEMAP # extension to Matplotlib, so maybe this is a moot point. -EJR 2/2014 theta_tmp = p.linspace(theta[:, 0].min(), theta[:, 0].max(), 3 * j + 1) r_tmp = theta_tmp * 0 + r[0, j] # all r's are the same for each j # currently only 1D interpolation along columns of constant theta; # 2D interpolation could be use to achieve more uniform distribution # of quiver positions, however this is already easily obtained if # the BASEMAP extenstion to Matplotlib is used, so leave as-is. -EJR 2/2014 minc = theta[:, j].argsort() vr_tmp = p.interp(theta_tmp, theta[minc, j], vrs[minc, j]) vt_tmp = p.interp(theta_tmp, theta[minc, j], vts[minc, j]) # call pylab's quiver, correcting for local polar coordinates # NOTE: if pylab/matplotlib ever fixes quiver to properly handle polar # plots (or projections in general), the rotation below will need # to be removed -EJR 11/2013 ...once again, this is probably a # moot point if/when BASEMAP is incoporated into our plot functions. units = 'width' # use plot width as basic unit for all quiver attributes qh = p.quiver( theta_tmp, r_tmp, vr_tmp * p.cos(theta_tmp) - vt_tmp * p.sin(theta_tmp), vr_tmp * p.sin(theta_tmp) + vt_tmp * p.cos(theta_tmp), units=units, scale=scale, width=width, pivot=pivot, color=color2) ## uncomment for debugging #print 'Number of longitude gridpoints: ',vr_tmp.size - 1 #blah = raw_input('Hit key for next plot:') if plotQuiverKey: # Since we forced units to be 'width', a scale keyword equal to 1 implies # that an arrow whose length is the full width of the plot will be equal # to 1 data unit, a scale keyword of 2 implies that an arrow whose length # is the full width of the plot will be equal to two data units, etc. # Here we draw a "Quiver Key" that is 1/10th the width of the plot, and # properly scale its value...much pained thought went into convincing my- # self that this is correct, but feel free to verify -EJR 12/2013 p.quiverkey(qh, .3, 0, .1 * scale, ('%3.1e ' + '%s') % (.1 * scale, vectors[0]['units']), coordinates='axes', labelpos='S') return p.gca()
dV = ((I_in - gCa * m_inf * (V - E_Ca) - gK * n * (V - E_K) - gL * (V - E_L)) / Cm + 50. * noise2 * (2. * (rand(n_i, 1) - 0.5)).ravel()) #---slow variable exogenous dz = r * (s * (x1 + mean(x2) - x0) - mean(z)) #update variables x1 = x1 + dx1 * dt x2 = (V + dV * dt) / 20. y1 = y1 + dy1 * dt n = n + dn * dt z = z + dz * dt uE = uE + duE * dt uI = uI + duI * dt #store if (pb.mod(t_step, 1) == 0): x_1s[:, int(t_step)] = x1.ravel() x_2s[:, int(t_step)] = x2.ravel() z_s[:, int(t_step)] = z.ravel() y_1s[:, int(t_step)] = y1.ravel() n_s[:, int(t_step)] = n.ravel() print(t_step) t_plot = pb.arange(0, t_stop) t_plot_dt = pb.arange(0, t_stop, dt) #save data radical = "_%i_HMR_%i_ML_CpES1_%i_CpES2_%i_x0_%i_noise1_%i_noise2_%i_noise3_%i_gx1x2_%i_gx2x1_%i_gx1x1_%i_gx2x2_%i_r%i_%is" % ( nbn1, nbn2, int(CpES1 * 100), int(CpES2 * 100), int(-x0 * 10), int(noise1 * 10), int(noise2 * 100), int(noise3 * 100), int( g_x1x2 * 100), int(g_x2x1 * 100), int(g_x1x1 * 100), int(
def trial(path, dir, CJ, npeak=1, bamp=0., opp=None, output=0): # Initialization rng = np.random.RandomState(seedrun) target = np.zeros(2) visI = np.zeros((2, n)) wmS = np.zeros(2) wmI = np.zeros(2) wmIno = np.zeros(2) wm = np.zeros(2) tgS = np.zeros((2, n)) tgI = np.zeros((2, n)) tgIno = np.zeros((2, n)) tg = np.zeros((2, n)) ctS = np.zeros(n) ctI = np.zeros(n) ctIno = np.zeros(n) ct = np.zeros(n) sigma_n_tg = sigma_n + std_sig * rng.randn(2, n) tgIno0 = ctIno0 + std_I * rng.randn(2, n) # Files for writing ft1 = open( path + '/lpfc_t1_net_' + str(seednet) + '_run_' + str(seedrun) + '_CJ_' + str(CJ) + '_d_' + str(dir) + '_.txt', 'w') ft2 = open( path + '/lpfc_t2_net_' + str(seednet) + '_run_' + str(seedrun) + '_CJ_' + str(CJ) + '_d_' + str(dir) + '_.txt', 'w') fct = open( path + '/lpfc_ct_net_' + str(seednet) + '_run_' + str(seedrun) + '_CJ_' + str(CJ) + '_d_' + str(dir) + '_.txt', 'w') # Target direction target[0] = dir if opp == None: target[1] = pylab.mod(target[0] + 180, 360) else: target[1] = opp # Visual neurons activated by target onset vgauss = visgauss(target[0], target[1], sigma_s, npeak, n, bamp) # Simulation for j in range(int(dur / ts)): # Chosen juice neurons at OFC if j > int(preoffer / ts) and j < int((preoffer + offeron) / ts): if CJ == 0: Ijw = jI elif CJ == 1: Ijw = np.array([jI[1], jI[0]]) else: Ijw = np.zeros(2) # Define input current wmI[0] = Ijw[0] + g_ww * wmS[0] + g_wwi * wmS[1] + wmIno[0] wmI[1] = Ijw[1] + g_ww * wmS[1] + g_wwi * wmS[0] + wmIno[1] tgI = tgIno + g_wt * np.dot( wmS[np.newaxis, :].T, np.ones(n)[np.newaxis, :]) + g_st * visI + np.array( [JM1.dot(tgS[0, :]) / n, JM2.dot(tgS[1, :]) / n]) tgI += np.array([JMx1.dot(tgS[1, :]) / n, JMx2.dot(tgS[0, :]) / n]) ctI = ctIno + JMct.dot(ctS) / n + g_tc * (tgS[0, :] + tgS[1, :]) # Visual neurons activated by target onset if cue_on == 1: if j >= (preoffer + offeron + offeroff) / ts: visI = vgauss + std_vis * rng.randn(2, n) else: visI = np.zeros(n) else: if j >= (preoffer + offeron + offeroff) / ts and j < ( preoffer + offeron + offeroff + targeton) / ts: visI = vgauss + std_vis * rng.randn(2, n) else: visI = np.zeros(n) # Firing rate wm = f(wmI) tg = f(tgI) ct = f(ctI) # Print files if np.mod(j, int(tp / ts)) == 0 and j >= tgt_start / ts: for k in range(n): ft1.write(str(tg[0, k]) + '\t') ft2.write(str(tg[1, k]) + '\t') fct.write(str(ct[k]) + '\t') ft1.write('\n') ft2.write('\n') fct.write('\n') # Modified Euler rn = rng.randn(2) stemp = wmS + ts * (-wmS / tau_s + gamma * (1 - wmS) * wm) inotemp = wmIno - ( wmIno - wmIno0) * ts / tau_n + sigma_n * rn * np.sqrt(ts / tau_n) Itemp = inotemp + Ijw + g_ww * wmS Itemp[0] += g_wwi * wmS[1] Itemp[1] += g_wwi * wmS[0] wmS = wmS + ts / 2. * (-wmS / tau_s + gamma * (1 - wmS) * wm - stemp / tau_s + gamma * (1 - stemp) * f(Itemp)) wmIno = wmIno + ts / 2. * ( -(wmIno - wmIno0) / tau_n - (inotemp - wmIno0) / tau_n) + sigma_n * rn * np.sqrt(ts / tau_n) rn = rng.randn(2, n) stemp = tgS + ts * (-tgS / tau_s + gamma * (1 - tgS) * tg) inotemp = tgIno - (tgIno - tgIno0) * ts / tau_n + sigma_n_tg * rn * np.sqrt( ts / tau_n) Itemp = inotemp + np.array([ JM1.dot(tgS[0, :]) / n, JM2.dot(tgS[1, :]) / n ]) + g_wt * np.dot(wmS[np.newaxis, :].T, np.ones(n)[np.newaxis, :]) + g_st * visI Itemp += np.array([JMx1.dot(tgS[1, :]) / n, JMx2.dot(tgS[0, :]) / n]) tgS = tgS + ts / 2. * (-tgS / tau_s + gamma * (1 - tgS) * tg - stemp / tau_s + gamma * (1 - stemp) * f(Itemp)) tgIno = tgIno + ts / 2. * ( -(tgIno - tgIno0) / tau_n - (inotemp - tgIno0) / tau_n) + sigma_n_tg * rn * np.sqrt(ts / tau_n) rn = rng.randn(n) stemp = ctS + ts * (-ctS / tau_s + gamma * (1 - ctS) * ct) inotemp = ctIno - (ctIno - ctIno0) * ts / tau_n + sigma_n_ring * rn * np.sqrt( ts / tau_n) Itemp = inotemp + JMct.dot(ctS) / n + g_tc * (tgS[0, :] + tgS[1, :]) ctS = ctS + ts / 2. * (-ctS / tau_s + gamma * (1 - ctS) * ct - stemp / tau_s + gamma * (1 - stemp) * f(Itemp)) ctIno = ctIno + ts / 2. * (-(ctIno - ctIno0) / tau_n - (inotemp - ctIno0) / tau_n ) + sigma_n_ring * rn * np.sqrt(ts / tau_n) temp, decodedCT = resultant(ct, div=n) print 'CT = ' + str(target[CJ]) + '; Decoded CT = ' + str(decodedCT) if anglediff(target[CJ], decodedCT) > 22.5: print 'Please check the result!' ft1.close() ft2.close() fct.close() if output == 1: return np.min([ np.abs(target[CJ] - decodedCT), 360 - np.abs(target[CJ] - decodedCT) ])
def stereoplot(strike, dip, filename): # Here is the stereonet plotting section bigr = 1.2 phid = pylab.arange(2, 90, 2) # Angular range for phir = phid * pylab.pi / 180 omegad = 90 - phid omegar = pylab.pi / 2 - phir # Set up for plotting great circles with centers along # positive x-axis x1 = bigr * pylab.tan(phir) y1 = pylab.zeros(pylab.size(x1)) r1 = bigr / pylab.cos(phir) theta1ad = (180 - 80) * pylab.ones(pylab.size(x1)) theta1ar = theta1ad * pylab.pi / 180 theta1bd = (180 + 80) * pylab.ones(pylab.size(x1)) theta1br = theta1bd * pylab.pi / 180 # Set up for plotting great circles # with centers along the negative x-axis x2 = -1 * x1 y2 = y1 r2 = r1 theta2ad = -80 * pylab.ones(pylab.size(x2)) theta2ar = theta2ad * pylab.pi / 180 theta2bd = 80 * pylab.ones(pylab.size(x2)) theta2br = theta2bd * pylab.pi / 180 # Set up for plotting small circles # with centers along the positive y-axis y3 = bigr / pylab.sin(omegar) x3 = pylab.zeros(pylab.size(y3)) r3 = bigr / pylab.tan(omegar) theta3ad = 3 * 90 - omegad theta3ar = 3 * pylab.pi / 2 - omegar theta3bd = 3 * 90 + omegad theta3br = 3 * pylab.pi / 2 + omegar # Set up for plotting small circles # with centers along the negative y-axis y4 = -1 * y3 x4 = x3 r4 = r3 theta4ad = 90 - omegad theta4ar = pylab.pi / 2 - omegar theta4bd = 90 + omegad theta4br = pylab.pi / 2 + omegar # Group all x, y, r, and theta information for great cricles phi = pylab.append(phid, phid, 0) x = pylab.append(x1, x2, 0) y = pylab.append(y1, y2, 0) r = pylab.append(r1, r2) thetaad = pylab.append(theta1ad, theta2ad, 0) thetaar = pylab.append(theta1ar, theta2ar, 0) thetabd = pylab.append(theta1bd, theta2bd, 0) thetabr = pylab.append(theta1br, theta2br, 0) # Plot portions of all great circles that lie inside the # primitive circle, with thick lines (1 pt.) at 10 degree increments for i in range(0, len(x)): thd = pylab.arange(thetaad[i], thetabd[i] + 1, 1) thr = pylab.arange(thetaar[i], thetabr[i] + pylab.pi / 180, pylab.pi / 180) xunit = x[i] + r[i] * pylab.cos(pylab.radians(thd)) yunit = y[i] + r[i] * pylab.sin(pylab.radians(thd)) # p = pylab.plot(xunit,yunit,'b',lw=.5) #commented out to remove small verticle lines pylab.hold(True) # Now "blank out" the portions of the great circle cyclographic traces # within 10 degrees of the poles of the primitive circle. rr = bigr / pylab.tan(80 * pylab.pi / 180) ang1 = pylab.arange(0, pylab.pi + pylab.pi / 180, pylab.pi / 180) xx = pylab.zeros(pylab.size(ang1)) + rr * pylab.cos(ang1) yy = bigr / pylab.cos(10 * pylab.pi / 180) * pylab.ones(pylab.size(ang1)) - rr * pylab.sin(ang1) p = pylab.fill(xx, yy, 'w') yy = -bigr / pylab.cos(10 * pylab.pi / 180) * pylab.ones(pylab.size(ang1)) + rr * pylab.sin(ang1) p = pylab.fill(xx, yy, 'w') for i in range(1, len(x)): thd = pylab.arange(thetaad[i], thetabd[i] + 1, 1) thr = pylab.arange(thetaar[i], thetabr[i] + pylab.pi / 180, pylab.pi / 180) xunit = x[i] + r[i] * pylab.cos(pylab.radians(thd)) yunit = y[i] + r[i] * pylab.sin(pylab.radians(thd)) if pylab.mod(phi[i], 10) == 0: p = pylab.plot(xunit, yunit, 'b', lw=1) angg = thetaad[i] pylab.hold(True) # Now "blank out" the portions of the great circle cyclographic traces # within 2 degrees of the poles of the primitive circle. rr = bigr / pylab.tan(88 * pylab.pi / 180) ang1 = pylab.arange(0, pylab.pi + pylab.pi / 180, pylab.pi / 180) xx = pylab.zeros(pylab.size(ang1)) + rr * pylab.cos(ang1) yy = bigr / pylab.cos(2 * pylab.pi / 180) * pylab.ones(pylab.size(ang1)) - rr * pylab.sin(ang1) p = pylab.fill(xx, yy, 'w') yy = -bigr / pylab.cos(2 * pylab.pi / 180) * pylab.ones(pylab.size(ang1)) + rr * pylab.sin(ang1) p = pylab.fill(xx, yy, 'w') # Group all x, y, r, and theta information for small circles phi = pylab.append(phid, phid, 0) x = pylab.append(x3, x4, 0) y = pylab.append(y3, y4, 0) r = pylab.append(r3, r4) thetaad = pylab.append(theta3ad, theta4ad, 0) thetaar = pylab.append(theta3ar, theta4ar, 0) thetabd = pylab.append(theta3bd, theta4bd, 0) thetabr = pylab.append(theta3br, theta4br, 0) # Plot primitive circle thd = pylab.arange(0, 360 + 1, 1) thr = pylab.arange(0, 2 * pylab.pi + pylab.pi / 180, pylab.pi / 180) xunit = bigr * pylab.cos(pylab.radians(thd)) yunit = bigr * pylab.sin(pylab.radians(thd)) p = pylab.plot(xunit, yunit) pylab.hold(True) # Plot portions of all small circles that lie inside the # primitive circle, with thick lines (1 pt.) at 10 degree increments for i in range(0, len(x)): thd = pylab.arange(thetaad[i], thetabd[i] + 1, 1) thr = pylab.arange(thetaar[i], thetabr[i] + pylab.pi / 180, pylab.pi / 180) xunit = x[i] + r[i] * pylab.cos(pylab.radians(thd)) yunit = y[i] + r[i] * pylab.sin(pylab.radians(thd)) blug = pylab.mod(thetaad[i], 10) if pylab.mod(phi[i], 10) == 0: p = pylab.plot(xunit, yunit, 'b', lw=1) angg = thetaad[i] # else: #Commented out to remove the small horizontal lines # p = pylab.plot(xunit,yunit,'b',lw=0.5) pylab.hold(True) # Draw thick north-south and east-west diameters xunit = [-bigr, bigr] yunit = [0, 0] p = pylab.plot(xunit, yunit, 'b', lw=1) pylab.hold(True) xunit = [0, 0] yunit = [-bigr, bigr] p = pylab.plot(xunit, yunit, 'b', lw=1) pylab.hold(True) ''' This is the plotting part''' trend1 = strike plunge1 = pylab.absolute(dip) # num = leng(lines1(:,1)); trendr1 = [foo * pylab.pi / 180 for foo in trend1] plunger1 = [foo * pylab.pi / 180 for foo in plunge1] rho1 = [bigr * pylab.tan(pylab.pi / 4 - ((foo) / 2)) for foo in plunger1] # polarb plots ccl from 3:00, so convert to cl from 12:00 # pylab.polar(pylab.pi/2-trendr1,rho1,'o') pylab.plot(9000, 90000, 'o', markerfacecolor="b", label='Positive Dip') pylab.plot(9000, 90000, 'o', markerfacecolor="w", label='Negative Dip') pylab.legend(loc=1) for n in range(0, len(strike)): if dip[n] > 0: pylab.plot(rho1[n] * pylab.cos(pylab.pi / 2 - trendr1[n]), rho1[n] * pylab.sin(pylab.pi / 2 - trendr1[n]), 'o', markerfacecolor="b", label='Positive Dip') else: pylab.plot(rho1[n] * pylab.cos(pylab.pi / 2 - trendr1[n]), rho1[n] * pylab.sin(pylab.pi / 2 - trendr1[n]), 'o', markerfacecolor="w", label='Negative Dip') '''above is self''' pylab.axis([-bigr, bigr, -bigr, bigr])
def get_data(sid, ttype, datdir = './SLIP_params', file_name_0 = 'params3D_', detrend_hwlen = 15, detrend = True, normalize = False, exclude_ws = ['params3D_s8t1r2.dict',]): """ returns a tuple (stateL, stateR, paramsL, paramsR, addInfo), such that the SLIP model that would start at stateL[0] with parameters paramsL[0] would result at stateR[0], and coninuing this would result in the states stateL[1], stateR[1], stateL[2], stateL[3], ... A break might occur at these steps where different trials are concatenated. addInfo is a dict containing additional information such as the mass, minimal vertical excursion, step duration (required for SLIP parameter calculation). state is [k, alpha, L0, beta, dE] input: sid: subject-id [currently: 1,2,3,4,6(?),7,8] ttype: trial-type [currently: 1-free running, 2-metronome running] datdir: directory where to look for stored data files fileName0: common beginning of filenames detrend_hwlen: (half) window length of centered moving average detrending detrend: whether or not to detrend normalize: whether or not to normalize parameters exclude_ws: list of filenames that must not be loaded """ param_type = 'ESLIP_params' # alternatively: 'SLIP_params' # import other, locally defined library (FDatAn -> misc) #import misc as fda pattern = file_name_0 + ('s%it%ir' % (sid, ttype)) files1 = [x for x in os.listdir(datdir) if x[:len(pattern)] == pattern and x not in exclude_ws] files1.sort() reps = [x[-6] for x in files1] states_r = [] states_l = [] params_r = [] params_l = [] masses1 = [] phases1 = [] phases_r = [] phases_l = [] delta_e = [] time_1 = [] ymin = [] ymin_r = [] ymin_l = [] delta_er = [] delta_el = [] time_r1 = [] time_l1 = [] n_in_ws = [] #allStates = [] avg_params_l = [] avg_params_r = [] for fname in files1: slip_params = mload(datdir + os.sep + fname) # normalization: k' = k*l0/(m*g) # process workspaces: # - make non-dimensional (following Blickhan+Full 1993): # k' = k*l0/(m*g) # - detrend [::2,:] !! detrend left and right steps separately, # to account for gait asymmetry # - sort left / right: 0 < phi < pi: subsequent touchdown is left, # pi < phi < 2pi: subsequent touchdown is right. phases1.append(slip_params['phases']) all_params = slip_params[param_type] masses1.append(slip_params['mass']) phases1.append(slip_params['phases']) all_states = vstack( [slip_params['y0'], slip_params['vx'], slip_params['vz'], ] ).T[:all_params.shape[0]] delta_e.append(slip_params['dE']) time_1.append(slip_params['T_exp']) ymin.append(slip_params['ymin']) offset_r = 0 offset_l = 0 # enforce that every dataset starts with a left step # -> important for regression L -> R, R -> L, because only then it is # guaranteed that stateR[i] follows stateL[i], and stateL[i+1] follows # stateR[i] if mean(mod(phases1[-1][::2], 2.*pi)) < pi: # starts with left step offset_r = 1 else: # starts with right step offset_l = 1 offset_r = 2 nStrides1 = all_params[offset_r::2, :].shape[0] states_r.append(all_states[offset_r::2, :]) states_l.append(all_states[offset_l::2, :][:nStrides1, :]) params_r.append(all_params[offset_r::2, :]) params_l.append(all_params[offset_l::2, :][:nStrides1, :]) delta_er.append(slip_params['dE'][offset_r::2]) delta_el.append(slip_params['dE'][offset_l::2][:nStrides1]) time_r1.append(slip_params['T_exp'][offset_r::2]) time_l1.append(slip_params['T_exp'][offset_l::2][:nStrides1]) ymin_r.append(slip_params['ymin'][offset_r::2][:nStrides1]) ymin_l.append(slip_params['ymin'][offset_l::2][:nStrides1]) phases_r.append(phases1[-1][offset_r::2][:nStrides1]) phases_l.append(phases1[-1][offset_l::2][:nStrides1]) # normalize parameters l0r = mean(params_r[-1][:, 2]) l0l = mean(params_l[-1][:, 2]) if normalize: params_r[-1][:, 0] = params_r[-1][:, 0] * l0r / (masses1[-1] * 9.81) params_l[-1][:, 0] = params_l[-1][:, 0] * l0l / (masses1[-1] * 9.81) params_r[-1][:, 4] = params_r[-1][:, 4] * l0r / (masses1[-1] * 9.81) params_l[-1][:, 4] = params_l[-1][:, 4] * l0l / (masses1[-1] * 9.81) params_r[-1][:, 2] = params_r[-1][:, 2] / l0r params_l[-1][:, 2] = params_l[-1][:, 2] / l0l params_r[-1][:, 5] = params_r[-1][:, 5] / l0r params_l[-1][:, 5] = params_l[-1][:, 5] / l0l delta_e[-1] = delta_e[-1]/( masses1[-1] * 9.81 * ( l0r + l0l) / 2.) delta_er[-1] = ( delta_er[-1]/( masses1[-1] * 9.81 * ( l0r + l0l) / 2.)) delta_el[-1] = ( delta_el[-1]/( masses1[-1] * 9.81 * ( l0r + l0l) / 2.)) params_r[-1][:, 4] = delta_er[-1] params_l[-1][:, 4] = delta_el[-1] avg_params_l.append( mean( params_r[-1], axis=0)) avg_params_l.append( mean( params_l[-1], axis=0)) if detrend: params_r[-1] = mi.dt_movingavg( params_r[-1], detrend_hwlen) params_l[-1] = mi.dt_movingavg( params_l[-1], detrend_hwlen) n_in_ws = [len(sl) for sl in states_l] state_r = vstack(states_r) params_r = vstack(params_r)[:, :5] state_l = vstack(states_l) params_l = vstack(params_l)[:, :5] add_info = {'time_left' : hstack(time_l1), 'time_right' : hstack(time_r1), 'ymin_left' : hstack(ymin_l), 'ymin_right' : hstack(ymin_r), 'all_masses' : masses1, 'mass' : mean(masses1), 'avg_params_l' : avg_params_l, 'avg_params_r' : avg_params_r, 'n_in_ws' : n_in_ws, 'phases_r' : hstack(phases_r), 'phases_l' : hstack(phases_l), 'reps': reps, } return state_l, state_r, params_l, params_r, add_info
def __PruneFileSciPy__(filename, MaxOverlap=0.15, **kwargs): '''Returns a prune score for a single file Args: MaxOverlap = 0 to 1''' # logger = logging.getLogger('irtools.prune') #logger = multiprocessing.log_to_stderr() if MaxOverlap > 0.5: MaxOverlap = 0.5 if not os.path.exists(filename): #logger.error(filename + ' not found when attempting prune') #PrettyOutput.LogErr(filename + ' not found when attempting prune') return None Im = core.LoadImage(filename) (Height, Width) = Im.shape StdDevList = [] MeanList = [] MaxDim = Height if Width > Height: MaxDim = Width SampleSize = int(ceil(MaxDim / 32)) VertOverlapPixelRange = int(MaxOverlap * float(Height)) HorzOverlapPixelRange = int(MaxOverlap * float(Width)) MaskTopBorder = VertOverlapPixelRange + (SampleSize - (mod(VertOverlapPixelRange, 32))) MaskBottomBorder = Height - VertOverlapPixelRange - (SampleSize - (mod(VertOverlapPixelRange, 32))) MaskLeftBorder = HorzOverlapPixelRange + (SampleSize - (mod(HorzOverlapPixelRange, 32))) MaskRightBorder = Width - HorzOverlapPixelRange - (SampleSize - (mod(HorzOverlapPixelRange, 32))) # Calculate the top for iHeight in range(0, MaskTopBorder - (SampleSize - 1), SampleSize): for iWidth in range(0, Width - 1, SampleSize): StdDev = std(Im[iHeight:iHeight + SampleSize, iWidth:iWidth + SampleSize]) StdDevList.append(StdDev) # Im[iHeight:iHeight+SampleSize,iWidth:iWidth+SampleSize] = 0 # Calculate the sides for iHeight in range(MaskTopBorder, MaskBottomBorder, SampleSize): for iWidth in range(0, MaskLeftBorder - (SampleSize - 1), SampleSize): StdDev = std(Im[iHeight:iHeight + SampleSize, iWidth:iWidth + SampleSize]) StdDevList.append(StdDev) # Im[iHeight:iHeight+SampleSize,iWidth:iWidth+SampleSize] = 0.25 for iWidth in range(MaskRightBorder, Width - SampleSize, SampleSize): StdDev = std(Im[iHeight:iHeight + SampleSize, iWidth:iWidth + SampleSize]) StdDevList.append(StdDev) # Im[iHeight:iHeight+SampleSize,iWidth:iWidth+SampleSize] = 0.5 # Calculate the bottom for iHeight in range(MaskBottomBorder, Height - SampleSize, SampleSize): for iWidth in range(0, Width - 1, SampleSize): StdDev = std(Im[iHeight:iHeight + SampleSize, iWidth:iWidth + SampleSize]) StdDevList.append(StdDev) # Im[iHeight:iHeight+SampleSize,iWidth:iWidth+SampleSize] = 0.75 del Im # core.ShowGrayscale(Im) return (filename, sum(StdDevList))
def add_to_legend(self, linefmt, textstr): """ adds an item to the legend and draws the legend note: the legend itself is stored in <object>.legend_entries Parameters: ----------- linefmt : *dict* properties of the line to draw textstr : *str* text of the legend entry Returns: -------- (None) """ # compute position for legend_entry: le_row = mod(len(self.legend_entries), self.layout['legend_rows']) le_col = len(self.legend_entries) // self.layout['legend_rows'] # print 'row / col: ', le_row, le_col # legend margins lm = self.layout.get('legend_margins', (2, 2, 10, 10)) inner_width = (float(self.haxes * self.width - lm[2] - lm[3]) / (self.haxes * self.width)) #print 'inner width:', inner_width inner_height = float(self.legendheight * self.height - lm[0] - lm[1]) / (self.legendheight * self.height) btmline = float(lm[0]) / (self.legendheight * self.height) lmargin = float(lm[2]) / (self.haxes * self.width) #lm #print 'btmline: ', btmline #print 'lmargin: ', lmargin fontheight = (float(self.layout.get('legend_fontsize', 10.)) * 25.4 / 72. / (self.legendheight * self.height)) # abs. #print 'fontheight:', fontheight line_x = (lmargin + (float(le_col) / float(self.layout['legend_cols'] + 1.)) / inner_width) lsp = self.layout.get('legend_textvspace', 1.2) times_fh = lsp * float(self.layout['legend_rows'] - le_row) line_y = btmline + fontheight * times_fh - fontheight / 2. line_length = (float(self.layout.get('legend_linelength', 8.)) / (self.haxes * self.width)) line_text_sep = (float(self.layout.get('legend_line_text_sep', 1.)) / (self.haxes * self.width)) self.legline = [[line_x, line_x + line_length], [line_y, line_y]] self.legendax.plot(*self.legline, **linefmt) self.legend_entries.append( self.legendax.text(line_x + line_length + line_text_sep, line_y - fontheight / 4., textstr, va='baseline', ha='left', fontsize=self.layout.get('legend_fontsize', 10))) self.legendax.set_xlim(0, 1) self.legendax.set_ylim(0, 1) self.legendax.set_xticks([]) self.legendax.set_yticks([])
def make_1D(self, nps, phase='phi2', fps=250, phases_list=None): """ interpolate the data with <nps> frames per stride *Note* The <object>.selection attribute must contain a valid list of selection items. A selection item can either be a single coordinate (e.g. 'com_z', 'r_anl_y') or the difference between two coordinates (e.g. 'l_anl_y - com_y') :args: nps (int): how many frames per stride should be sampled phase (str): 'phi1' or 'phi2' : which phase to use. Note: previous data mostly used 'phi2'. fps (int): how many frames per second do the original data have? This is only required for correct scaling of the velocities. phases_list (list of list of int): If present, use given phases instead of predefined sections. Data will *not* be sampled exactly at the given phases; instead there will be _nps_ sections per stride, and strides start (on average only) at the given phases. """ if len(self.raw_dat) == 0: print "No data loaded." return if len(self.selection) == 0: print "No data selected. Set <object>.selection to something!" # gather phases for each trial: i_phases =[] if not phases_list: # typical call: omit first and last strides; # strides go from phase 0 to phase 2pi (exluding 2pi) for raw in self.raw_dat: phi = raw[phase].squeeze() # cut lower phase and upper phase by ~4pi each first_step = (phi[0] + 6. * pi) // (2. * pi) last_step = (phi[-1] - 4. * pi) // (2. * pi) i_phases.append(linspace(first_step, last_step + 1, (last_step - first_step + 1) * nps, endpoint=False) * 2. *pi) else: # phases are explicitely given avg_phasemod = mean([mean(mod(elem, 2.*pi)) for elem in phases_list]) for elem in phases_list: firstphase = (elem[0] // (2. * pi)) * 2.*pi + avg_phasemod lastphase = (elem[-1] // (2. * pi)) * 2.*pi + avg_phasemod i_phases.append(linspace(firstphase, lastphase + 2*pi, len(elem) * nps, endpoint=False)) self.i_phases = i_phases # walk through each element of "selection" all_pos = [] all_vel = [] for elem in self.selection: items = [x.strip() for x in elem.split('-')] # 1 item if no "-" present dims = [] markers = [] for item in items: if item.endswith('_x'): dims.append(0) elif item.endswith('_y'): dims.append(1) elif item.endswith('_z'): dims.append(2) else: print "invalid marker suffix: ", item continue markers.append(item[:-2]) all_elem_pos = [] all_elem_vel = [] for raw, phi in zip(self.raw_dat, self.i_phases): if len(items) == 1: # only a single marker dat = raw[markers[0]][:, dims[0]] else: # differences between two markers dat = raw[markers[0]][:, dims[0]] - raw[markers[1]][:, dims[1]] all_elem_pos.append(interp(phi, raw[phase].squeeze(), dat)) all_elem_vel.append(interp(phi, raw[phase].squeeze(), gradient(dat) * fps)) all_pos.append(hstack(all_elem_pos)) all_vel.append(hstack(all_elem_vel)) dat_2D = vstack([all_pos, all_vel]) return mi.twoD_oneD(dat_2D, nps)
def __call__( self, mode, solver, x0, lb, ub, init_args={}, solve_args={}, f_args=(), plot=False ): ''' This is where the action starts. Aguments -------- Keyword arguments ----------------- ''' if self.verbose: msg = 'Solving for %s part of signal' % mode print msg # Check if initial guess is provided in one or both of the argument # dictionaries redundant_args = ['A', 'b', 'lb', 'ub', 'x0', 'plot'] for red_arg in redundant_args: if red_arg in init_args.keys(): msg = 'Initial guess *%s* found in *init_args*. I will ' \ 'override this value with the value *%s* passed on as '\ 'positional/keyword argument' % (red_arg, red_arg) if self.verbose: print msg del init_args[red_arg] if red_arg in solve_args.keys(): msg = 'Initial guess *%s* found in *solve_args*. I will ' \ 'override this value with the value *%s* passed on as '\ 'positional/keyword argument' % (red_arg, red_arg) if self.verbose: print msg del solve_args[red_arg] # Set temporary attributes. These are removed in the end attr_list = ['solver', 'x0', 'ub', 'init_args', 'solve_args'] for attr_name in attr_list: try: exec('self.'+attr_name+' = '+attr_name+'.copy()') except AttributeError: exec('self.'+attr_name+' = '+attr_name) if mode.lower()=='mua': # Check for consistent length of x0 M_params = pl.asarray(x0).squeeze() if pl.mod(M_params.shape[0], 3): err_msg = 'Number of elements in x0 must be dividable' \ 'by 3. Current number of elements is %d' % M_params.shape[0] raise Exception, err_msg else: self.npop = M_params.shape[0]/3 # Do some pre-solve operations f_args = self._muaWarmup(*f_args) # create linear constraints A, b = self._muaConstraints() # Set the error function f_fnc = self._muaErr elif mode.lower()=='lfp': # linear constraints f_args = self._lfpWarmup(*f_args) A, b = self._lfpConstraints() # Error function f_fnc = self._lfpErr init_args_internal = { 'A' : A, 'b' : b, 'lb' : lb, 'ub' : self.ub } # Override self.init_args with init_args_internal self.init_args.update(init_args_internal) # Finally, put everything into a dictionary that can be # passed to self._solve() fmin_args = { 'solver' : self.solver, 'f_fnc' : f_fnc, 'f_args' : f_args, 'x0' : self.x0, 'init_args' : self.init_args, 'solve_args' : self.solve_args, 'plot' : plot } r = self._solve(fmin_args) ############################################################ # Post solver processing # Find decompositions and full matrix for best parameters if mode.lower()=='mua': Smat, Tmat_tmp = self.muaDecomp( r.xf, *f_args ) elif mode.lower()=='lfp': Smat, Tmat_tmp = self.lfpDecomp( r.xf, *f_args ) Phimat_tmp = pl.dot(Smat, Tmat_tmp) # Reshape to 3d Tmat = self._reshapeMat( Tmat_tmp ) Phimat = self._reshapeMat( Phimat_tmp ) # deleting temporary attributes for attr_name in attr_list: exec('del self.'+attr_name) return r, Smat, Tmat, Phimat
def __PruneFileSciPy__(filename, MaxOverlap=0.15, **kwargs): '''Returns a prune score for a single file Args: MaxOverlap = 0 to 1''' # TODO: This function should be updated to use the grid_subdivision module to create cells. It should be used in the mosaic tile translation code to eliminate featureless # overlap regions of adjacent tiles # logger = logging.getLogger('irtools.prune') # logger = multiprocessing.log_to_stderr() if MaxOverlap > 0.5: MaxOverlap = 0.5 # # if not os.path.exists(filename): # # logger.error(filename + ' not found when attempting prune') # # PrettyOutput.LogErr(filename + ' not found when attempting prune') # return None Im = nornir_imageregistration.ImageParamToImageArray(filename) # Imb = nornir_imageregistration.LoadImage(filename) (Height, Width) = Im.shape StdDevList = [] # MeanList = [] MaxDim = Height if Width > Height: MaxDim = Width SampleSize = int(ceil(MaxDim / 32)) VertOverlapPixelRange = int(MaxOverlap * float(Height)) HorzOverlapPixelRange = int(MaxOverlap * float(Width)) MaskTopBorder = VertOverlapPixelRange + (SampleSize - (mod(VertOverlapPixelRange, 32))) MaskBottomBorder = Height - VertOverlapPixelRange - (SampleSize - (mod(VertOverlapPixelRange, 32))) MaskLeftBorder = HorzOverlapPixelRange + (SampleSize - (mod(HorzOverlapPixelRange, 32))) MaskRightBorder = Width - HorzOverlapPixelRange - (SampleSize - (mod(HorzOverlapPixelRange, 32))) # Calculate the top for iHeight in range(0, MaskTopBorder - (SampleSize - 1), SampleSize): for iWidth in range(0, Width - 1, SampleSize): StdDev = numpy.std(Im[iHeight:iHeight + SampleSize, iWidth:iWidth + SampleSize]) StdDevList.append(StdDev) # Im[iHeight:iHeight+SampleSize,iWidth:iWidth+SampleSize] = 0 # Calculate the sides for iHeight in range(MaskTopBorder, MaskBottomBorder, SampleSize): for iWidth in range(0, MaskLeftBorder - (SampleSize - 1), SampleSize): StdDev = numpy.std(Im[iHeight:iHeight + SampleSize, iWidth:iWidth + SampleSize]) StdDevList.append(StdDev) # Im[iHeight:iHeight+SampleSize,iWidth:iWidth+SampleSize] = 0.25 for iWidth in range(MaskRightBorder, Width - SampleSize, SampleSize): StdDev = numpy.std(Im[iHeight:iHeight + SampleSize, iWidth:iWidth + SampleSize]) StdDevList.append(StdDev) # Im[iHeight:iHeight+SampleSize,iWidth:iWidth+SampleSize] = 0.5 # Calculate the bottom for iHeight in range(MaskBottomBorder, Height - SampleSize, SampleSize): for iWidth in range(0, Width - 1, SampleSize): StdDev = numpy.std(Im[iHeight:iHeight + SampleSize, iWidth:iWidth + SampleSize]) StdDevList.append(StdDev) # Im[iHeight:iHeight+SampleSize,iWidth:iWidth+SampleSize] = 0.75 del Im # nornir_imageregistration.ShowGrayscale(Im) return sum(StdDevList)
def set_layout(self, layout): """ sets the layout of the subplots =========== Parameters: =========== layout : *dict* a dictionary that defines the layout. Example dictionaries are collected in the module's dictionary 'layouts' ======== Returns: ======== (None) """ self.layout = layout self.mainframe = self.fig.add_axes([0, 0, 1, 1], frameon=False) self.mainframe.set_xticks([]) self.mainframe.set_yticks([]) lm = layout.get('legend_margins', (2., 2., 10., 10.)) # define subplots # walk through all subplots lmargin = float(layout['margins'][2]) / float(self.width) rmargin = 1. - float(layout['margins'][3]) / float(self.width) topmargin = 1. - float(layout['margins'][1]) / float(self.height) bottommargin = float(layout['margins'][0]) / float(self.height) # 1.2 * fontheight -> spacing between rows lsp = layout.get('legend_textvspace', 1.2) legendheight = (layout['legend_rows'] * layout['legend_fontsize'] / 72. * 25.4 * lsp + float(lm[0] + lm[1])) / float( self.height) if layout['legend_frame'] and layout['legend_location'] == 'top': topmargin -= (float(layout['spacing'][2]) / self.height + legendheight) haxes = rmargin - lmargin vaxes = topmargin - bottommargin hspacing = float(layout['spacing'][0]) / self.height vspacing = float(layout['spacing'][1]) / self.width gridboxwidth = (haxes - float(layout['subplot_grid_horiz'] - 1) * hspacing) / float(layout['subplot_grid_horiz']) gridboxheight = (vaxes - float(layout['subplot_grid_vert'] - 1) * vspacing) / float(layout['subplot_grid_vert']) rect = [0, 0, 0, 0] # dummy, will be overwritten for elem in layout['subplots']: draw_xticks = True draw_yticks = True if isinstance(elem, int): # a plain number -> a single grid point nleft = mod(elem, layout['subplot_grid_horiz']) nbtm = elem // layout['subplot_grid_horiz'] # this has only an effect if layout['ticklabels_outer_only'] is set if nleft > 0: draw_yticks = False if nbtm != layout['subplot_grid_vert'] - 1: draw_xticks = False rect = [ lmargin + nleft * gridboxwidth + nleft * hspacing, topmargin - (nbtm + 1) * gridboxheight - nbtm * vspacing, gridboxwidth, gridboxheight ] elif isinstance(elem, tuple): # a tuple defining first and last box nleft0 = mod(elem[0], layout['subplot_grid_horiz']) nbtm0 = elem[0] // layout['subplot_grid_horiz'] nleft1 = mod(elem[1], layout['subplot_grid_horiz']) nbtm1 = elem[1] // layout['subplot_grid_horiz'] if nleft0 > 0: draw_yticks = False if nbtm1 != layout['subplot_grid_vert'] - 1: draw_xticks = False rect = [ lmargin + nleft0 * gridboxwidth + nleft0 * hspacing, topmargin - (nbtm1 + 1) * gridboxheight - nbtm1 * vspacing, gridboxwidth * (nleft1 - nleft0 + 1) + hspacing * (nleft1 - nleft0), gridboxheight * (nbtm1 - nbtm0 + 1) + vspacing * (nbtm1 - nbtm0) ] else: raise ValueError('invalid subplot configuration - only ' + 'integers and tuples are allowed') self.axes.append(self.fig.add_axes(rect)) if layout.get('ticklabels_outer_only', False): if not draw_xticks: self.axes[-1].set_xticklabels([]) if not draw_yticks: self.axes[-1].set_yticklabels([]) self.haxes = haxes self.vaxes = vaxes self.bottommargin = bottommargin self.lmargin = lmargin self.legendheight = legendheight if layout['legend_frame']: if layout['legend_location'] != 'top': raise NotImplementedError('other positions than "top" not ' + 'yet implemented!') # define legend frame rect = [ lmargin, 1. - float(layout['margins'][1]) / float(self.height) - legendheight, haxes, legendheight ] self.legendax = self.fig.add_axes(rect) self.legendax.set_xticks([]) self.legendax.set_yticks([])
def set_layout(self, layout): """ sets the layout of the subplots =========== Parameters: =========== layout : *dict* a dictionary that defines the layout. Example dictionaries are collected in the module's dictionary 'layouts' ======== Returns: ======== (None) """ self.layout = layout self.mainframe = self.fig.add_axes([0, 0, 1, 1], frameon=False) self.mainframe.set_xticks([]) self.mainframe.set_yticks([]) lm = layout.get('legend_margins', (2., 2., 10., 10.)) # define subplots # walk through all subplots lmargin = float(layout['margins'][2]) / float(self.width) rmargin = 1. - float(layout['margins'][3]) / float(self.width) topmargin = 1. - float(layout['margins'][1]) / float(self.height) bottommargin = float(layout['margins'][0]) / float(self.height) # 1.2 * fontheight -> spacing between rows lsp = layout.get('legend_textvspace', 1.2) legendheight = ( layout['legend_rows'] * layout['legend_fontsize'] / 72. * 25.4 * lsp + float(lm[0] + lm[1])) / float(self.height) if layout['legend_frame'] and layout['legend_location'] == 'top': topmargin -= (float(layout['spacing'][2]) / self.height + legendheight) haxes = rmargin - lmargin vaxes = topmargin - bottommargin hspacing = float(layout['spacing'][0]) / self.height vspacing = float(layout['spacing'][1]) / self.width gridboxwidth = (haxes - float(layout['subplot_grid_horiz'] - 1) * hspacing )/ float(layout['subplot_grid_horiz']) gridboxheight = (vaxes - float(layout['subplot_grid_vert'] - 1) * vspacing ) / float(layout['subplot_grid_vert']) rect=[0, 0, 0, 0] # dummy, will be overwritten for elem in layout['subplots']: draw_xticks = True draw_yticks = True if isinstance(elem, int): # a plain number -> a single grid point nleft = mod(elem, layout['subplot_grid_horiz']) nbtm = elem // layout['subplot_grid_horiz'] # this has only an effect if layout['ticklabels_outer_only'] is set if nleft > 0: draw_yticks = False if nbtm != layout['subplot_grid_vert'] - 1: draw_xticks = False rect = [lmargin + nleft * gridboxwidth + nleft * hspacing, topmargin - (nbtm + 1) * gridboxheight - nbtm * vspacing, gridboxwidth, gridboxheight] elif isinstance(elem, tuple): # a tuple defining first and last box nleft0 = mod(elem[0], layout['subplot_grid_horiz']) nbtm0 = elem[0] // layout['subplot_grid_horiz'] nleft1 = mod(elem[1], layout['subplot_grid_horiz']) nbtm1 = elem[1] // layout['subplot_grid_horiz'] if nleft0 > 0: draw_yticks = False if nbtm1 != layout['subplot_grid_vert'] - 1: draw_xticks = False rect = [lmargin + nleft0 * gridboxwidth + nleft0 * hspacing, topmargin - (nbtm1 + 1) * gridboxheight - nbtm1 * vspacing, gridboxwidth * (nleft1 - nleft0 + 1) + hspacing * (nleft1 - nleft0), gridboxheight * (nbtm1 - nbtm0 + 1) + vspacing * (nbtm1 - nbtm0)] else: raise ValueError('invalid subplot configuration - only ' + 'integers and tuples are allowed') self.axes.append(self.fig.add_axes(rect)) if layout.get('ticklabels_outer_only', False): if not draw_xticks: self.axes[-1].set_xticklabels([]) if not draw_yticks: self.axes[-1].set_yticklabels([]) self.haxes = haxes self.vaxes = vaxes self.bottommargin = bottommargin self.lmargin = lmargin self.legendheight = legendheight if layout['legend_frame']: if layout['legend_location'] != 'top': raise NotImplementedError('other positions than "top" not ' + 'yet implemented!') # define legend frame rect = [lmargin, 1. - float(layout['margins'][1]) / float(self.height) - legendheight, haxes, legendheight] self.legendax = self.fig.add_axes(rect) self.legendax.set_xticks([]) self.legendax.set_yticks([])