x = np.arange(10) y = np.arange(15) X, Y = np.meshgrid(x, y) XY = np.hstack((X.ravel()[:,np.newaxis], Y.ravel()[:,np.newaxis])) ww = X/10.0 hh = Y/15.0 aa = X*9 ax = plt.subplot(1,1,1) ec = EllipseCollection( ww, hh, aa, units='x', offsets=XY, transOffset=ax.transData) ec.set_array((X+Y).ravel()) ax.add_collection(ec) ax.autoscale_view() ax.set_xlabel('X') ax.set_ylabel('y') cbar = plt.colorbar(ec) cbar.set_label('X+Y') plt.show()
x = np.linspace(0, 2 * size, 2 * size) y = np.linspace(0, 2 * size, 2 * size) X, Y = np.meshgrid(x, y) # Ellipses Plotting # XY = np.column_stack((X.ravel(), -Y.ravel())) fig, ax = plt.subplots() ax.set_facecolor('white') ec = EllipseCollection(w, h, np.rad2deg(Psi), units='xy', offsets=XY, transOffset=ax.transData, cmap='Greens', facecolors='none') ec.set_array(S0.ravel()) # Scales ellipse colour to intensity (i.e. S0) # ec.set_array(H.ravel()) This line may be used to allow for the scaling of the ellipse colour with the measured # handedness (i.e. +/- 1 for right/left respectively) ax.add_collection(ec) ax.autoscale_view() c_bar = plt.colorbar(ec) c_bar.set_label('Measured $S_0$') plt.axis('off') # Remove this line to see the axes plt.show()
def draw_netwulf(network_properties, fig=None, ax=None, figsize=None, draw_links=True, draw_nodes=True, link_zorder=-1, node_zorder=1000): """ Redraw the visualization using matplotlib. Creates figure and axes if None provided. In order to add labels, check out :mod:`netwulf.tools.add_node_label` and :mod:`netwulf.tools.add_edge_label` Parameters ---------- network_properties : dict The network properties which are returned from the interactive visualization. fig : matplotlib.Figure, default : None The figure in which to draw ax : matplotlib.Axes, default : None The Axes in which to draw figsize : float, default : None the size of the figure in inches (sidelength of a square) if None, will be taken as the minimum of the values in ``matplotlib.rcParams['figure.figsize']``. draw_links : bool, default : True Whether the links should be drawn draw_nodes : bool, default : True Whether the nodes should be drawn Returns ------- fig : matplotlib.Figure, default : None Resulting figure ax : matplotlib.Axes, default : None Resulting axes """ # if no figure given, create a square one if ax is None or fig is None: if figsize is None: size = min(mpl.rcParams['figure.figsize']) else: size = figsize fig = pl.figure(figsize=(size, size)) ax = fig.add_axes([0, 0, 1, 1]) # Customize the axis # remove top and right spines ax.spines['right'].set_color('none') ax.spines['left'].set_color('none') ax.spines['top'].set_color('none') ax.spines['bottom'].set_color('none') # turn off ticks ax.xaxis.set_ticks_position('none') ax.yaxis.set_ticks_position('none') ax.xaxis.set_ticklabels([]) ax.yaxis.set_ticklabels([]) # for conversion of inches to points # (important for markersize and linewidths). # Apparently matplotlib uses 72 dpi internally for conversions in all figures even for those # which do not follow dpi = 72 which is freaking weird but hey why not. dpi = 72 # set everything square and get the axis size in points ax.axis('square') ax.axis('off') ax.margins(0) ax.set_xlim(network_properties['xlim']) ax.set_ylim(network_properties['ylim']) bbox = ax.get_window_extent().transformed(fig.dpi_scale_trans.inverted()) axwidth, axheight = bbox.width * dpi, bbox.height * dpi # filter out node positions for links width = network_properties['xlim'][1] - network_properties['xlim'][0] height = network_properties['ylim'][1] - network_properties['ylim'][0] pos = { node['id']: np.array([node['x_canvas'], height - node['y_canvas']]) for node in network_properties['nodes'] } if draw_links: #zorder = max( _c.get_zorder() for _c in ax.get_children()) + 1 zorder = -1 # make sure that links are very much in the background lines = [] linewidths = [] linecolors = [] for link in network_properties['links']: u, v = link['source'], link['target'] lines.append([[pos[u][0], pos[v][0]], [pos[u][1], pos[v][1]]]) linewidths.append(link['width'] / width * axwidth) if 'color' in link.keys(): linecolors.append(link['color']) else: linecolors.append(network_properties['linkColor']) # collapse to line segments lines = [list(zip(x, y)) for x, y in lines] # plot Lines alpha = network_properties['linkAlpha'] ax.add_collection( LineCollection(lines, colors=linecolors, alpha=alpha, linewidths=linewidths, zorder=zorder)) if draw_nodes: zorder = max(_c.get_zorder() for _c in ax.get_children()) + 1 # compute node positions and properties XY = [] size = [] node_colors = [] for node in network_properties['nodes']: XY.append([node['x_canvas'], height - node['y_canvas']]) # size has to be given in points*2 size.append(2 * node['radius']) node_colors.append(node['color']) XY = np.array(XY) size = np.array(size) circles = EllipseCollection( size, size, np.zeros_like(size), offsets=XY, units='x', transOffset=ax.transData, facecolors=node_colors, linewidths=network_properties['nodeStrokeWidth'] / width * axwidth, edgecolors=network_properties['nodeStrokeColor'], zorder=zorder) ax.add_collection(circles) return fig, ax
def plot_people(ifig, dom, people, contacts, U, colors, time=-1, axis=None, plot_people=True, plot_contacts=True, plot_velocities=True, plot_paths=False, paths=None, plot_sensors=False, sensors=[], savefig=False, filename='fig.png', cmap='winter'): """ This function draws spheres for the individuals, \ lines for the active contacts and arrows for the \ (desired or real) velocities. If specified, also \ spawns a new process (which is returned) to save \ the resulting figure to the disk. Parameters ---------- ifig: int figure number dom: Domain contains everything for managing the domain people: numpy array people coordinates and radius : x,y,r contacts: numpy array all the contacts : i,j,dij,eij_x,eij_y U: numpy array people velocities colors: numpy array scalar field used to define people colors time: float time in seconds axis: numpy array matplotlib axis : [xmin, xmax, ymin, ymax] plot_people: boolean draws spheres for people if true plot_paths: boolean draws people paths if true paths: numpy array coordinates of the people paths plot_sensors: boolean draws sensor lines if true sensors: numpy array sensor line coordinates (see also the sensor function below) savefig: boolean writes the figure as a png file if true filename: string png filename used to write the figure cmap: string matplotlib colormap name Returns ------- process: multiprocessing.Process process which is saving the image """ fig = plt.figure(ifig) plt.clf() ax1 = fig.add_subplot(111) # Domain ax1.imshow(dom.image, interpolation='nearest', extent=[dom.xmin, dom.xmax, dom.ymin, dom.ymax], origin='lower') if (plot_people): # People #offsets = list(zip(people[:,:2])) ## for older versions of matplotlib... offsets = people[:, :2] ec = EllipseCollection(widths=2 * people[:, 2], heights=2 * people[:, 2], angles=0, units='xy', cmap=plt.get_cmap(cmap), offsets=offsets, transOffset=ax1.transData) ec.set_array(colors) ax1.add_collection(ec) if (plot_contacts): # Contacts Nc = contacts.shape[0] if (Nc > 0): for ic in sp.arange(Nc): i = sp.int64(contacts[ic, 0]) j = sp.int64(contacts[ic, 1]) if (j != -1): line = Line2D([people[i, 0], people[j, 0]], [people[i, 1], people[j, 1]], lw=1., alpha=0.6, color='k') else: line = Line2D([ people[i, 0], people[i, 0] - (people[i, 2] + contacts[ic, 2]) * contacts[ic, 3] ], [ people[i, 1], people[i, 1] - (people[i, 2] + contacts[ic, 2]) * contacts[ic, 4] ], lw=1., alpha=0.6, color='k') ax1.add_line(line) if (plot_velocities): # Velocities Np = people.shape[0] for ip in sp.arange(Np): arrow = Arrow(people[ip, 0], people[ip, 1], U[ip, 0], U[ip, 1], width=0.3) ax1.add_patch(arrow) if ((plot_paths) and (paths is not None)): mpaths = sp.ma.masked_values(paths, 1e99) pathlines = [] for id in sp.arange(paths.shape[0]): pathlines.append(sp.swapaxes(mpaths[id, :, :], 0, 1)) pathlinecoll = LineCollection(pathlines, linewidths=0.5, linestyle="solid", cmap=plt.get_cmap(cmap)) pathlinecoll.set_array(colors) ax1.add_collection(pathlinecoll) if (plot_sensors): # Sensors for ss in sensors: line = Line2D([ss[0], ss[2]], [ss[1], ss[3]], lw=1., alpha=0.6, color='g') ax1.add_line(line) if (axis): ax1.set_xlim(axis[0], axis[1]) ax1.set_ylim(axis[2], axis[3]) ax1.set_xticks([]) ax1.set_yticks([]) ax1.axis('off') if (time >= 0): ax1.set_title('time = {:.2F}'.format(time) + ' s') fig.canvas.draw() if (savefig): process = Process(target=do_savefig, args=( fig, filename, )) process.start() return process
def main(): ########################################################################### ###################### Problem Definition Start ########################### ########################################################################### # Close any existing figure plt.close('all') # Define steer function variables dt = 0.2 # discretized time step N = 10 # Prediction horizon rDia = 0.1 # Diameter of robot # Define MPC input constraints xMax = 2 # Max Position xMin = -xMax # Min Position vMax = 0.6 # Max Linear Velocity vMin = -vMax # Min Linear Velocity wMax = pi/4 # Max Angular Velocity wMin = -wMax # Min Angular Velocity # Define the weighing matrices Q for states and R for inputs Q = np.diag([1, 5, 0.1]) R = np.diag([0.5, 0.05]) # Create state variables for using in Casadi & set up some aliases states = struct_symSX(["x","y", "theta"]) # vertcat(x, y, theta) x,y,theta = states[...] numStates = states.size # Create input variables for using in Casadi & set up some aliases controls = struct_symSX(["v", "omega"]) v, omega = controls[...] numControls = controls.size # Define the Nonlinear state equation (Righthand side) nonlinearDynamics = struct_SX(states) nonlinearDynamics["x"] = v*cos(theta) nonlinearDynamics["y"] = v*sin(theta) nonlinearDynamics["theta"] = omega # Nonlinear State Update function f(x,u) # Given {states, controls} as inputs, returns {nonlinearDynamics} as output f = Function('f',[states,controls], [nonlinearDynamics]) ## Create the bounds for constraints values # Zero Bounds For Dynamics Equality Constraint lbg_values = np.zeros(numStates*(N+1)) ubg_values = np.zeros(numStates*(N+1)) # Initialize Bounds For State Constraints lbx_values = np.zeros((numStates*(N+1)+numControls*N,1)) ubx_values = np.zeros((numStates*(N+1)+numControls*N,1)) # Create the indices list for states and controls xIndex = np.arange(0, numStates*(N+1), numStates).tolist() yIndex = np.arange(1, numStates*(N+1), numStates).tolist() thetaIndex = np.arange(2, numStates*(N+1), numStates).tolist() vIndex = np.arange(numStates*(N+1), numStates*(N+1)+numControls*N, numControls).tolist() omegaIndex = np.arange(numStates*(N+1)+1, numStates*(N+1)+numControls*N, numControls).tolist() # Feed Bounds For State Constraints lbx_values[xIndex,:] = -float("inf") # xMin lbx_values[yIndex,:] = -float("inf") # xMin lbx_values[thetaIndex,:] = -float("inf") ubx_values[xIndex,:] = float("inf") # xMax ubx_values[yIndex,:] = float("inf") # xMax ubx_values[thetaIndex,:] = float("inf") # Feed Bounds For Input Constraints lbx_values[vIndex, :] = vMin lbx_values[omegaIndex, :] = wMin ubx_values[vIndex, :] = vMax ubx_values[omegaIndex, :] = wMax # Create the arguments dictionary to hold the constraint values argums = {'lbg': lbg_values, 'ubg': ubg_values, 'lbx': lbx_values, 'ubx': ubx_values} # Define parameters - Things that change during optimization # Control Inputs for N time steps, Initial states & Reference states # U-controls, P[0:numStates-1]-states, P[numStates:2*numStates-1]-Reference # X: Vector that represents the states over the optimization problem U = struct_symSX([entry("U", shape = (numControls, N))]) # Decision vars (controls) P = struct_symSX([entry("P", shape = (2*numStates,1))]) # Decision vars (states) X = struct_symSX([entry("X", shape = (numStates,N+1))]) # History of states # Specify initial state st_k = X["X", :, 0] # Objective function - will be defined shortly below obj = 0 # constraints vector g = [] # Add the initial state constraint g.append(st_k - P["P", 0:numStates]) # Form the obj_fun and update constraints for k in range(N): st_k = X["X", :, k] u_k = U["U", :, k] x_error = st_k - P["P", numStates:2*numStates] # Calculate objective function obj = obj + x_error.T @ Q @ x_error + u_k.T @ R @ u_k st_next = X["X", :, k+1] f_value = f(st_k, u_k) st_pred = st_k + dt*f_value # Add the constraints g.append(st_next - st_pred) # compute constraints ########################################################################### ###################### Problem Definition Complete ######################## ########################################################################### ########################################################################### ###################### Simulation Loop Start ############################## ########################################################################### # Start the simulation loop t0 = 0 # Initial time for each MPC iteration simTime = 20 # Maximum simulation time checkTol = 0.05 # MPC Loop tolerance xRef = np.array([[1.5], [1.5], [0]]) # Reference pose x0 = np.zeros((numStates,1)) # Initial states S0 = np.array([[0.01, 0, 0], [0, 0.02, 0], [0, 0, 0.001]]) SigmaW = 0.001*np.identity(numStates) # States: (x,y,theta) SigmaV = 0.001*np.identity(numStates-1) # Outputs: (r,phi) # Define the dictionary to pass paramters for UKF state estimation ukfParam = {"n_z": numStates, "Q": SigmaW, "R": SigmaV} # Define Data Structures to store history xHist = [x0] # For states tHist = [] # For initial times sHist = [S0] # For covariances # Specify the initial conditions u0 = np.zeros((N, numControls)) X0 = repmat(x0, 1, N+1).T # State Nonlinear MPC iteration Loop mpcIter = 0 xMPC = [] uMPC = [] # Make the decision variables as one column vector optVariables = vertcat(X.cat, U.cat) # Feed the solver options opts = {"print_time": False, "ipopt.print_level":0, "ipopt.max_iter":2000, "ipopt.acceptable_tol": 1e-8, "ipopt.acceptable_obj_change_tol": 1e-6} # Create the nlp problem structure with obj_fun, variables & constraints nlp = {"x":optVariables, "p":P, "f":obj, "g":vcat(g)} # Call the IPOPT solver with nlp object and options S = nlpsol("solver", "ipopt", nlp, opts) # Start the timer startTime = time.time() while mpcIter < simTime/dt: # and LA.norm(x0 - xRef) > checkTol: if LA.norm(x0 - xRef) < checkTol: break print('MPC iteration:', mpcIter) # Set the values of the parameters vector argums['p'] = np.vstack((x0, xRef)) # Set initial value of the optimization variables argums['x0'] = np.vstack(((X0.T).reshape((numStates*(N+1),1)), (u0.T).reshape((numControls*N,1)))) # Solve the NMPC using IPOPT solver soln = S(x0 = argums['x0'], p = argums['p'], lbg = argums['lbg'], ubg = argums['ubg'], lbx = argums['lbx'], ubx = argums['ubx']) # Retrieve the solution xSol = soln['x'] # Extract the minimizing control u = xSol[numStates*(N+1):].full().reshape(N, numControls) uShape = np.shape(u) # Store only the input at the first time step uMPC.append(u[0,:].T) # Update the time history tHist.append(t0) # Apply the control and shift the solution # Get the nonlinear propagation w.r.t given states and controls fValue = f(x0, u[0,:].T) x0 = x0 + dt*fValue x0 = x0.full() t0 = t0 + dt u0 = np.vstack((u[1:,:], u[-1,:])) # Update the dictionary to call the UKF state estimator ukfParam["x0"] = x0 ukfParam["u0"] = u[0,:].T ukfParam["S0"] = S0 # Call the UKF to get the state estimate ukfOutput = UKF(ukfParam) # Unbox the UKF state estimate & covariance x0 = ukfOutput["stateMean"] S0 = ukfOutput["stateCovar"] # Reshape x0 to comply to its dimensions x0 = np.reshape(x0, (numStates, 1)) # Update the state history xHist.append(x0) sHist.append(S0) # Reshape and get solution TRAJECTORY X0 = xSol[0:numStates*(N+1)].full().reshape(N+1, numStates) # Store the MPC trajectory xMPC.append(X0) # Shift trajectory to initialize the next step X0 = np.vstack((X0[1:,:], X0[-1,:])) # Increment the MPC iteration number mpcIter = mpcIter + 1 # End of while loop # End the timer and fetch the time for total iteration time totalTime = time.time() - startTime print('Average MPC Iteration time = ', totalTime/(mpcIter + 1)) print('x0 and xRef are: ', np.c_[x0, xRef]) # How close is the solution to the reference provided solnError = LA.norm(x0 - xRef) print('|| X_{MPC}(final) - X_{ref} || = ', solnError) totalIter = mpcIter print('Total number of Iterations: ', totalIter) STEER_TIME = 10 iterIndices = [(totalIter // STEER_TIME) + (1 if i < (totalIter % STEER_TIME) else 0) for i in range(STEER_TIME)] iterIndices.insert(0,0) reqIndices = [sum(iterIndices[:i+1]) for i in range(len(iterIndices))] reqIndices[-1] = reqIndices[-1] - 1 print('Required Indices = ', reqIndices) ## Plot the MPC trajectory rRad = rDia/2 angles = np.arange(0, 2*pi, 0.005).tolist() xPoint = rRad*cos(angles) yPoint = rRad*sin(angles) xPoint = 0 yPoint = 0 xHistShape = np.shape(xHist) # Plot the reference state plt.figure(figsize = [16,9]) plt.plot(xRef[0], xRef[1], 'sb') plt.plot(xHist[0][0], xHist[0][1], 'dk') # Plot the predicted and true trajectory for k in range(xHistShape[0]): xkHist = xHist[k] # Plot plt.plot(xkHist[0,:], xkHist[1,:], '-r') if k < xHistShape[0] - 1: xkMPCTraj = xMPC[k] indices1N = np.arange(N).tolist() rzz, = plt.plot(xkMPCTraj[indices1N,0], xkMPCTraj[indices1N,1], '--*k') rx, = plt.plot(xkHist[0,:]+xPoint, xkHist[1,:]+yPoint, '--r') plt.pause(0.1001) if k < xHistShape[0]-1: rx.remove() rzz.remove() plt.pause(1.000) plt.close() # Plot the required States with ellipses plt.figure(figsize = [16,9]) plt.plot(xRef[0], xRef[1], 'sb') plt.plot(xHist[0][0], xHist[0][1], 'dk') xValues = [] yValues = [] widthValues = [] heightValues = [] angleValues = [] for k in range(len(reqIndices)): x_kHist = xHist[reqIndices[k]] s_kHist = sHist[reqIndices[k]] s_kHist = s_kHist[0:numStates-1, 0:numStates-1] alfa = math.atan2(x_kHist[1], x_kHist[0]) elcovar = np.asarray(s_kHist) elE, elV = LA.eig(elcovar) xValues.append(x_kHist[0]) yValues.append(x_kHist[1]) widthValues.append(math.sqrt(elE[0])) heightValues.append(math.sqrt(elE[1])) angleValues.append(alfa*360) # Scatter plot all the mean points plt.scatter(xValues, yValues) plt.plot(xValues, yValues) # Plot all the covariance ellipses XY = np.column_stack((xValues, yValues)) ec = EllipseCollection(widthValues, heightValues, angleValues, units='x', offsets=XY, facecolors="#C59434", transOffset=plt.axes().transData) ec.set_alpha(0.6) plt.axes().add_collection(ec)
n_total += len(m500) m_filter = np.where(m500 > 10**13)[0] n_largeM += len(m_filter) ax.scatter(cop[m_filter, 0], cop[m_filter, 1], marker='o', s=2, c='r', alpha=1) offsets = list(zip(cop[m_filter, 0], cop[m_filter, 1])) ax.add_collection( EllipseCollection(widths=r200[m_filter] * 5, heights=r200[m_filter] * 5, angles=0, units='xy', facecolors='r', offsets=offsets, alpha=0.3, transOffset=ax.transData)) m_filter = np.where(m500 < 10**13)[0] ax.scatter(cop[m_filter, 0], cop[m_filter, 1], marker='o', s=2, c='k', alpha=0.02) # offsets = list(zip(cop[m_filter, 0], cop[m_filter, 1])) # ax.add_collection(EllipseCollection(widths=r200[m_filter] * 5, heights=r200[m_filter] * 5, angles=0, units='xy', # facecolors='k', offsets=offsets, alpha=0.3, # transOffset=ax.transData))
def _init(self): """ Initialise display """ # Recompute volume self.real_volume = np.prod(self.L - self.d.mean()) - .25 * np.pi * sum( self.d**2) # No update during setup plt.ioff() self.fig.clear() show_v = self.toshow['velocities'] show_s = self.toshow['speeds'] show_p = self.toshow['pressure'] if sum([show_v, show_s, show_p]) > 1: raise RuntimeError( 'Can show only velocities OR speeds OR pressure') if show_v or show_s or show_p: # Create two side-by-side axes, with a histogram of the x-component of the velodicities in the second one. axes = [ self.fig.add_subplot(121, aspect='equal', adjustable='box'), self.fig.add_subplot(122) ] if show_v: axes[1].set_xlabel('velocity along x') elif show_s: axes[1].set_xlabel('speeds') elif show_p: axes[1].set_xlabel('time') if show_p: axes[1].set_ylabel('momentum') else: # Y axis does not mean much axes[1].get_yaxis().set_visible(False) if show_p: self._pressure = 0 self.plot_pressure, self.plot_pressure_theory = axes[1].plot( [0], [0], 'b-', [0], [0], 'k-') else: # Generate initial histogram if show_v: f, bins = np.histogram(self.v[:, 0], int(np.sqrt(self.N)), range=(self.vxmin, self.vxmax), density=True) else: f, bins = np.histogram(np.sqrt((self.v**2).sum(axis=1)), int(np.sqrt(self.N)), range=(0., self.v2max), density=True) binwidth = bins[1] - bins[0] # Create bar graph self.vhist = axes[1].bar(bins[:-1], f, width=binwidth, align='edge') else: # Create just one axis - the particle box axes = [ self.fig.add_subplot(111, aspect='equal', adjustable='box') ] # Set box size and axis properties axes[0].axis([0, self.L[0], 0, self.L[1]]) axes[0].get_xaxis().set_visible(False) axes[0].get_yaxis().set_visible(False) # Draw particles circles = EllipseCollection(widths=self.d, heights=self.d, angles=0, units='xy', facecolors='k', offsets=self.r, transOffset=axes[0].transData) axes[0].add_collection(circles) # Create colormap self.cm = plt.get_cmap('plasma') self.fig.tight_layout() self.circles = circles to_return = (circles, ) # Option to show the trace of one particle (to illustrate random walk) if self.toshow['trace'] is not None: i = self.toshow['trace'] self.trace = plt.plot([self.r[i, 0]], [self.r[i, 1]], 'k-')[0] self._vtrace = self.v[i].copy() to_return += (self.trace, ) # Option to show velocity arrows if self.toshow['quiver']: quiver = plt.quiver(self.r[:, 0], self.r[:, 1], self.v[:, 0], self.v[:, 1], units='xy', scale=35. * self.vRMS / self.L.mean()) self.quiver = quiver to_return += (quiver, ) self.axes = axes if show_s or show_v: p0 = axes[0].get_position() p1 = axes[1].get_position() axes[1].set_position([p1.x0, p0.y0, p0.width, p0.height]) to_return += (self.vhist, ) if show_p: p0 = axes[0].get_position() p1 = axes[1].get_position() axes[1].set_position([p1.x0, p0.y0, p0.width, p0.height]) to_return += (self.plot_pressure, self.plot_pressure_theory) # Process all obstacles (polygons) if self.obstacles: for obs in self.obstacles: vc = obs['vertices'] axes[0].add_patch(Polygon(vc, facecolor='black')) return to_return
y = samples[:, 2] fig, ax = plt.subplots() ax.set_xlim(-0.5 * 15, 0.5 * 15) ax.set_ylim(-0.5 * 15, 0.5 * 15) ax.set_aspect('equal') plt.ylabel('position~$y$') plt.xlabel('position~$x$') radius = 1.0 ellipse_pos = EllipseCollection(widths=radius, heights=radius, angles=0, units='xy', facecolors='r', offsets=[], transOffset=ax.transData) ellipse_neg = EllipseCollection(widths=radius, heights=radius, angles=0, units='xy', facecolors='b', offsets=[], transOffset=ax.transData) ax.add_collection(ellipse_pos) ax.add_collection(ellipse_neg) idx_pos = q > 0.0 idx_neg = np.logical_not(idx_pos)
def circular_border(ax): offsets = [width/2, height/2] color = 'k' size = width - 10 ax.add_collection(EllipseCollection(widths=size, heights=size, angles=0, units='xy', facecolors='w', edgecolors='k', offsets=offsets, transOffset=ax.transData))
def overlay_skies(self, ax, diameter=None, return_figure=True, **kwargs): """ Overlay the sky fibers on a plot Parameters: ax (Axis): The matplotlib axis object diameter (float): The fiber diameter in arcsec return_figure (bool): If True, returns the figure axis object. Default is True kwargs: Any keyword arguments accepted by Matplotlib EllipseCollection """ if self.wcs is None: raise MarvinError('No WCS found. Cannot overlay sky fibers.') # check for sky coordinates if self.bundle.skies is None: self.bundle.get_sky_coordinates() # check the diameter if diameter: assert isinstance(diameter, (float, int)), 'diameter must be a number' diameter = (diameter or 2.0) / float(self.header['SCALE']) # get sky fiber pixel positions fiber_pix = self.wcs.wcs_world2pix(self.bundle.skies, 1) outside_range = ((fiber_pix < 0) | (fiber_pix > self.data.size[0])).any() if outside_range: raise MarvinError( 'Cannot overlay sky fibers. Image is too small. ' 'Please retrieve a bigger image cutout') # some matplotlib kwargs kwargs['edgecolor'] = kwargs.get('edgecolor', 'Orange') kwargs['facecolor'] = kwargs.get('facecolor', 'none') kwargs['linewidth'] = kwargs.get('linewidth', 0.7) # draw the sky fibers ec = EllipseCollection(diameter, diameter, 0.0, units='xy', offsets=fiber_pix, transOffset=ax.transData, **kwargs) ax.add_collection(ec) # Add a larger circle to help identify the sky fiber locations in large images. if (self.data.size[0] > 1000) or (self.data.size[1] > 1000): ec = EllipseCollection(diameter * 5, diameter * 5, 0.0, units='xy', offsets=fiber_pix, transOffset=ax.transData, **kwargs) ax.add_collection(ec) if return_figure: return ax
def DrawGraph(self, lastFlag, randNode=None): """ Updates the Plot with uncertainty ellipse and trajectory at each time step Input Parameters: lastFlag: Flag to denote if its the last iteration randNode: Node data representing the randomly sampled point """ xValues = [] yValues = [] widthValues = [] heightValues = [] angleValues = [] lineObjects = [] for ellipseNode in self.nodeList: if ellipseNode is not None and ellipseNode.parent is not None: ellNodeShape = ellipseNode.means.shape xPlotValues = [] yPlotValues = [] # Prepare the trajectory x and y vectors and plot them for k in range(ellNodeShape[0]): xPlotValues.append(ellipseNode.means[k, 0, 0]) yPlotValues.append(ellipseNode.means[k, 1, 0]) # Plotting the risk bounded trajectories lx, = plt.plot(xPlotValues, yPlotValues, color='#636D97', linewidth=2.0) lineObjects.append(lx) # Plot only the last ellipse in the trajectory alfa = math.atan2(ellipseNode.means[-1, 1, 0], ellipseNode.means[-1, 0, 0]) elcovar = np.asarray(ellipseNode.covar[-1, :, :]) elE, elV = LA.eig(elcovar[0:2, 0:2]) xValues.append(ellipseNode.means[-1, 0, 0]) yValues.append(ellipseNode.means[-1, 1, 0]) widthValues.append(math.sqrt(elE[0])) heightValues.append(math.sqrt(elE[1])) angleValues.append(alfa * 360) # Plot the randomly sampled point rx, = plt.plot(randNode.means[-1, 0, :], randNode.means[-1, 1, :], "^k") # Plot the Safe Ellipses XY = np.column_stack((xValues, yValues)) ec = EllipseCollection(widthValues, heightValues, angleValues, units='x', offsets=XY, facecolors="#C59434", transOffset=plt.axes().transData) ec.set_alpha(0.5) plt.axes().add_collection(ec) plt.pause(0.0001) if not lastFlag: ec.remove() rx.remove() for lx in lineObjects: lx.remove()
def produce_demo_for_synapses_to_postsynapses(): origin = np.asarray([5.0, 5.0]) end = np.asarray([13.0, 14.0]) direction = cart_to_pol(end - origin) origins = generate_random_points_along_line(origin, direction, 100, 20) number_of_circles = 250 circle_origins = [ produce_bounded_random_point(15.0, 15.0) for i in range(number_of_circles) ] circle_radiuses = [ np.random.normal(1.5, 0.5, size=1)[0] for i in range(number_of_circles) ] fig, ax = plt.subplots(1, figsize=(3, 3)) ax.plot([origin[0], end[0]], [origin[1], end[1]], color="y", linewidth=1.0, label="Axon Segment") ax.scatter([p[0] for p in origins], [p[1] for p in origins], label="Chosen Origins for Post Synaptic Attempts", color="b", s=15, zorder=5) ax.add_collection( EllipseCollection(widths=[2 * x for x in circle_radiuses], heights=[2 * x for x in circle_radiuses], angles=0, units='xy', facecolors='r', offsets=circle_origins, transOffset=ax.transData, alpha=0.1, label="Pool of Postsynapses")) chosen_circle_origins = [] chosen_circle_radiuses = [] for origin in origins: i = choose_random_circle_as_connection_index(origin, circle_origins, circle_radiuses) chosen_circle_origins.append(circle_origins[i][:]) chosen_circle_radiuses.append(circle_radiuses[i]) ax.add_collection( EllipseCollection(widths=[x * 2 for x in chosen_circle_radiuses], heights=[x * 2 for x in chosen_circle_radiuses], angles=0, units='xy', facecolors='g', offsets=chosen_circle_origins, transOffset=ax.transData, alpha=0.2, label="Connected Postsynapses")) ax.set_title("PostSynapse Choosing For Growth") ax.set_aspect('equal', 'datalim') legend = ax.legend(loc='upper left', shadow=True) plt.tight_layout() plt.savefig( generate_tex_friendly_filename("paperfigs/SynapseChoosingForGrowth") + ".pdf") plt.close(fig) print("Finished SynapseChoosingForGrowth in " + str(time.time() - t))
def TransDisplay(self, data, A_or_B, major_axis=20, minor_axis=6, angle=None, cbar_label='', colorbar_lim=None, max_color_range=True, combine_colorbar=False): """This function creates a color plot of data, for probe A_or_B. The feed horns are represented using ellipses of size major_axis & minor_axis, rotated by angle. If angle is None, uses self.angle_file; if that's also None, throws error. data must be a correctly organized array. The plot is drawn on succeeding figures. The graph is labeled title, and the colour bar is labeled cbar_label. colorbar_lim and max_color_range explained in draw_ellipses docs. combine_colorbar is only relevant if multiple sets of ellipses are being plotted on the same figure. In that case, only 1 colorbar is shown if combine_colorbar=True, and one colorbar is shown for each set of data if it is False. Returns the EllipseCollection.""" if A_or_B == 'A': x = self.beam_centers_Ax y = self.beam_centers_Ay elif A_or_B == 'B': x = self.beam_centers_Bx y = self.beam_centers_By else: print "I'm sorry that you do not understand that " + A_or_B + " is not A and is not B!" return major_axes = np.ones(len(x)) * major_axis minor_axes = np.ones(len(x)) * minor_axis if angle != None: angles = np.ones(len(x)) * angle # print angles else: angles = self.get_angles(A_or_B) if len(angles) != len(x): raise Exception("Angles file is invalid!") XY = np.hstack((x[:, np.newaxis], y[:, np.newaxis])) if combine_colorbar and self.curr_ellipses != None: plt.gcf().clear() ax = plt.subplot(1, 1, 1) #Make a new collection, containing all previous data plus new data old_majors = self.curr_ellipses._widths * 2 old_minors = self.curr_ellipses._heights * 2 #old_angles in radians, convert to degrees old_angles = self.curr_ellipses._angles * 180 / np.pi old_offsets = self.curr_ellipses._offsets old_data = self.curr_ellipses.get_array() combined_majors = np.hstack([old_majors, major_axes]) combined_minors = np.hstack([old_minors, minor_axes]) combined_angles = np.hstack([old_angles, angles]) combined_data = np.hstack([old_data, data]) combined_offsets = np.vstack([old_offsets, XY]) new_ec = EllipseCollection(combined_majors, combined_minors, combined_angles, offsets=combined_offsets, transOffset=ax.transData) new_ec.set_array(combined_data) ec = new_ec else: ax = plt.subplot(1, 1, 1) ec = EllipseCollection(major_axes, minor_axes, angles, offsets=XY, transOffset=ax.transData) ec.set_array(data) self.curr_ellipses = ec ax.add_collection(ec) ax.autoscale_view() cbar = plt.colorbar(ec) if colorbar_lim != None: cbar.set_clim(colorbar_lim) if max_color_range == True: norm = mpl.colors.Normalize(vmin=colorbar_lim[0], vmax=colorbar_lim[1]) cbar = mpl.colorbar.ColorbarBase(cbar.ax, norm=norm) ec.color_bar = cbar cbar.set_label(cbar_label) return ec
def graph(locator, parameters, method, samples): """ :param locator: locator class :param parameters: list of output parameters to analyse :param method: 'morris' or 'sobol' methods :param samples: number of samples to calculate :return: .pdf file per output_parameter stored in locator.get_sensitivity_plots_file() """ if method is 'sobol': result = ['ST', 'ST_conf', 'S1'] else: result = ['mu_star', 'sigma', 'mu_star_conf'] for parameter in parameters: pdf = PdfPages(locator.get_sensitivity_plots_file(parameter)) # read the mustar of morris analysis data_mu = pd.read_excel(locator.get_sensitivity_output(method, samples), (parameter + result[0])) data_sigma = pd.read_excel(locator.get_sensitivity_output(method, samples), (parameter + result[1])) var_names = data_mu.columns.values # normalize data to maximum value data_mu[var_names] = data_mu[var_names].div(data_mu[var_names].max(axis=1), axis=0) data_sigma[var_names] = data_sigma[var_names].div(data_sigma[var_names].max(axis=1), axis=0) # get x_names and y_names # columns x_names = data_mu.columns.tolist() # rows y_names = ['config '+str(i) for i in list(data_mu.index+1)] # get counter (integer to create the graph) x = range(len(x_names)) y = range(len (y_names)) X, Y = np.meshgrid(x,y) XY = np.hstack((X.ravel()[:, np.newaxis], Y.ravel()[:, np.newaxis])) ww = data_mu.values.tolist() hh = data_sigma.values.tolist() aa = X*0 fig, ax = plt.subplots(dpi=150, figsize=(len(x_names)+2, len(y_names)+2)) # ec = EllipseCollection(ww, hh, aa, units='x', offsets=XY, transOffset=ax.transData, cmap='Blues') ec.set_array(np.array(ww).ravel()) ec.set_alpha(0.8) ax.add_collection(ec) ax.autoscale_view() plt.xticks(np.arange(-1, max(x) + 1, 1.0)) plt.yticks(np.arange(-1, max(y) + 1, 1.0)) ax.set_xlabel('variables [-]') ax.set_ylabel('configurations [-]') ax.set_xticklabels([""]+x_names) ax.set_yticklabels([""]+y_names) cbar = plt.colorbar(ec) cbar.set_label(result[0]) plt.title('GRAPH OF '+parameter+' PARAMETER', fontsize=14, fontstyle='italic', fontweight='bold') pdf.savefig() plt.close() plt.clf() pdf.close()
#fig2, ax2 =plt.subplots() #file2 = np.loadtxt('snapsL.out', delimiter=' ') #file2 = np.flipud(np.transpose(file2)) #plt.imshow(file2, cmap='hot') #plt.show() #plt.pause(-1) data = np.loadtxt('sim_0.55.1.out', delimiter=' ') fig, ax = plt.subplots() Nps = 2000 ax.set_xlim(0, 102) ax.set_ylim(0, 102) ellcoll = EllipseCollection(0.5,0.5,1, units='x', offsets = [], transOffset=ax.transData) ax.add_collection(ellcoll) #ax.add_artist(circ) def init(): ax.set_xlim(0, 102) ax.set_ylim(0, 102) ellcoll.set_offsets(data[0:Nps,1:3]) return ellcoll, def update(frame): ellcoll.set_offsets(data[frame*Nps:(frame*1+1)*Nps,1:3]) zrs = np.zeros(Nps) cols = np.transpose(data[frame*Nps:(frame*1+1)*Nps,3]/(2*pi)) comp = np.concatenate(([1-cols],[cols],[zrs])) #print(len(comp))
# assert None circles = cv2.HoughCircles(img_blur, cv.CV_HOUGH_GRADIENT, dp=2.0, minDist=20.0, param1=170, param2=44, minRadius=50, maxRadius=100) print circles x, y, r = circles[0].T fig, ax = plt.subplots(figsize=(8, 6)) plt.imshow(img, cmap="gray") from matplotlib.collections import EllipseCollection ec = EllipseCollection(widths=2 * r, heights=2 * r, angles=0, units="xy", facecolors="none", edgecolors="red", transOffset=ax.transData, offsets=np.c_[x, y]) ax.add_collection(ec) ax.axis("off") plt.show()
def create_png_images(time_end, input_data): # Vectors used in plots time_vect = [] healthy_vect = [] infected_wo_sympt_vect = [] infected_with_sympt_vect = [] recovered_vect = [] deaths_vect = [] R_factor_vect = [] # Loop on data files filelist = glob.glob(input_data.saving_folder + '/solutions/*.h5') nb_files = len(filelist) # Total number of files i_file = 0 # Current file number for filename in sorted(filelist): # Opening h5 file hf = h5py.File(filename, 'r') # Getting desired datasets time = hf.get('TIME')[()] nb_timestep = hf.get('NB_TIMESTEP')[()] X_vect = hf.get('X')[()] Y_vect = hf.get('Y')[()] PartState_vect = hf.get('STATE')[()] R_factor = hf.get('R_FACTOR')[()] # Closing h5 file hf.close() # Number of particles Nb_part = len(X_vect) # Getting statistics: healthy, infected, etc... nb_healthy = 0 nb_infected_wo_sympt = 0 nb_infected_with_sympt = 0 nb_recovered = 0 for i in range(Nb_part): a = PartState_vect[i] if a == 0: nb_healthy += 1 elif a == 1: nb_infected_wo_sympt += 1 elif a == 2: nb_infected_with_sympt += 1 elif a == 3: nb_recovered += 1 nb_deaths = input_data.population_size - Nb_part # Appending to vectors time_vect.append(time) healthy_vect.append(nb_healthy) infected_wo_sympt_vect.append(nb_infected_wo_sympt) infected_with_sympt_vect.append(nb_infected_with_sympt) recovered_vect.append(nb_recovered) deaths_vect.append(nb_deaths) R_factor_vect.append(R_factor) # Cumulative vectors state_2 = np.array(infected_with_sympt_vect) state_2_1 = state_2 + np.array(infected_wo_sympt_vect) state_2_1_4 = state_2_1 + np.array(deaths_vect) state_2_1_4_0 = state_2_1_4 + np.array(healthy_vect) state_2_1_4_0_3 = state_2_1_4_0 + np.array(recovered_vect) # RGB colors for each state color_s0 = (0, 0.44, 0.87, 1) color_s1 = (1.0, 0.46, 0, 1) color_s2 = (1.0, 0, 0.4, 1) color_s3 = (0.63, 0, 0.87, 1) color_s4 = (0.0, 0.0, 0.0, 1) # Creating matplotlib figures fig = plt.figure(constrained_layout=True) gs = fig.add_gridspec(3, 2) ax0 = fig.add_subplot(gs[0, 0]) ax1 = fig.add_subplot(gs[0, 1]) ax2 = fig.add_subplot(gs[1:, :]) # GLOBAL STATISTICS ax1.fill_between(time_vect, 0, state_2, color=color_s2, alpha=0.5) ax1.fill_between(time_vect, state_2, state_2_1, color=color_s1, alpha=0.5) ax1.fill_between(time_vect, state_2_1, state_2_1_4, color=color_s4, alpha=0.5) ax1.fill_between(time_vect, state_2_1_4, state_2_1_4_0, color=color_s0, alpha=0.5) ax1.fill_between(time_vect, state_2_1_4_0, state_2_1_4_0_3, color=color_s3, alpha=0.5) # Last image, we display the peak value of infected people if (i_file == nb_files - 1): # Array of total infected people index_max_infected, max_infected = np.argmax( infected_with_sympt_vect), np.max(infected_with_sympt_vect) ax1.plot([time_vect[index_max_infected]], [max_infected], marker="o", markersize=3, color='k') ax1.text(time_vect[index_max_infected], 1.2 * max_infected, f"Peak = {max_infected}", fontsize=6) ax1.set_xlim(0.0, time_end) ax1.set_ylim(0, input_data.population_size) ax1.set_title("Evolution of disease", fontsize=10) # Setting only min and max ticks ax1.set_xticks([0.0, time_end]) ax1.set_yticks([0.0, input_data.population_size]) # labels ax1.set_xlabel("Time [days]", fontsize=8) ax1.set_ylabel("Population [-]", fontsize=8) # REPRESENTATION OF POPULATION # collection related quantities size = 2.0 * input_data.radius # color function of states color = [] for i in range(Nb_part): if PartState_vect[i] == 0: color.append(color_s0) elif PartState_vect[i] == 1: color.append(color_s1) elif PartState_vect[i] == 2: color.append(color_s2) elif PartState_vect[i] == 3: color.append(color_s3) # data offsets = list(zip(X_vect, Y_vect)) # Plot with points respecting given radius ec = EllipseCollection(widths=size, heights=size, angles=0, units='xy', offsets=offsets, transOffset=ax2.transData) ec.set_facecolor(color) ec.set_edgecolor(color) ax2.add_collection(ec) # show R factor ax2.set_title(f"$R = {R_factor:.2f}$", fontsize=8) # Disabling axis ax2.axes.get_yaxis().set_visible(False) ax2.axes.get_xaxis().set_visible(False) ax2.set_aspect("equal") # PLOTS WITH LEGENDS # Disabling axis ax0.axes.get_yaxis().set_visible(False) ax0.axes.get_xaxis().set_visible(False) ax0.spines['right'].set_visible(False) ax0.spines['top'].set_visible(False) ax0.spines['bottom'].set_visible(False) ax0.spines['left'].set_visible(False) ax0.plot([0.05], [0.15], color=color_s0, ls="", marker="o", markersize=7) ax0.plot([0.05], [0.30], color=color_s1, ls="", marker="o", markersize=7) ax0.plot([0.05], [0.45], color=color_s2, ls="", marker="o", markersize=7) ax0.plot([0.05], [0.60], color=color_s3, ls="", marker="o", markersize=7) ax0.plot([0.05], [0.75], color=color_s4, ls="", marker="o", markersize=7) # Legend associating states with colors ax0.text(0.12, 0.115, "Healthy", fontsize=8) ax0.text(0.12, 0.265, "Infected without symptoms", fontsize=8) ax0.text(0.12, 0.415, "Infected with symptoms", fontsize=8) ax0.text(0.12, 0.565, "Recovered", fontsize=8) ax0.text(0.12, 0.715, "Dead", fontsize=8) ax0.set_xlim([0, 1]) ax0.set_ylim([0, 1]) ax0.set_aspect("equal") # Finalizing # fig.tight_layout() fig.savefig(input_data.saving_folder + "/images/image_step_{:05d}.png".format(i_file), dpi=250) plt.close(fig) # Next file i_file += 1 # Create a last plot with R factor against time plot_R_factor(input_data, time_vect, R_factor_vect)
world.positions[1, :] + origin[1]): ann = Annotation(label, xy=(x, y), xytext=(0, 0), textcoords='offset points', ha='center', va='center') ax.add_artist(ann) anns.append(ann) circles = ax.add_collection( EllipseCollection(widths=2 * robotRadius, heights=2 * robotRadius, angles=0, units='xy', edgecolors='black', linewidth=0.5, facecolors=world.colors, offsets=startPos, transOffset=ax.transData)) points = ax.add_collection( EllipseCollection(widths=0.5 * robotRadius, heights=0.5 * robotRadius, angles=0, units='xy', facecolors='black', offsets=startPosFace, transOffset=ax.transData))
def display_matrices(ax, grid, texture, scale=None, col=None): """Display on a matplotlib axis an ellipse representing a symmetric matrix at each grid element. Each axis of the ellipse corresponds to an eigenvalue and is oriented along its eigenvector. An axis corresponding to a positive eigenvalue is drawn. A 'coffee bean' has a negative eigenvalue smaller in absolute value than its positive eigenvalue. A 'capsule' has a negative eigenvalue larger in absolute value than its positive eigenvalue. A circle is when the two eigenvalues are equal in absolute value.""" XY = grid.mesh() mask = grid.mask() #convert the texture back to an array of matrices mat = tri2square(texture) #compute egenvalues and eigenvectors of texture for each cell of the grid evalues, evectors = np.linalg.eigh(mat) #width and height are the larger and smaller eigenvalues respectively ww = evalues[..., 1][mask] hh = evalues[..., 0][mask] #angle is given by the angle of the larger eigenvector aa = np.rad2deg(np.arctan2(evectors[..., 1, 1], evectors[..., 0, 1]))[mask] #sum of the eigenvalues (trace of the matrix) trace = ww + hh #np.where(np.abs(ww)>np.abs(hh), ww, hh)#ww*hh #color #if col is None: # if trace.ptp()>0: # col = plt.cm.viridis((trace.ravel() - trace.min())/trace.ptp()) # else: # col = plt.cm.viridis(np.ones_like(trace)) if scale is None: #scale = 1 ellipse_areas = np.pi * np.abs(np.prod(evalues, axis=-1)) rarea = ellipse_areas / grid.areas() scale = np.nanpercentile(np.sqrt(rarea[mask]), 90) if scale == 0: scale = np.nanmax(np.sqrt(rarea[mask])) if scale == 0: raise ValueError("All matrices are null") scale = 1 / scale #show ellipses ec = EllipseCollection( ww * scale, hh * scale, aa, units='xy', offsets=XY, transOffset=ax.transData, edgecolors=col, facecolors='none', ) #major and minor axes (only for positive eigenvalues) xyps = scale * np.transpose( evectors * np.maximum(0, evalues)[..., None, :], (0, 1, 3, 2))[mask].reshape(2 * len(ww), 2) * 0.5 ma = LineCollection([[-xyp, xyp] for xyp in xyps], offsets=np.repeat(XY, 2, axis=0), color=(0.5, 0.5, 0.5)) if col is None: if trace.ptp() > 0: ec.set_array(trace) ma.set_array(trace[mask.ravel()]) else: ec.set_edgecolors(col) ma.set_edgecolors(col) ax.add_collection(ec) ax.add_collection(ma) return ec
# Ellipse collection # ---------------------------------------------------------------------------- n = 10 offsets = np.ones((n, 2)) offsets[:, 0], offsets[:, 1] = np.linspace(1, 10, n), y X, Y = offsets[:, 0], offsets[:, 1] widths, heights = 15 * np.ones(n), 10 * np.ones(n) angles = np.linspace(0, 45, n) linewidths = np.linspace(1, 2, n) facecolors = ["%.1f" % c for c in np.linspace(0.25, 0.75, n)] collection = EllipseCollection( widths, heights, angles, # linewidths = linewidths, facecolors=facecolors, edgecolor="black", offsets=offsets, transOffset=ax.transData, ) ax.add_collection(collection) ax.text( X[0] - 0.25, y + 0.35, "Ellipse collection", size="small", ha="left", va="baseline" ) ax.text( X[-1] + 0.25, y + 0.35, "EllipseCollection", color="blue", size="small", ha="right",
color=fontcolor) ax.text(0, -2.2, bgcolor.upper()[1:], transform=ax.transData, ha='center', va='center', color=fontcolor) circles = EllipseCollection( size, size, np.zeros_like(size), offsets=np.array(XY), units='x', transOffset=ax.transData, facecolors=node_colors, linewidths=0.5, edgecolors='k', ) ax.add_collection(circles) ax.plot([-dx - 2 * r, -dx / 3], 2 * [-(i + 1) * dy - 3], color=hex_link_colors[palette], lw=3) ax.text(dx / 3, -(i + 1) * dy - 3, hex_link_colors[palette][1:].upper(),