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, "#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 update(kk): ellipseNode = NodeList[kk] ellNodeShape = ellipseNode.means.shape xPlotValues = [] yPlotValues = [] xValues = [] yValues = [] widthValues = [] heightValues = [] angleValues = [] # 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, "#636D97", linewidth=2.0) # 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 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) return lx, ec
def main(): # Close any existing figure plt.close('all') ########################################################################### ######################## Grow DR-RRTStar Tree ############################# ########################################################################### # Create the DR_RRTStar Class Object by initizalizng the required data dr_rrtstar = DR_RRTStar(start=[0, 0], randArea=[-1.2, 1.2, -0.1, 2.1], goalArea=[-1.2, -1.0, 0.8, 1.1], maxIter=1300) # Perform DR_RRTStar Tree Expansion pathNodesList = dr_rrtstar.ExpandTree() ########################################################################### ######################## Draw final path ################################## ########################################################################### # If a valid path is found from root to the goal, display success if pathNodesList is not None: print("Sampled path found !!") xValues = [] yValues = [] widthValues = [] heightValues = [] angleValues = [] # Iterate through al pathNodes and draw the trajectory and final ellipses for pathNode in pathNodesList: xPlotValues = [] yPlotValues = [] pathNodeShape = pathNode.means.shape # Prepare the trajectory x and y vectors and plot them for k in range(pathNodeShape[0]): xPlotValues.append(pathNode.means[k, 0, 0]) yPlotValues.append(pathNode.means[k, 1, 0]) # Plotting the risk bounded trajectories plt.plot(xPlotValues, yPlotValues, color='#F5793A', linewidth=2.0) # Plot only the last ellipse in the trajectory elcovar = np.asarray(pathNode.covar[-1, :, :]) elE, elV = LA.eig(elcovar[0:2, 0:2]) alfa = math.atan2(pathNode.means[-1, 1, 0], pathNode.means[-1, 0, 0]) angleValues.append(alfa * 360) xValues.append(pathNode.means[-1, 0, 0]) yValues.append(pathNode.means[-1, 1, 0]) widthValues.append(math.sqrt(elE[0])) heightValues.append(math.sqrt(elE[1])) # Plot the Safe Ellipses XY = np.column_stack((xValues, yValues)) ec = EllipseCollection(widthValues, heightValues, angleValues, units='x', offsets=XY, facecolors="faded green", transOffset=plt.axes().transData) ec.set_alpha(0.6) plt.axes().add_collection(ec) plt.grid(True) else: print("Cannot find a sampled path !!")
class HoughDemo(ImageProcessDemo): TITLE = u"Hough Demo" DEFAULT_IMAGE = "stuff.jpg" SETTINGS = ["th2", "show_canny", "rho", "theta", "hough_th", "minlen", "maxgap", "dp", "mindist", "param2", "min_radius", "max_radius", "blur_sigma", "linewidth", "alpha", "check_line", "check_circle"] check_line = Bool(True) check_circle = Bool(True) #Gaussian blur parameters blur_sigma = Range(0.1, 5.0, 2.0) show_blur = Bool(False) # Canny parameters th2 = Range(0.0, 255.0, 200.0) show_canny = Bool(False) # HoughLine parameters rho = Range(1.0, 10.0, 1.0) theta = Range(0.1, 5.0, 1.0) hough_th = Range(1, 100, 40) minlen = Range(0, 100, 10) maxgap = Range(0, 20, 10) # HoughtCircle parameters dp = Range(1.0, 5.0, 1.9) mindist = Range(1.0, 100.0, 50.0) param2 = Range(5, 100, 50) min_radius = Range(5, 100, 20) max_radius = Range(10, 100, 70) # draw parameters linewidth = Range(1.0, 3.0, 1.0) alpha = Range(0.0, 1.0, 0.6) def control_panel(self): return VGroup( Group( Item("blur_sigma", label=u"标准方差"), Item("show_blur", label=u"显示结果"), label=u"高斯模糊参数" ), Group( Item("th2", label=u"阈值2"), Item("show_canny", label=u"显示结果"), label=u"边缘检测参数" ), Group( Item("rho", label=u"偏移分辨率(像素)"), Item("theta", label=u"角度分辨率(角度)"), Item("hough_th", label=u"阈值"), Item("minlen", label=u"最小长度"), Item("maxgap", label=u"最大空隙"), label=u"直线检测" ), Group( Item("dp", label=u"分辨率(像素)"), Item("mindist", label=u"圆心最小距离(像素)"), Item("param2", label=u"圆心检查阈值"), Item("min_radius", label=u"最小半径"), Item("max_radius", label=u"最大半径"), label=u"圆检测" ), Group( Item("linewidth", label=u"线宽"), Item("alpha", label=u"alpha"), HGroup( Item("check_line", label=u"直线"), Item("check_circle", label=u"圆"), ), label=u"绘图参数" ) ) def __init__(self, **kwargs): super(HoughDemo, self).__init__(**kwargs) self.connect_dirty("th2, show_canny, show_blur, rho, theta, hough_th," "min_radius, max_radius, blur_sigma," "minlen, maxgap, dp, mindist, param2, " "linewidth, alpha, check_line, check_circle") self.lines = LineCollection([], linewidths=2, alpha=0.6) self.axe.add_collection(self.lines) self.circles = EllipseCollection( [], [], [], units="xy", facecolors="none", edgecolors="red", linewidths=2, alpha=0.6, transOffset=self.axe.transData) self.axe.add_collection(self.circles) def _img_changed(self): self.img_gray = cv2.cvtColor(self.img, cv2.COLOR_BGR2GRAY) def draw(self): img_smooth = cv2.GaussianBlur(self.img_gray, (0, 0), self.blur_sigma, self.blur_sigma) img_edge = cv2.Canny(img_smooth, self.th2 * 0.5, self.th2) if self.show_blur and self.show_canny: show_img = cv2.cvtColor(np.maximum(img_smooth, img_edge), cv2.COLOR_BAYER_BG2BGR) elif self.show_blur: show_img = cv2.cvtColor(img_smooth, cv2.COLOR_BAYER_BG2BGR) elif self.show_canny: show_img = cv2.cvtColor(img_edge, cv2.COLOR_GRAY2BGR) else: show_img = self.img if self.check_line: theta = self.theta / 180.0 * np.pi lines = cv2.HoughLinesP(img_edge, self.rho, theta, self.hough_th, minLineLength=self.minlen, maxLineGap=self.maxgap) if lines is not None: lines = lines[0] lines.shape = -1, 2, 2 self.lines.set_segments(lines) self.lines.set_visible(True) else: self.lines.set_visible(False) else: self.lines.set_visible(False) if self.check_circle: circles = cv2.HoughCircles(img_smooth, 3, self.dp, self.mindist, param1=self.th2, param2=self.param2, minRadius=self.min_radius, maxRadius=self.max_radius) if circles is not None: circles = circles[0] self.circles._heights = self.circles._widths = circles[:, 2] self.circles.set_offsets(circles[:, :2]) self.circles._angles = np.zeros(len(circles)) self.circles._transOffset = self.axe.transData self.circles.set_visible(True) else: self.circles.set_visible(False) else: self.circles.set_visible(False) self.lines.set_linewidths(self.linewidth) self.circles.set_linewidths(self.linewidth) self.lines.set_alpha(self.alpha) self.circles.set_alpha(self.alpha) self.draw_image(show_img)
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()
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)
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', '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()