def create_plot(snapshot, folder, output_folder='.', output_plot=True, show_plot=False): """ Creates a plot as per instructions inside the function. As of 10.13.20 this was a plot of ECM-organoid simulations: a base layer of a contour plot of either the anisotropy or the oxygen, the cells in the smulation as a scatter plot, and finally the ECM orientation overlaid with a quiver plot. Parameters ---------- snapshot : Base name of PhysiCell output files - eg 'output00000275' --> 'output' + '%08d' folder : str Path to input data output_folder : str Path for image output output_plot : bool True = image file will be made. Image output is required for movie production. show_plot : bool True = plot is displayed. Expected to be false for large batches. Returns ------- Nothing : Produces a png image from the input PhysiCell data. """ ###### Flags ###### produce_for_panel = True #################################################################################################################### #################################### Load data ######################## #################################################################################################################### # load cell and microenvironment data mcds = pyMCDS(snapshot + '.xml', folder) # loads and reads ECM data mcds.load_ecm(snapshot + '_ECM.mat', folder) # Get cell positions and attributes, microenvironment, and ECM data for plotting. # Cells cell_df = mcds.get_cell_df() #### Diffusion microenvironment xx, yy = mcds.get_2D_mesh() # Mesh plane_oxy = mcds.get_concentrations('oxygen', 0.0) # Oxyen (used for contour plot) #### ECM microenvironment xx_ecm, yy_ecm = mcds.get_2D_ECM_mesh() # Mesh plane_anisotropy = mcds.get_ECM_field( 'anisotropy', 0.0) # Anistropy (used for scaling and contour plot) # plane_anisotropy = micro # Used for contour plot #################################################################################################################### #################################### Preprocessing ######################## #################################################################################################################### #### Helper varialbes and functions ###### # Number of contours (could include as a parameter) num_levels = 10 # 25 works well for ECM, 38 works well for oxygen # Make levels for contours levels_o2 = np.linspace(1e-14, 38, num_levels) # levels_ecm = np.linspace(1e-14, 1.0, num_levels) levels_ecm = np.linspace( 0.90, 0.93, num_levels ) # for the march environment - need to especially highlight small changes in anistoropy. # Old function and scripting to scale and threshold anisotorpy values for later use in scaling lenght of ECM fibers # for visualization purposes. # micro = plane_anisotropy # micro_scaled = micro # # def curve(x): # #return (V_max * x) / (K_M + x) # return 0.5 if x > 0.5 else x # for i in range(len(micro)): # for j in range(len(micro[i])): # #micro_scaled[i][j] = 10 * math.log10(micro[i][j] + 1) / math.log10(2) # micro_scaled[i][j] = curve(micro[i][j]) ##### Process data for plotting - weight fibers by anisotropy, mask out 0 anisotropy ECM units, get cell radii and types # Anisotropy strictly runs between 0 and 1. Element by element mulitplication produces weighted lengths between 0 - 1 # for vizualization scaled_ECM_x = np.multiply( mcds.data['ecm']['ECM_fields']['x_fiber_orientation'][:, :, 0], plane_anisotropy) scaled_ECM_y = np.multiply( mcds.data['ecm']['ECM_fields']['y_fiber_orientation'][:, :, 0], plane_anisotropy) # if we want the arrows the same length instead ECM_x = mcds.data['ecm']['ECM_fields']['x_fiber_orientation'][:, :, 0] ECM_y = mcds.data['ecm']['ECM_fields']['y_fiber_orientation'][:, :, 0] # mask out zero vectors mask = plane_anisotropy > 0.0001 # get unique cell types and radii cell_df['radius'] = (cell_df['total_volume'].values * 3 / (4 * np.pi))**(1 / 3) types = cell_df['cell_type'].unique() colors = ['yellow', 'blue'] #################################################################################################################### #################################### Plotting ######################## #################################################################################################################### # start plot and make correct size fig = plt.figure(figsize=(8, 8)) ax = fig.gca() ax.set_aspect("equal") plt.ylim(-500, 500) plt.xlim(-500, 500) # add contour layer # cs = plt.contourf(xx, yy, plane_oxy, cmap="Greens_r", levels=levels_o2) cs = plt.contourf(xx_ecm, yy_ecm, plane_anisotropy, cmap="YlGnBu", levels=levels_ecm) # Add cells layer for i, ct in enumerate(types): plot_df = cell_df[cell_df['cell_type'] == ct] for j in plot_df.index: circ = Circle( (plot_df.loc[j, 'position_x'], plot_df.loc[j, 'position_y']), radius=plot_df.loc[j, 'radius'], color='blue', alpha=0.7, edgecolor='black') # for a blue circle with a black edge # circ = Circle((plot_df.loc[j, 'position_x'], plot_df.loc[j, 'position_y']), # radius=plot_df.loc[j, 'radius'], alpha=0.7, edgecolor='black') ax.add_artist(circ) # add quiver layer with scaled arrows ### # q = ax.quiver(xx_ecm[mask], yy_ecm[mask], scaled_ECM_x[mask], scaled_ECM_y[mask], pivot='middle', angles='xy', scale_units='inches', scale=2.0, headwidth=0, # width=0.0015) ## What is the deal with the line segment lengths shifting as the plots progress when I don't ue teh scaling?? # add ECM orientation vectors unscaled by anistorpy ### plt.quiver( xx, yy, ECM_x, ECM_y, pivot='middle', angles='xy', scale_units='inches', scale=4.75, headwidth=0, alpha=0.3 ) ### was at 3.0 before changing the mat size from 12 to 8 to match my otherr images AND get the font for the ticks large # ax.axis('scaled') #used to be 'equal' https://stackoverflow.com/questions/45057647/difference-between-axisequal-and-axisscaled-in-matplotlib # This changes teh axis from -750,750 to ~-710,730. It looks better with scaled compared to axix, but either way it changes the plot limits # Labels and title (will need removed for journal - they will be added manually) plt.ylim(-500, 500) plt.xlim(-500, 500) # ax.axis('scaled') if produce_for_panel == False: ax.set_xlabel('microns') ax.set_ylabel('microns') fig.colorbar(cs, ax=ax) plt.title(snapshot) # Carefully place the command to make the plot square AFTER the color bar has been added. ax.axis('scaled') else: plt.xticks(fontsize=20) plt.yticks(fontsize=20) ax.set_xlabel('microns', fontsize=20) ax.set_ylabel('microns', fontsize=20) fig.tight_layout() # Plot output if output_plot is True: plt.savefig(output_folder + snapshot + '.png', dpi=256) if show_plot is True: plt.show()
fig_mat[fig_mat == 0] = 1e-10 fig_mat = np.log10(fig_mat) fig_mat = np.transpose(fig_mat) ax.imshow(fig_mat) fof_x = fof_pos[:, 0] fof_y = fof_pos[:, 1] fof_r = fof_radius print(fof_x.max(), fof_x.max()) print(fof_y.max(), fof_y.min()) print(fof_r.max(), fof_r.min()) fof_x = (fof_x - xmin) / (xmax - xmin) * fig_size fof_y = (fof_y - ymin) / (ymax - ymin) * fig_size fof_r = (fof_r - xmin) / (xmax - xmin) * fig_size print(fof_x.max(), fof_x.max()) print(fof_y.max(), fof_y.min()) print(fof_r.max(), fof_r.min()) ax.plot(fof_x, fof_y, 'w.', markersize=1) for i in range(len(fof_pos)): cir = Circle(xy=(fof_x[i], fof_y[i]), radius=fof_r[i], alpha=0.5) cir.set_edgecolor([1, 1, 1, 1]) ax.add_patch(cir) ''' ax = fig.add_subplot( 111, projection='3d' ) ax.scatter( particle_pos[:,0], particle_pos[:,1], particle_pos[:,2], s=0.01 ) ax.scatter( fof_pos[:,0], fof_pos[:,1], fof_pos[:,2], s=250 ) ''' plt.axis('scaled') plt.axis('equal') plt.savefig('test.png')
def extract_minutiae_cylinder(img, minutiae, ROI, num_ori=12): # for the latent or the low quality rolled print sigma = 5**2 if ROI is not None: h, w = ROI.shape for i in range(h): for j in range(w): if ROI[i, j] == 0: img[i, j] = 255 h, w = ROI.shape col_sum = np.sum(ROI, axis=0) ind = [x for x in range(len(col_sum)) if col_sum[x] > 0] min_x = np.max([np.min(ind) - 32, 0]) max_x = np.min([np.max(ind) + 32, w]) row_sum = np.sum(ROI, axis=1) ind = [x for x in range(len(row_sum)) if row_sum[x] > 0] min_y = np.max([np.min(ind) - 32, 0]) max_y = np.min([np.max(ind) + 32, h]) ROI = ROI[min_y:max_y, min_x:max_x] img = img[min_y:max_y, min_x:max_x] minutiae[:, 0] = minutiae[:, 0] - min_x minutiae[:, 1] = minutiae[:, 1] - min_y h, w = ROI.shape minutiae_cylinder = np.zeros((h, w, num_ori), dtype=float) cylinder_ori = np.asarray(range(num_ori)) * math.pi * 2 / num_ori Y, X = np.mgrid[0:h, 0:w] minu_num = minutiae.shape[0] for i in range(0, minu_num): xx = minutiae[i, 0] yy = minutiae[i, 1] if yy < 0 or xx < 0: print xx, yy weight = np.exp(-((X - xx) * (X - xx) + (Y - yy) * (Y - yy)) / sigma) ori = minutiae[i, 2] if ori < 0: ori += np.pi * 2 if ori > np.pi * 2: ori -= np.pi * 2 for j in range(num_ori): ori_diff = np.fabs(ori - cylinder_ori[j]) if ori_diff > np.pi * 2: ori_diff = ori_diff - np.pi * 2 ori_diff = np.min([ori_diff, np.pi * 2 - ori_diff]) #print ori_diff minutiae_cylinder[:, :, j] += weight * np.exp(-ori_diff / np.pi * 6) #for j in range(num_ori): # ax.imshow(minutiae_cylinder[:,:,j], cmap='gray') #print xx,yy #print minutiae_cylinder[int(yy),int(xx),:] show = 0 if show: fig, ax = plt.subplots(1) ax.set_aspect('equal') ax.imshow(ROI, cmap='gray') for i in range(0, minu_num): xx = minutiae[i, 0] yy = minutiae[i, 1] circ = Circle((xx, yy), R, color='r', fill=False) ax.add_patch(circ) ori = -minutiae[i, 2] dx = math.cos(ori) * arrow_len dy = math.sin(ori) * arrow_len ax.arrow(xx, yy, dx, dy, head_width=0.05, head_length=0.1, fc='r', ec='r') plt.show() return img, ROI, minutiae_cylinder
def drawMultiAgentPath(self, status_MultiAgent): for id_agent in range(self.config.num_agents): name_agent = "agent{}".format(id_agent) path = status_MultiAgent[name_agent]["path"] list_pathIndexX = [] list_pathIndexY = [] list_action = status_MultiAgent[name_agent]["action"] len_path = len( path) # self.status_MultiAgent[name_agent]["len_action"] start = status_MultiAgent[name_agent]["start"] goal = status_MultiAgent[name_agent]["goal"] start_np = start.cpu().detach().numpy() goal_np = goal.cpu().detach().numpy() agent_color = self.list_agent_color(id_agent) # step_color = self.list_step_color[id_agent] if len_path != 0: color_gradient = 1 / len_path else: color_gradient = 0.1 if color_gradient < 0.1: step_color_gradient = 1 / len_path else: step_color_gradient = 0.1 # start symbol self.patches.append( Circle((start_np[0][0], start_np[0][1]), 0.3, facecolor=(1, 1, 1), edgecolor=agent_color, linewidth=3, alpha=1)) for step in range(len_path): pathIndexX = path[step][0][0].cpu().detach().numpy() pathIndexY = path[step][0][1].cpu().detach().numpy() list_pathIndexX.append(pathIndexX) list_pathIndexY.append(pathIndexY) step_color = tuple( [x * step * step_color_gradient for x in agent_color]) # self.patches.append(Circle((pathIndexX , pathIndexY), 0.3, facecolor=agent_color, edgecolor=agent_color)) if step < len_path - 1: targetSymbol = self.delta_name_modified[list_action[step]] plt.plot(pathIndexX, pathIndexY, targetSymbol, markerfacecolor=agent_color, markeredgecolor=agent_color, markersize=16) self.ax.annotate(step, xy=(pathIndexX, pathIndexY), color=step_color) plt.plot(list_pathIndexX, list_pathIndexY, linewidth=3, color=agent_color) # goal symbol plt.plot(goal_np[0][0], goal_np[0][1], '*', markerfacecolor='red', markeredgecolor='red', markersize=20)
def plot_particles(xmin, xmax, ymin, ymax, zmin, zmax, particle_list, max_particle_distance, draw_circumscribing_sphere): """Add circles, ellipses and rectangles to plot to display spheres, spheroids and cylinders. Args: xmin (float): Minimal x-value of plot xmax (float): Maximal x-value of plot ymin (float): Minimal y-value of plot ymax (float): Maximal y-value of plot zmin (float): Minimal z-value of plot zmax (float): Maximal z-value of plot particle_list (list): List of smuthi.particles.Particle objects max_particle_distance (float): Plot only particles that ar not further away from image plane draw_circumscribing_sphere (bool): If true (default), draw a circle indicating the circumscribing sphere of particles. """ ax = plt.gca() if xmin == xmax: plane_coord = 0 draw_coord = [1, 2] elif ymin == ymax: plane_coord = 1 draw_coord = [0, 2] elif zmin == zmax: plane_coord = 2 draw_coord = [0, 1] else: raise ValueError('Field points must define a plane') for particle in particle_list: pos = particle.position if abs((xmin, ymin, zmin)[plane_coord] - pos[plane_coord]) > max_particle_distance: continue if type(particle).__name__ == 'Sphere': ax.add_patch( Circle((pos[draw_coord[0]], pos[draw_coord[1]]), particle.radius, facecolor='w', edgecolor='k')) else: if not particle.euler_angles == [0, 0, 0]: warnings.warn( "Drawing rotated particles currently not supported - drawing black disc with size" + " of circumscribing sphere instead") ax.add_patch( Circle((pos[draw_coord[0]], pos[draw_coord[1]]), particle.circumscribing_sphere_radius(), facecolor='k', edgecolor='k')) ax.text(pos[draw_coord[0]], pos[draw_coord[1]], 'rotated ' + type(particle).__name__, verticalalignment='center', horizontalalignment='center', color='blue', fontsize=5) else: if draw_circumscribing_sphere: ax.add_patch( Circle((pos[draw_coord[0]], pos[draw_coord[1]]), particle.circumscribing_sphere_radius(), linestyle='dashed', facecolor='none', edgecolor='k')) if type(particle).__name__ == 'Spheroid': width = 2 * particle.semi_axis_a if plane_coord == 2: height = 2 * particle.semi_axis_a else: height = 2 * particle.semi_axis_c ax.add_patch( Ellipse(xy=(pos[draw_coord[0]], pos[draw_coord[1]]), width=width, height=height, facecolor='w', edgecolor='k')) elif type(particle).__name__ == 'FiniteCylinder': if plane_coord == 2: ax.add_patch( Circle((pos[draw_coord[0]], pos[draw_coord[1]]), particle.cylinder_radius, facecolor='w', edgecolor='k')) else: ax.add_patch( Rectangle( (pos[draw_coord[0]] - particle.cylinder_radius, pos[draw_coord[1]] - particle.cylinder_height / 2), 2 * particle.cylinder_radius, particle.cylinder_height, facecolor='w', edgecolor='k'))
def circles(x, y, s, c='b', vmin=None, vmax=None, **kwargs): """ See https://gist.github.com/syrte/592a062c562cd2a98a83 Make a scatter plot of circles. Similar to plt.scatter, but the size of circles are in data scale. Parameters ---------- x, y : scalar or array_like, shape (n, ) Input data s : scalar or array_like, shape (n, ) Radius of circles. c : color or sequence of color, optional, default : 'b' `c` can be a single color format string, or a sequence of color specifications of length `N`, or a sequence of `N` numbers to be mapped to colors using the `cmap` and `norm` specified via kwargs. Note that `c` should not be a single numeric RGB or RGBA sequence because that is indistinguishable from an array of values to be colormapped. (If you insist, use `color` instead.) `c` can be a 2-D array in which the rows are RGB or RGBA, however. vmin, vmax : scalar, optional, default: None `vmin` and `vmax` are used in conjunction with `norm` to normalize luminance data. If either are `None`, the min and max of the color array is used. kwargs : `~matplotlib.collections.Collection` properties Eg. alpha, edgecolor(ec), facecolor(fc), linewidth(lw), linestyle(ls), norm, cmap, transform, etc. Returns ------- paths : `~matplotlib.collections.PathCollection` Examples -------- a = np.arange(11) circles(a, a, s=a*0.2, c=a, alpha=0.5, ec='none') plt.colorbar() License -------- This code is under [The BSD 3-Clause License] (http://opensource.org/licenses/BSD-3-Clause) """ if np.isscalar(c): kwargs.setdefault('color', c) c = None if 'fc' in kwargs: kwargs.setdefault('facecolor', kwargs.pop('fc')) if 'ec' in kwargs: kwargs.setdefault('edgecolor', kwargs.pop('ec')) if 'ls' in kwargs: kwargs.setdefault('linestyle', kwargs.pop('ls')) if 'lw' in kwargs: kwargs.setdefault('linewidth', kwargs.pop('lw')) # You can set `facecolor` with an array for each patch, # while you can only set `facecolors` with a value for all. zipped = np.broadcast(x, y, s) patches = [Circle((x_, y_), s_) for x_, y_, s_ in zipped] collection = PatchCollection(patches, **kwargs) if c is not None: c = np.broadcast_to(c, zipped.shape).ravel() collection.set_array(c) collection.set_clim(vmin, vmax) ax = plt.gca() ax.add_collection(collection) ax.autoscale_view() # plt.draw_if_interactive() if c is not None: plt.sci(collection)
from matplotlib.patches import Circle import matplotlib.pyplot as plt from mpl_toolkits.axes_grid.anchored_artists import AnchoredDrawingArea fig = plt.figure(1, figsize=(3, 3)) ax = plt.subplot(111) ada = AnchoredDrawingArea(40, 20, 0, 0, loc=1, pad=0., frameon=False) p1 = Circle((10, 10), 10) ada.drawing_area.add_artist(p1) p2 = Circle((30, 10), 5, fc="r") ada.drawing_area.add_artist(p2) ax.add_artist(ada) plt.show()
def draw(self, ax): """Add this Particle's Circle patch to the Matplotlib Axes ax.""" circle = Circle(xy=self.r, radius=self.radius, color=self.color) ax.add_patch(circle) return circle
def nucleosom_match_local_plot( histogram_gaussian_1, histogram_gaussian_2, nucl_state_1, nucl_state_2, nucl_state_1_reverse, nucl_state_2_reverse, peaks_1_position_length, peaks_2_position_length, name_data_1, name_data_2, data_min, data_max, reverse_var, sub_directory, save_txt_var): #We change the directory os.chdir(sub_directory) if save_txt_var == 1: np.savetxt( 'Nucleosom_comparaison_states_1_data_min{0}_data_max{1}.txt'. format(data_min, data_max), nucl_state_1) np.savetxt( 'Nucleosom_comparaison_states_2_data_min{0}_data_max{1}.txt'. format(data_min, data_max), nucl_state_2) import matplotlib matplotlib.use('Agg') import matplotlib.pyplot as plt fig1 = plt.figure() ax1 = fig1.add_subplot(111) #We normalize the histograms before plotting print("Normalizing the histograms before plotting...") histogram_gaussian_1_sum = np.sum(histogram_gaussian_1) histogram_gaussian_2_sum = np.sum(histogram_gaussian_2) histogram_gaussian_1 = histogram_gaussian_1 / histogram_gaussian_1_sum histogram_gaussian_2 = histogram_gaussian_2 / histogram_gaussian_2_sum print("Done!\n") #We adjuste the window to be symmetric on y print("Adjusting the size of the window...") histogram_gaussian_1_max = np.amax(histogram_gaussian_1) histogram_gaussian_2_max = np.amax(histogram_gaussian_2) histogram_gaussian_max = max(histogram_gaussian_1_max, histogram_gaussian_2_max) print("Done!\n") #print histogram_gaussian_1.shape #print data_max - data_min ax1.plot(np.linspace(data_min, data_max, data_max - data_min), histogram_gaussian_1) ax1.plot(np.linspace(data_min, data_max, data_max - data_min), -histogram_gaussian_2) ax1.set_title('Nucleosom Position (Histogram Up: ' + name_data_1 + ' ; Histogram Down: ' + name_data_2 + ' )', fontsize=10) ax1.set_xlabel('Position (bp)', fontsize=8) ax1.set_ylabel('Frequency of Histograms Normalized', fontsize=8) ax1.tick_params(axis='x', labelsize=8) ax1.tick_params(axis='y', labelsize=8) ax1.grid() ax1.axis('tight') ax1.set_xlim([data_min, data_max]) ax1.set_ylim([ -histogram_gaussian_max - 0.1 * histogram_gaussian_max, histogram_gaussian_max + 0.1 * histogram_gaussian_max ]) trans_1 = ax1.transAxes data_length = data_max - data_min high = 0.01 diameter = 0.002 shift = 0.05 for i in xrange(peaks_1_position_length): #el1 = Circle( (nucl_state_1[i][3]/data_length,0.5 + 2*high),diameter, color='w',ec = 'k',transform=trans_1) #ax1.add_artist(el1) if nucl_state_1[i][0] != 0: el1 = Circle((nucl_state_1[i][3] / data_length, 0.5 + high), diameter, color='r', transform=trans_1) ax1.add_artist(el1) el2 = Circle((nucl_state_1[i][3] / data_length, 0.5 - high), diameter, color='b', transform=trans_1) ax1.add_artist(el2) if nucl_state_1[i][1] != 0: el2 = Circle((nucl_state_1[i][3] / data_length, 0.5 + high), diameter, color='c', transform=trans_1) ax1.add_artist(el2) if nucl_state_1[i][2] != 0: el2 = Circle((nucl_state_1[i][3] / data_length, 0.5 + high), diameter, color='k', transform=trans_1) ax1.add_artist(el2) if reverse_var == 1: #el1 = Circle( (nucl_state_1_reverse[i][3]/data_length,0.5 + 2*high),diameter, color='w',ec = 'k',transform=trans_1) #ax1.add_artist(el1) if nucl_state_1_reverse[i][0] != 0: el1 = Circle( (nucl_state_1_reverse[i][3] / data_length, 0.5 + 2 * high), diameter, color='r', transform=trans_1) ax1.add_artist(el1) el2 = Circle( (nucl_state_1_reverse[i][3] / data_length, 0.5 - 2 * high), diameter, color='b', transform=trans_1) ax1.add_artist(el2) if nucl_state_1_reverse[i][1] != 0: el2 = Circle( (nucl_state_1_reverse[i][3] / data_length, 0.5 + 2 * high), diameter, color='c', transform=trans_1) ax1.add_artist(el2) if nucl_state_1_reverse[i][2] != 0: el2 = Circle( (nucl_state_1_reverse[i][3] / data_length, 0.5 + 2 * high), diameter, color='k', transform=trans_1) ax1.add_artist(el2) for i in xrange(peaks_2_position_length): if nucl_state_2[i][0] != 0: el2 = Circle((nucl_state_2[i][3] / data_length, 0.5 - high), diameter, color='r', transform=trans_1) ax1.add_artist(el2) el1 = Circle((nucl_state_2[i][3] / data_length, 0.5 + high), diameter, color='b', transform=trans_1) ax1.add_artist(el1) if nucl_state_2[i][1] != 0: el2 = Circle((nucl_state_2[i][3] / data_length, 0.5 - high), diameter, color='c', transform=trans_1) ax1.add_artist(el2) if nucl_state_2[i][2] != 0: el2 = Circle((nucl_state_2[i][3] / data_length, 0.5 - high), diameter, color='k', transform=trans_1) ax1.add_artist(el2) if reverse_var == 1: if nucl_state_2_reverse[i][0] != 0: el1 = Circle( (nucl_state_2_reverse[i][3] / data_length, 0.5 + 2 * high), diameter, color='b', transform=trans_1) ax1.add_artist(el1) el2 = Circle( (nucl_state_2_reverse[i][3] / data_length, 0.5 - 2 * high), diameter, color='r', transform=trans_1) ax1.add_artist(el2) if nucl_state_2_reverse[i][1] != 0: el2 = Circle( (nucl_state_2_reverse[i][3] / data_length, 0.5 - 2 * high), diameter, color='c', transform=trans_1) ax1.add_artist(el2) if nucl_state_2_reverse[i][2] != 0: el2 = Circle( (nucl_state_2_reverse[i][3] / data_length, 0.5 - 2 * high), diameter, color='k', transform=trans_1) ax1.add_artist(el2) fig1.set_tight_layout(fig1) fig1.savefig('Nucleosom Position' + name_data_2 + '_data_min_{0}_data_max_{1}.pdf'.format(data_min, data_max)) plt.clf() plt.close() return 0
def __init__(self, config): self.config = config with open(config.map) as map_file: self.data_map = yaml.load(map_file) with open(config.schedule) as states_file: self.schedule = yaml.load(states_file) self.num_agents = len(self.data_map["agents"]) self.K = self.config.nGraphFilterTaps self.ID_agent = self.config.id_chosenAgent data_contents = sio.loadmat(config.GSO) self.GSO = np.transpose(data_contents["gso"], (2, 3, 0, 1)).squeeze(3) self.commRadius = data_contents["commRadius"] self.maxLink = 500 aspect = self.data_map["map"]["dimensions"][0] / self.data_map["map"][ "dimensions"][1] self.fig = plt.figure(frameon=False, figsize=(4 * aspect, 4)) self.ax = self.fig.add_subplot(111, aspect='equal') self.fig.subplots_adjust(left=0, right=1, bottom=0, top=1, wspace=None, hspace=None) # self.ax.set_frame_on(False) self.patches = [] self.artists = [] self.agents = dict() self.commLink = dict() self.agent_names = dict() # self.list_color = self.get_cmap(self.num_agents) self.list_color = sns.color_palette("hls", self.num_agents) self.list_color_commLink = sns.color_palette("hls", 8) # self.K) self.list_commLinkStyle = list(lines.lineStyles.keys()) # create boundary patch xmin = -0.5 ymin = -0.5 xmax = self.data_map["map"]["dimensions"][0] - 0.5 ymax = self.data_map["map"]["dimensions"][1] - 0.5 # self.ax.relim() plt.xlim(xmin, xmax) plt.ylim(ymin, ymax) # self.ax.set_xticks([]) # self.ax.set_yticks([]) # plt.axis('off') # self.ax.axis('tight') # self.ax.axis('off') self.patches.append( Rectangle((xmin, ymin), xmax - xmin, ymax - ymin, facecolor='none', edgecolor='black')) for o in self.data_map["map"]["obstacles"]: x, y = o[0], o[1] self.patches.append( Rectangle((x - 0.5, y - 0.5), 1, 1, facecolor='black', edgecolor='black')) # initialize communication Link for id_link in range(self.maxLink): #https://matplotlib.org/api/artist_api.html#module-matplotlib.lines name_link = "{}".format(id_link) # self.commLink[name_link] = FancyArrowPatch((0,0), (0,0),linewidth=2) self.commLink[name_link] = plt.Line2D((0, 0), (0, 0), linewidth=2) self.artists.append(self.commLink[name_link]) # print(self.schedule["schedule"]) # create agents: self.T = 0 # draw goals first for d, i in zip(self.data_map["agents"], range(0, self.num_agents)): self.patches.append( Rectangle((d["goal"][0] - 0.25, d["goal"][1] - 0.25), 0.6, 0.6, facecolor=self.list_color[i], edgecolor=self.list_color[i], alpha=0.5)) for d, i in zip(self.data_map["agents"], range(0, self.num_agents)): #https://matplotlib.org/api/artist_api.html#module-matplotlib.lines name = d["name"] self.agents[name] = Circle((d["start"][0], d["start"][1]), 0.4, facecolor=self.list_color[i], edgecolor=self.list_color[i]) self.agents[name].original_face_color = self.list_color[i] self.patches.append(self.agents[name]) self.T = max(self.T, self.schedule["schedule"][name][-1]["t"]) # set floating ID self.agent_names[name] = self.ax.text(d["start"][0], d["start"][1], name.replace('agent', '')) self.agent_names[name].set_horizontalalignment('center') self.agent_names[name].set_verticalalignment('center') self.artists.append(self.agent_names[name]) # self.ax.add_line(dotted_line) # self.ax.set_axis_off() # self.fig.axes[0].set_visible(False) # self.fig.axes.get_yaxis().set_visible(False) # self.fig.tight_layout() self.anim = animation.FuncAnimation(self.fig, self.animate_func, init_func=self.init_func, frames=int(self.T + 1) * 10, interval=100, blit=True)
z = np.cos(v) return x,y,z if __name__=='__main__': fig = plt.figure() H,W = 2,3 h0,w0 = 1,1 h3,w3 = 2,2 ax0 = plt.subplot2grid((H,W),(0,0),rowspan=h0,colspan=w0,fig=fig) ax0.set_aspect('equal') ax0.set_xlim(-1.3,1.3) ax0.set_ylim(-1.3,1.3) ax0.set_axis_off() ax0.add_artist(Circle((0,0),1.)) handle0 = Arrow(0,1) ax0.add_artist(handle0) ax1 = plt.subplot2grid((H,W),(1,0),rowspan=h0,colspan=w0,fig=fig) ax1.set_aspect('equal') ax1.set_xlim(-1.3,1.3) ax1.set_ylim(-1.3,1.3) ax1.set_axis_off() ax1.add_artist(Circle((0,0),1.)) handle1 = Arrow(0,0) ax1.add_artist(handle1) ax3 = plt.subplot2grid((H,W),(0,1),rowspan=h3,colspan=w3,fig=fig,projection='3d') ax3.set_aspect('equal') ax3.set_axis_off()
G = gradient(_x1, _x2) _g1 = G _g2 = -G __x1 = _x1 - _g1 __x1 = __x1 / la.norm(__x1) __x2 = _x2 - _g2 __x2 = __x2 / la.norm(__x2) G = gradient(_x1, _x2) __g1 = G __g2 = -G print('distance between points {:1.2f}'.format(la.norm(x1 - x2))) print('gradient norm {:1.2f}'.format(la.norm(g1))) circle = Circle((0., 0.), radius=1., fill=False) fig = pl.figure() ax = fig.add_subplot(111) ax.axis('equal') ax.add_patch(circle) ax.scatter(0., 0., color='black') ax.scatter(x1[0], x1[1], color='blue') ax.scatter(x2[0], x2[1], color='red') ax.arrow(x1[0], x1[1], g1[0], g1[1]) ax.arrow(x2[0], x2[1], g2[0], g2[1]) ax.scatter(_x1[0], _x1[1], marker='^', color='blue') ax.scatter(_x2[0], _x2[1], marker='^', color='red') ax.arrow(_x1[0], _x1[1], _g1[0], _g1[1]) ax.arrow(_x2[0], _x2[1], _g2[0], _g2[1]) ax.scatter(__x1[0], __x1[1], marker='s', color='blue') ax.scatter(__x2[0], __x2[1], marker='s', color='red')
def full_circle(center, radius, ax=None, colors=('w'), **kwargs): if ax is None: ax = plt.gca() c = Circle(center, radius, fc=colors, **kwargs) ax.add_artist(c)
edgecolor='black', linewidth=0.5, color='blue') # scatter plot between the two different features else: ax[i, j].scatter(X[:, j], X[:, i], color=cc[y], edgecolor='black', linewidth=0.5) # add x/y labels if j == 0: ax[i, j].set_ylabel(feature[i]) if i == 3: ax[i, j].set_xlabel(feature[j]) #legend for feature colors for leg_col in cc: legend_type.append(Circle((1, 1), 1, color=leg_col)) fig.legend(legend_type, class_name, loc='center right', prop={'size': 11}) fig.text(0.5, .9, 'Iris Pair-Plot Dataset', ha="center", fontsize=20) # In[202]: #store png task32.png fig.savefig('task32.png', bbox_inches="tight")
def plot_state_qsphere( state, figsize=None, ax=None, show_state_labels=True, show_state_phases=False, use_degrees=False, *, rho=None, ): """Plot the qsphere representation of a quantum state. Here, the size of the points is proportional to the probability of the corresponding term in the state and the color represents the phase. Args: state (Statevector or DensityMatrix or ndarray): an N-qubit quantum state. figsize (tuple): Figure size in inches. ax (matplotlib.axes.Axes): An optional Axes object to be used for the visualization output. If none is specified a new matplotlib Figure will be created and used. Additionally, if specified there will be no returned Figure since it is redundant. show_state_labels (bool): An optional boolean indicating whether to show labels for each basis state. show_state_phases (bool): An optional boolean indicating whether to show the phase for each basis state. use_degrees (bool): An optional boolean indicating whether to use radians or degrees for the phase values in the plot. Returns: Figure: A matplotlib figure instance if the ``ax`` kwarg is not set Raises: MissingOptionalLibraryError: Requires matplotlib. VisualizationError: if input is not a valid N-qubit state. QiskitError: Input statevector does not have valid dimensions. Example: .. jupyter-execute:: from qiskit import QuantumCircuit from qiskit.quantum_info import Statevector from qiskit.visualization import plot_state_qsphere %matplotlib inline qc = QuantumCircuit(2) qc.h(0) qc.cx(0, 1) state = Statevector.from_instruction(qc) plot_state_qsphere(state) """ if not HAS_MATPLOTLIB: raise MissingOptionalLibraryError( libname="Matplotlib", name="plot_state_qsphere", pip_install="pip install matplotlib", ) import matplotlib.gridspec as gridspec from matplotlib import pyplot as plt from matplotlib.patches import Circle from matplotlib import get_backend from qiskit.visualization.bloch import Arrow3D try: import seaborn as sns except ImportError as ex: raise MissingOptionalLibraryError( libname="seaborn", name="plot_state_qsphere", pip_install="pip install seaborn", ) from ex rho = DensityMatrix(state) num = rho.num_qubits if num is None: raise VisualizationError("Input is not a multi-qubit quantum state.") # get the eigenvectors and eigenvalues eigvals, eigvecs = linalg.eigh(rho.data) if figsize is None: figsize = (7, 7) if ax is None: return_fig = True fig = plt.figure(figsize=figsize) else: return_fig = False fig = ax.get_figure() gs = gridspec.GridSpec(nrows=3, ncols=3) ax = fig.add_subplot(gs[0:3, 0:3], projection="3d") ax.axes.set_xlim3d(-1.0, 1.0) ax.axes.set_ylim3d(-1.0, 1.0) ax.axes.set_zlim3d(-1.0, 1.0) ax.axes.grid(False) ax.view_init(elev=5, azim=275) # Force aspect ratio # MPL 3.2 or previous do not have set_box_aspect if hasattr(ax.axes, "set_box_aspect"): ax.axes.set_box_aspect((1, 1, 1)) # start the plotting # Plot semi-transparent sphere u = np.linspace(0, 2 * np.pi, 25) v = np.linspace(0, np.pi, 25) x = np.outer(np.cos(u), np.sin(v)) y = np.outer(np.sin(u), np.sin(v)) z = np.outer(np.ones(np.size(u)), np.cos(v)) ax.plot_surface(x, y, z, rstride=1, cstride=1, color=plt.rcParams["grid.color"], alpha=0.2, linewidth=0) # Get rid of the panes ax.w_xaxis.set_pane_color((1.0, 1.0, 1.0, 0.0)) ax.w_yaxis.set_pane_color((1.0, 1.0, 1.0, 0.0)) ax.w_zaxis.set_pane_color((1.0, 1.0, 1.0, 0.0)) # Get rid of the spines ax.w_xaxis.line.set_color((1.0, 1.0, 1.0, 0.0)) ax.w_yaxis.line.set_color((1.0, 1.0, 1.0, 0.0)) ax.w_zaxis.line.set_color((1.0, 1.0, 1.0, 0.0)) # Get rid of the ticks ax.set_xticks([]) ax.set_yticks([]) ax.set_zticks([]) # traversing the eigvals/vecs backward as sorted low->high for idx in range(eigvals.shape[0] - 1, -1, -1): if eigvals[idx] > 0.001: # get the max eigenvalue state = eigvecs[:, idx] loc = np.absolute(state).argmax() # remove the global phase from max element angles = (np.angle(state[loc]) + 2 * np.pi) % (2 * np.pi) angleset = np.exp(-1j * angles) state = angleset * state d = num for i in range(2**num): # get x,y,z points element = bin(i)[2:].zfill(num) weight = element.count("1") zvalue = -2 * weight / d + 1 number_of_divisions = n_choose_k(d, weight) weight_order = bit_string_index(element) angle = (float(weight) / d) * (np.pi * 2) + ( weight_order * 2 * (np.pi / number_of_divisions)) if (weight > d / 2) or ( (weight == d / 2) and (weight_order >= number_of_divisions / 2)): angle = np.pi - angle - (2 * np.pi / number_of_divisions) xvalue = np.sqrt(1 - zvalue**2) * np.cos(angle) yvalue = np.sqrt(1 - zvalue**2) * np.sin(angle) # get prob and angle - prob will be shade and angle color prob = np.real(np.dot(state[i], state[i].conj())) if prob > 1: # See https://github.com/Qiskit/qiskit-terra/issues/4666 prob = 1 colorstate = phase_to_rgb(state[i]) alfa = 1 if yvalue >= 0.1: alfa = 1.0 - yvalue if not np.isclose(prob, 0) and show_state_labels: rprime = 1.3 angle_theta = np.arctan2(np.sqrt(1 - zvalue**2), zvalue) xvalue_text = rprime * np.sin(angle_theta) * np.cos(angle) yvalue_text = rprime * np.sin(angle_theta) * np.sin(angle) zvalue_text = rprime * np.cos(angle_theta) element_text = "$\\vert" + element + "\\rangle$" if show_state_phases: element_angle = (np.angle(state[i]) + (np.pi * 4)) % (np.pi * 2) if use_degrees: element_text += "\n$%.1f^\\circ$" % ( element_angle * 180 / np.pi) else: element_angle = pi_check(element_angle, ndigits=3).replace( "pi", "\\pi") element_text += "\n$%s$" % (element_angle) ax.text( xvalue_text, yvalue_text, zvalue_text, element_text, ha="center", va="center", size=12, ) ax.plot( [xvalue], [yvalue], [zvalue], markerfacecolor=colorstate, markeredgecolor=colorstate, marker="o", markersize=np.sqrt(prob) * 30, alpha=alfa, ) a = Arrow3D( [0, xvalue], [0, yvalue], [0, zvalue], mutation_scale=20, alpha=prob, arrowstyle="-", color=colorstate, lw=2, ) ax.add_artist(a) # add weight lines for weight in range(d + 1): theta = np.linspace(-2 * np.pi, 2 * np.pi, 100) z = -2 * weight / d + 1 r = np.sqrt(1 - z**2) x = r * np.cos(theta) y = r * np.sin(theta) ax.plot(x, y, z, color=(0.5, 0.5, 0.5), lw=1, ls=":", alpha=0.5) # add center point ax.plot( [0], [0], [0], markerfacecolor=(0.5, 0.5, 0.5), markeredgecolor=(0.5, 0.5, 0.5), marker="o", markersize=3, alpha=1, ) else: break n = 64 theta = np.ones(n) colors = sns.hls_palette(n) ax2 = fig.add_subplot(gs[2:, 2:]) ax2.pie(theta, colors=colors[5 * n // 8:] + colors[:5 * n // 8], radius=0.75) ax2.add_artist(Circle((0, 0), 0.5, color="white", zorder=1)) offset = 0.95 # since radius of sphere is one. if use_degrees: labels = ["Phase\n(Deg)", "0", "90", "180 ", "270"] else: labels = ["Phase", "$0$", "$\\pi/2$", "$\\pi$", "$3\\pi/2$"] ax2.text(0, 0, labels[0], horizontalalignment="center", verticalalignment="center", fontsize=14) ax2.text(offset, 0, labels[1], horizontalalignment="center", verticalalignment="center", fontsize=14) ax2.text(0, offset, labels[2], horizontalalignment="center", verticalalignment="center", fontsize=14) ax2.text(-offset, 0, labels[3], horizontalalignment="center", verticalalignment="center", fontsize=14) ax2.text(0, -offset, labels[4], horizontalalignment="center", verticalalignment="center", fontsize=14) if return_fig: if get_backend() in [ "module://ipykernel.pylab.backend_inline", "nbAgg" ]: plt.close(fig) return fig
def plotGraph(ax,pos,lineX,lineY,prob=None,prob2=None,nodesize=None,barscale=1, barcolor='green',baralpha=0.25,barcolor2='blue',baralpha2=0.25, bartext=False,bartextcolor='black',bartextbg=None,btoffset=[-0.025,-0.025,0.05], bartext2=False,bartextcolor2='black',bartextbg2=None,btoffset2=[-0.025,-0.025,-0.05], nodecolor='red',nodealpha=0.5, nodetext=True,nodetextcolor='black',nodetextbg=None,nodetextbg2=None,ntoffset=[0,0,-0.15]): """ Creates a plot of probability vs node superimposed on a 3D visualisation of the graph vertices. Args: ax (mpl_toolkits.mplot3d.plt3d.Axes3D): a matplotlib 3D axes to plot the graph on. pos (array) : :math:`(x,y)` coordinates of the graph vertices. lineX (array): :math:`x` coordinates of graph edges connecting vertices. lineY (array): :math:`y` coordinates of graph edges connecting vertices. probP (petsc4py.PETSc.Vec) : the probability to be represented as bars placed above/below each graph vertex for ``P=(1|2)`` repectively. If ``None``, the graph is plotted without any probability. Keyword Args: nodesize (float) : size of the vertices in the plot. If left blank, this is determined automatically. nodecolor (str) : vertex color (*default* ``'red'``). For more details on how to specify a color, see the `matplotlib documentation <http://matplotlib.org/api/colors_api.html#module-matplotlib.colors>`_. nodealpha (float) : value between 0 and 1 specifying the vertex opacity (*default* 0.25) nodetext (bool) : if set ``True``, the vertices are labelled by number. nodetextcolor (str) : vertex label text color (*default* ``'black'``). nodetextbg (str) : vertex label background color (*default* ``'None'``). ntofffset (array of floats): the :math:`(x,y,z)` vertex label offset relative \ to the vertex (*default* ``[0.,0.,-0.15]``). barscaleP (float) : scaled height of the probability bars (*default* ``1``). barcolorP (str) : probability bar color (*default* ``'green'``). baralphaP (float) : value between 0 and 1 specifying the opacity (*default* 0.25) bartext (bool) : if set ``True``, the probability bars are labelled with their value. bartextcolorP (str) : probability label text color (*default* ``'black'``). bartextbgP (str) : probability label background color (*default* ``'None'``). btoffsetP (array of floats): the :math:`(x,y,z)` probability label offset relative to the top of the probability bars (*default* ``[-0.025,-0.025,0.05]``) .. important:: * Where an argument ends with ``P`` above, substitute ``P=(1|2)`` to \ access the property for particle 1 and 2 respectively. * Only MPI node **0** will run this function; all others will just ``Pass``. \ **Thus if the** :attr:`probP` **vectors are distributed over multiple nodes, \ they must first be gathered to node 0** * This function does not initialize a 3D matplotlib figure/axes; that **must** be done \ independently, and passed through the :attr:`ax` argument. """ # use process 0 to create the plot rank = _PETSc.COMM_WORLD.Get_rank() if rank==0: from matplotlib.colors import ColorConverter as cl from matplotlib.patches import Circle import mpl_toolkits.mplot3d.art3d as art3d for i in range(len(lineX)): ax.plot(lineX[i], lineY[i],zs=-0.01,color='black',alpha=0.8, linewidth=2) #ax.scatter3D(pos.T[0], pos.T[1], color = 'orange', marker = "o", s=200) #ax.bar3d([x-0.04 for x in pos.T[0]],[x-0.04 for x in pos.T[1]], # _np.zeros_like(pos.T[0]),0.08,0.08,0, color='orange',alpha=0.3,edgecolor='gray') if nodesize is None: nodesize=[] for i in range(len(lineX)): nodesize.append(_np.sqrt(_np.sum(_np.square([-_np.subtract(*lineX[i]), -_np.subtract(*lineY[i])])))) nodesize=min(_np.min(nodesize)*0.6/2,0.05) for i in range(len(pos)): p = Circle((pos.T[0][i], pos.T[1][i]), nodesize, color=nodecolor, alpha=nodealpha) ax.add_patch(p) art3d.pathpatch_2d_to_3d(p, z=0.0, zdir="z") if nodetext: ax.text(pos.T[0][i]+ntoffset[0], pos.T[1][i]+ntoffset[1],ntoffset[2],str(i),color=nodetextcolor, bbox=(None if nodetextbg is None else dict(facecolor=nodetextbg, alpha=0.2))) if prob is not None: # probability bars for i,val in enumerate(prob): if val != 0: ax.bar3d(pos.T[0][i]-0.7*nodesize/2,pos.T[1][i]-0.7*nodesize/2,0,0.7*nodesize,0.7*nodesize,val*barscale, color=barcolor,edgecolor=cl.to_rgba(cl(),barcolor,alpha=baralpha),alpha=baralpha) if bartext: ax.text(pos.T[0][i]+btoffset[0], pos.T[1][i]+btoffset[1],val*barscale+btoffset[2],'{0: .4f}'.format(val), color=bartextcolor,bbox=(None if bartextbg is None else dict(facecolor=nodetextbg, alpha=0.1))) if prob2 is not None: # probability bars for i,val in enumerate(prob2): if val != 0: ax.bar3d(pos.T[0][i]-0.7*nodesize/2,pos.T[1][i]-0.7*nodesize/2,0,0.7*nodesize,0.7*nodesize,-val*barscale, color=barcolor2,edgecolor=cl.to_rgba(cl(),barcolor2,alpha=baralpha2),alpha=baralpha2) if bartext: ax.text(pos.T[0][i]+btoffset[0], pos.T[1][i]+btoffset[1],-val*barscale-btoffset[2],'{0: .4f}'.format(val), color=bartextcolor2,bbox=(None if bartextbg2 is None else dict(facecolor=nodetextbg2, alpha=0.1))) if prob2 is None: ax.set_zlim3d([0,1]) else: ax.set_zlim3d([-1,1]) ax.set_xlim3d([pos.T[0].min(),pos.T[0].max()]) ax.set_ylim3d([pos.T[1].min(),pos.T[1].max()]) ax.set_axis_off()
def _plot_data(data, parameters): storm_dir, storm_spd = parameters['storm_motion'] bl_dir, bl_spd = parameters['bunkers_left'] br_dir, br_spd = parameters['bunkers_right'] mn_dir, mn_spd = parameters['mean_wind'] u, v = vec2comp(data['wind_dir'], data['wind_spd']) alt = data['altitude'] storm_u, storm_v = vec2comp(storm_dir, storm_spd) bl_u, bl_v = vec2comp(bl_dir, bl_spd) br_u, br_v = vec2comp(br_dir, br_spd) mn_u, mn_v = vec2comp(mn_dir, mn_spd) seg_idxs = np.searchsorted(alt, _seg_hghts) try: seg_u = np.interp(_seg_hghts, alt, u, left=np.nan, right=np.nan) seg_v = np.interp(_seg_hghts, alt, v, left=np.nan, right=np.nan) ca_u = np.interp(0.5, alt, u, left=np.nan, right=np.nan) ca_v = np.interp(0.5, alt, v, left=np.nan, right=np.nan) except ValueError: seg_u = np.nan * np.array(_seg_hghts) seg_v = np.nan * np.array(_seg_hghts) ca_u = np.nan ca_v = np.nan mkr_z = np.arange(16) mkr_u = np.interp(mkr_z, alt, u, left=np.nan, right=np.nan) mkr_v = np.interp(mkr_z, alt, v, left=np.nan, right=np.nan) for idx in range(len(_seg_hghts) - 1): idx_start = seg_idxs[idx] idx_end = seg_idxs[idx + 1] if not np.isnan(seg_u[idx]): pylab.plot([seg_u[idx], u[idx_start]], [seg_v[idx], v[idx_start]], '-', color=_seg_colors[idx], linewidth=1.5) if idx_start < len( data['rms_error']) and data['rms_error'][idx_start] == 0.: # The first segment is to the surface wind, draw it in a dashed line pylab.plot(u[idx_start:(idx_start + 2)], v[idx_start:(idx_start + 2)], '--', color=_seg_colors[idx], linewidth=1.5) pylab.plot(u[(idx_start + 1):idx_end], v[(idx_start + 1):idx_end], '-', color=_seg_colors[idx], linewidth=1.5) else: pylab.plot(u[idx_start:idx_end], v[idx_start:idx_end], '-', color=_seg_colors[idx], linewidth=1.5) if not np.isnan(seg_u[idx + 1]): pylab.plot([u[idx_end - 1], seg_u[idx + 1]], [v[idx_end - 1], seg_v[idx + 1]], '-', color=_seg_colors[idx], linewidth=1.5) for upt, vpt, rms in list(zip(u, v, data['rms_error']))[idx_start:idx_end]: rad = np.sqrt(2) * rms circ = Circle((upt, vpt), rad, color=_seg_colors[idx], alpha=0.05) pylab.gca().add_patch(circ) pylab.plot(mkr_u, mkr_v, 'ko', ms=10) for um, vm, zm in zip(mkr_u, mkr_v, mkr_z): if not np.isnan(um): pylab.text(um, vm - 0.1, str(zm), va='center', ha='center', color='white', size=6.5, fontweight='bold') try: pylab.plot([storm_u, u[0]], [storm_v, v[0]], 'c-', linewidth=0.75) pylab.plot([u[0], ca_u], [v[0], ca_v], 'm-', linewidth=0.75) except IndexError: pass if not (np.isnan(bl_u) or np.isnan(bl_v)): pylab.plot(bl_u, bl_v, 'ko', markersize=5, mfc='none') pylab.text(bl_u + 0.5, bl_v - 0.5, "LM", ha='left', va='top', color='k', fontsize=10) if not (np.isnan(br_u) or np.isnan(br_v)): pylab.plot(br_u, br_v, 'ko', markersize=5, mfc='none') pylab.text(br_u + 0.5, br_v - 0.5, "RM", ha='left', va='top', color='k', fontsize=10) if not (np.isnan(mn_u) or np.isnan(mn_v)): pylab.plot(mn_u, mn_v, 's', color='#a04000', markersize=5, mfc='none') pylab.text(mn_u + 0.6, mn_v - 0.6, "MEAN", ha='left', va='top', color='#a04000', fontsize=10) smv_is_brm = (storm_u == br_u and storm_v == br_v) smv_is_blm = (storm_u == bl_u and storm_v == bl_v) smv_is_mnw = (storm_u == mn_u and storm_v == mn_v) if not (np.isnan(storm_u) or np.isnan(storm_v)) and not ( smv_is_brm or smv_is_blm or smv_is_mnw): pylab.plot(storm_u, storm_v, 'k+', markersize=6) pylab.text(storm_u + 0.5, storm_v - 0.5, "SM", ha='left', va='top', color='k', fontsize=10)
def draw_other_ax(self, ax, x, y, max_score_id, joint_id=None): output = self.output b_output = self.b_output cx, cy = int(coord2pix(x, 4)), int(coord2pix(y, 4)) xx, yy = output.corr_pos_pred[cy][cx] bxx, byy = self.b_output.corr_pos_pred[cy][cx] ax.clear() ax.imshow(output.img2) circ = Circle(max_score_id, 3, color=RGB_MATCHING_COLOR) ax.add_patch(circ) # draw epipolar lines line_start1 = de_normalize(output.sample_locs[1][int(cy)][int(cx)], output.H, output.W) line_start2 = de_normalize(output.sample_locs[63][int(cy)][int(cx)], output.H, output.W) ax.plot([line_start1[0], line_start2[0]], [line_start1[1], line_start2[1]], alpha=0.5, color='b', zorder=1) # draw groundtruth points # for i in range(17): gx, gy = output.points_2d[output.other_camera][joint_id][ 0], output.points_2d[output.other_camera][joint_id][1] circ = Circle((gx, gy), 3, color=GROUNDTRUTH_COLOR, zorder=2) ax.add_patch(circ) # draw baseline predicted point circ = Circle((pix2coord(bxx, 4), pix2coord(byy, 4)), 3, color=BASELINE_MATCHING_COLOR, zorder=2) ax.add_patch(circ) # draw predicted point circ = Circle((pix2coord(xx, 4), pix2coord(yy, 4)), 3, color=OURS_MATCHING_COLOR, zorder=3) ax.add_patch(circ) def dist(x1, y1, x2, y2): return math.sqrt((x1 - x2)**2 + (y1 - y2)**2) flag = True # predicted - gt > baseline - gt if dist(pix2coord(xx, 4), pix2coord(yy, 4), gx, gy) * 1.5 > dist( pix2coord(bxx, 4), pix2coord(byy, 4), gx, gy): flag = False # predicted - gt > TH: 3 if dist(pix2coord(bxx, 4), pix2coord(byy, 4), gx, gy) < 5: flag = False if flag: print('img1 path: ', output.img1_path) print('img2 path: ', output.img2_path) print('pred - gt: ', dist(pix2coord(xx, 4), pix2coord(yy, 4), gx, gy)) print('baseline - gt', dist(pix2coord(bxx, 4), pix2coord(byy, 4), gx, gy)) txt = self.sample_ax.text(0, 0, '', va="bottom", ha="left") txt.set_text('g: groundtruth; y: baseline; r: our prediction') return flag
def smith(smithR=1, chart_type='z', draw_labels=False, border=False, ax=None): ''' plots the smith chart of a given radius Parameters ----------- smithR : number radius of smith chart chart_type : ['z','y'] Contour type. Possible values are * *'z'* : lines of constant impedance * *'y'* : lines of constant admittance draw_labels : Boolean annotate real and imaginary parts of impedance on the chart (only if smithR=1) border : Boolean draw a rectangular border with axis ticks, around the perimeter of the figure. Not used if draw_labels = True ax : matplotlib.axes object existing axes to draw smith chart on ''' ##TODO: fix this function so it doesnt suck if ax == None: ax1 = plb.gca() else: ax1 = ax # contour holds matplotlib instances of: pathes.Circle, and lines.Line2D, which # are the contours on the smith chart contour = [] # these are hard-coded on purpose,as they should always be present rHeavyList = [0, 1] xHeavyList = [1, -1] #TODO: fix this # these could be dynamically coded in the future, but work good'nuff for now if not draw_labels: rLightList = plb.logspace(3, -5, 9, base=.5) xLightList = plb.hstack([ plb.logspace(2, -5, 8, base=.5), -1 * plb.logspace(2, -5, 8, base=.5) ]) else: rLightList = plb.array([0.2, 0.5, 1.0, 2.0, 5.0]) xLightList = plb.array( [0.2, 0.5, 1.0, 2.0, 5.0, -0.2, -0.5, -1.0, -2.0, -5.0]) # cheap way to make a ok-looking smith chart at larger than 1 radii if smithR > 1: rMax = (1. + smithR) / (1. - smithR) rLightList = plb.hstack([plb.linspace(0, rMax, 11), rLightList]) if chart_type is 'y': y_flip_sign = -1 else: y_flip_sign = 1 # loops through Light and Heavy lists and draws circles using patches # for analysis of this see R.M. Weikles Microwave II notes (from uva) for r in rLightList: center = (r / (1. + r) * y_flip_sign, 0) radius = 1. / (1 + r) contour.append(Circle(center, radius, ec='grey', fc='none')) for x in xLightList: center = (1 * y_flip_sign, 1. / x) radius = 1. / x contour.append(Circle(center, radius, ec='grey', fc='none')) for r in rHeavyList: center = (r / (1. + r) * y_flip_sign, 0) radius = 1. / (1 + r) contour.append(Circle(center, radius, ec='black', fc='none')) for x in xHeavyList: center = (1 * y_flip_sign, 1. / x) radius = 1. / x contour.append(Circle(center, radius, ec='black', fc='none')) # clipping circle clipc = Circle([0, 0], smithR, ec='k', fc='None', visible=True) ax1.add_patch(clipc) #draw x and y axis ax1.axhline(0, color='k', lw=.1, clip_path=clipc) ax1.axvline(1 * y_flip_sign, color='k', clip_path=clipc) ax1.grid(0) #set axis limits ax1.axis('equal') ax1.axis(smithR * npy.array([-1.1, 1.1, -1.1, 1.1])) if not border: ax1.yaxis.set_ticks([]) ax1.xaxis.set_ticks([]) for loc, spine in ax1.spines.iteritems(): spine.set_color('none') if draw_labels: #Clear axis ax1.yaxis.set_ticks([]) ax1.xaxis.set_ticks([]) for loc, spine in ax1.spines.iteritems(): spine.set_color('none') #Will make annotations only if the radius is 1 and it is the impedance smith chart if smithR is 1 and y_flip_sign is 1: #Make room for annotation ax1.axis(smithR * npy.array([-1., 1., -1.2, 1.2])) #Annotate real part for value in rLightList: rho = (value - 1) / (value + 1) ax1.annotate(str(value), xy=((rho-0.12)*smithR, 0.01*smithR), \ xytext=((rho-0.12)*smithR, 0.01*smithR)) #Annotate imaginary part deltax = plb.array( [-0.17, -0.14, -0.06, 0., 0.02, -0.2, -0.2, -0.08, 0., 0.03]) deltay = plb.array( [0., 0.03, 0.01, 0.02, 0., -0.02, -0.06, -0.09, -0.08, -0.05]) for value, dx, dy in zip(xLightList, deltax, deltay): #Transforms from complex to cartesian and adds a delta to x and y values rhox = (-value**2 + 1) / (-value**2 - 1) * smithR * y_flip_sign + dx rhoy = (-2 * value) / (-value**2 - 1) * smithR + dy #Annotate value ax1.annotate(str(value) + 'j', xy=(rhox, rhoy), xytext=(rhox, rhoy)) #Annotate 0 and inf ax1.annotate('0.0', xy=(-1.15, -0.02), xytext=(-1.15, -0.02)) ax1.annotate('$\infty$', xy=(1.02, -0.02), xytext=(1.02, -0.02)) # loop though contours and draw them on the given axes for currentContour in contour: cc = ax1.add_patch(currentContour) cc.set_clip_path(clipc)
def patch(): return Circle((0.5, 0.4687), radius=.46, clip_on=True, transform=plt.gca().transAxes)
def _gen_axes_patch(self): return Circle((0.5, 0.5), 0.5)
def render_single_dot(self, x, y): cir = Circle((x, y), radius=0.5, color='white') self.ax.add_patch(cir) self.dot = cir
fig, (ax, ax2) = plt.subplots(nrows=2, ncols=1, figsize=(8, 6)) lines = [] circles = [] patches = [] walls = [] kes = [] for i in range(0, len(cols), NCOLS): print(i) # print(cols[i]) # print(cols[i+1]) line, = ax.plot(cols[i], cols[i + 1]) lines.append(line) circle = Circle((cols[i][0], cols[i + 1][0]), radius=rads[int(i / NCOLS)]) patch = ax.add_patch(circle) circles.append(circle) patches.append(patch) ke, = ax2.plot(cols[i + 4]) kes.append(ke) tke, = ax2.plot(totke) for i in range(NWALLS): xs = [walldat[i * WALLCOL][0], walldat[i * WALLCOL + 2][0]] ys = [walldat[i * WALLCOL + 1][0], walldat[i * WALLCOL + 3][0]] wall, = ax.plot(xs, ys, 'k-') walls.append(wall)
def __init__(self, map, schedule): self.map = map self.schedule = schedule aspect = map["map"]["dimensions"][0] / map["map"]["dimensions"][1] self.fig = plt.figure(frameon=False, figsize=(4 * aspect, 4)) self.ax = self.fig.add_subplot(111, aspect='equal') self.fig.subplots_adjust(left=0,right=1,bottom=0,top=1, wspace=None, hspace=None) # self.ax.set_frame_on(False) self.patches = [] self.artists = [] self.agents = dict() self.agent_names = dict() # create boundary patch xmin = -0.5 ymin = -0.5 xmax = map["map"]["dimensions"][0] - 0.5 ymax = map["map"]["dimensions"][1] - 0.5 # self.ax.relim() plt.xlim(xmin, xmax) plt.ylim(ymin, ymax) # self.ax.set_xticks([]) # self.ax.set_yticks([]) # plt.axis('off') # self.ax.axis('tight') # self.ax.axis('off') self.patches.append(Rectangle((xmin, ymin), xmax - xmin, ymax - ymin, facecolor='none', edgecolor='red')) for o in map["map"]["obstacles"]: x, y = o[0], o[1] self.patches.append(Rectangle((x - 0.5, y - 0.5), 1, 1, facecolor='red', edgecolor='red')) # create agents: self.T = 0 # draw goals first for d, i in zip(map["agents"], range(0, len(map["agents"]))): self.patches.append(Rectangle((d["goal"][0] - 0.25, d["goal"][1] - 0.25), 0.5, 0.5, facecolor=Colors[i%len(Colors)], edgecolor='black', alpha=0.5)) for d, i in zip(map["agents"], range(0, len(map["agents"]))): name = d["name"] self.agents[name] = Circle((d["start"][0], d["start"][1]), 0.3, facecolor=Colors[i%len(Colors)], edgecolor='black') self.agents[name].original_face_color = Colors[i%len(Colors)] self.patches.append(self.agents[name]) self.T = max(self.T, schedule["schedule"][name][-1]["t"]) self.agent_names[name] = self.ax.text(d["start"][0], d["start"][1], name.replace('agent', '')) self.agent_names[name].set_horizontalalignment('center') self.agent_names[name].set_verticalalignment('center') self.artists.append(self.agent_names[name]) # self.ax.set_axis_off() # self.fig.axes[0].set_visible(False) # self.fig.axes.get_yaxis().set_visible(False) # self.fig.tight_layout() self.anim = animation.FuncAnimation(self.fig, self.animate_func, init_func=self.init_func, frames=int(self.T+1) * 10, interval=100, blit=True)
def runSlices(opsimName, metadata, simdata, fields, bins, args, opsDb, verbose=False): # Set up the movie slicer. movieslicer = setupMovieSlicer(simdata, bins) # Set up formatting for output suffix. sliceformat = '%s0%dd' % ('%', int(np.log10(len(movieslicer))) + 1) # Get the telescope latitude info. lat_tele = Site(name='LSST').latitude_rad # Run through the movie slicer slicePoints and generate plots at each point. for i, ms in enumerate(movieslicer): t = time.time() slicenumber = sliceformat % (i) if verbose: print(slicenumber) # Set up metrics. if args.movieStepsize != 0: tstep = args.movieStepsize else: tstep = ms['slicePoint']['binRight'] - bins[i] if tstep > 1: tstep = 40. / 24. / 60. / 60. # Add simple view of time to plot label. times_from_start = ms['slicePoint']['binRight'] - (int(bins[0]) + 0.16 - 0.5) # Opsim years are 365 days (not 365.25) years = int(times_from_start / 365) days = times_from_start - years * 365 plotlabel = 'Year %d Day %.4f' % (years, days) # Set up metrics. metricList, plotDictList = setupMetrics( opsimName, metadata, plotlabel=plotlabel, t0=ms['slicePoint']['binRight'], tStep=tstep, years=years, verbose=verbose) # Identify the subset of simdata in the movieslicer 'data slice' simdatasubset = simdata[ms['idxs']] # Set up opsim slicer on subset of simdata provided by movieslicer opslicer = slicers.OpsimFieldSlicer(simDataFieldIdColName='fieldID', fieldIdColName='fieldID') # Set up metricBundles to combine metrics, plotdicts and slicer. bundles = [] sqlconstraint = '' for metric, plotDict in zip(metricList, plotDictList): bundles.append( metricBundles.MetricBundle(metric, opslicer, constraint=sqlconstraint, metadata=metadata, runName=opsimName, plotDict=plotDict)) # Remove (default) stackers from bundles, because we've already run them above on the original data. for mb in bundles: mb.stackerList = [] bundledict = metricBundles.makeBundlesDictFromList(bundles) # Set up metricBundleGroup to handle metrics calculation + plotting bg = metricBundles.MetricBundleGroup(bundledict, opsDb, outDir=args.outDir, resultsDb=None, saveEarly=False) # 'Hack' bundleGroup to just go ahead and run the metrics, without querying the database. simData = simdatasubset bg.fieldData = fields bg.setCurrent(sqlconstraint) bg.runCurrent(constraint=sqlconstraint, simData=simData) # Plot data each metric, for this slice of the movie, adding slicenumber as a suffix for output plots. # Plotting here, rather than automatically via sliceMetric method because we're going to rotate the sky, # and add extra legend info and figure text (for FilterColors metric). ph = plots.PlotHandler(outDir=args.outDir, figformat='png', dpi=72, thumbnail=False, savefig=False) obsnow = np.where( simdatasubset['expMJD'] == simdatasubset['expMJD'].max())[0] raCen = np.mean(simdatasubset[obsnow]['lst']) # Calculate horizon location. horizonlon, horizonlat = addHorizon(lat_telescope=lat_tele) # Create the plot for each metric and save it (after some additional manipulation). for mb in bundles: ph.setMetricBundles([mb]) fignum = ph.plot(plotFunc=plots.BaseSkyMap(), plotDicts={'raCen': raCen}) fig = plt.figure(fignum) ax = plt.gca() # Add horizon and zenith. plt.plot(horizonlon, horizonlat, 'k.', alpha=0.3, markersize=1.8) plt.plot(0, lat_tele, 'k+') # For the FilterColors metric, add some extra items. if mb.metric.name == 'FilterColors': # Add the time stamp info (plotlabel) with a fancybox. plt.figtext(0.75, 0.9, '%s' % (plotlabel), bbox=dict(boxstyle='Round, pad=0.7', fc='w', ec='k', alpha=0.5)) # Add a legend for the filters. filterstacker = stackers.FilterColorStacker() for i, f in enumerate(['u', 'g', 'r', 'i', 'z', 'y']): plt.figtext(0.92, 0.55 - i * 0.035, f, color=filterstacker.filter_rgb_map[f]) # Add a moon. moonRA = np.mean(simdatasubset[obsnow]['moonRA']) lon = -(moonRA - raCen - np.pi) % (np.pi * 2) - np.pi moonDec = np.mean(simdatasubset[obsnow]['moonDec']) # Note that moonphase is 0-100 (translate to 0-1). 0=new. moonPhase = np.mean(simdatasubset[obsnow]['moonPhase']) / 100. alpha = np.max([moonPhase, 0.15]) circle = Circle((lon, moonDec), radius=0.05, color='k', alpha=alpha) ax.add_patch(circle) # Add some explanatory text. ecliptic = Line2D([], [], color='r', label="Ecliptic plane") galaxy = Line2D([], [], color='b', label="Galactic plane") horizon = Line2D([], [], color='k', alpha=0.3, label="20 deg elevation limit") moon = Line2D([], [], color='k', linestyle='', marker='o', markersize=8, alpha=alpha, label="\nMoon (Dark=Full)\n (Light=New)") zenith = Line2D([], [], color='k', linestyle='', marker='+', markersize=5, label="Zenith") plt.legend( handles=[horizon, zenith, galaxy, ecliptic, moon], loc=[0.1, -0.35], ncol=3, frameon=False, title= 'Aitoff plot showing HA/Dec of simulated survey pointings', numpoints=1, fontsize='small') # Save figure. plt.savefig(os.path.join( args.outDir, mb.metric.name + '_' + slicenumber + '_SkyMap.png'), format='png', dpi=72) plt.close('all') dt, t = dtime(t) if verbose: print('Ran and plotted slice %s of movieslicer in %f s' % (slicenumber, dt))
def plotter(fdict): """ Go """ import matplotlib matplotlib.use('agg') import matplotlib.pyplot as plt from matplotlib.patches import Circle pgconn = psycopg2.connect(database='coop', host='iemdb', user='******') station = fdict.get('station', 'IA0000') month = int(fdict.get('month', 7)) year = int(fdict.get('year', datetime.datetime.now().year)) table = "alldata_%s" % (station[:2],) nt = network.Table("%sCLIMATE" % (station[:2],)) df = read_sql(""" SELECT year, sum(precip) as total_precip, sum(gdd50(high::numeric,low::numeric)) as gdd50 from """+table+""" WHERE station = %s and month = %s GROUP by year """, pgconn, params=(station, month), index_col='year') if len(df.index) == 0: return "ERROR: No Data Found" gstats = df.gdd50.describe() pstats = df.total_precip.describe() df['precip_sigma'] = (df.total_precip - pstats['mean']) / pstats['std'] df['gdd50_sigma'] = (df.gdd50 - gstats['mean']) / gstats['std'] df['distance'] = (df.precip_sigma ** 2 + df.gdd50_sigma ** 2) ** 0.5 h_slope, intercept, r_value, _, _ = stats.linregress(df['gdd50_sigma'], df['precip_sigma']) y1 = -4.0 * h_slope + intercept y2 = 4.0 * h_slope + intercept (fig, ax) = plt.subplots(1, 1) ax.scatter(df['gdd50_sigma'], df['precip_sigma']) ax.plot([-4, 4], [y1, y2], label="Slope=%.2f\nR$^2$=%.2f" % (h_slope, r_value ** 2)) xmax = df.gdd50_sigma.abs().max() + 0.25 ymax = df.precip_sigma.abs().max() + 0.25 ax.set_xlim(0 - xmax, xmax) ax.set_ylim(0 - ymax, ymax) events = df.query("distance > 2.5 or year == %.0f" % (year, )) for _year, row in events.iterrows(): ax.text(row['gdd50_sigma'], row['precip_sigma'], ' %.0f' % (_year,), va='center') if year in df.index: c = Circle((0, 0), radius=df.loc[year].distance, facecolor='none') ax.add_patch(c) ax.set_xlabel("Growing Degree Day Departure ($\sigma$)") ax.set_ylabel("Precipitation Departure ($\sigma$)") ax.grid(True) ax.legend(fontsize=10) ax.set_title(("%s %s [%s]\n" "Growing Degree Day (base=50) + Precipitation Departure" ) % ( calendar.month_name[month], nt.sts[station]['name'], station)) return fig, df
def circles(x, y, s, c='b', vmin=None, vmax=None, **kwargs): """ Make a scatter of circles plot of x vs y, where x and y are sequence like objects of the same lengths. The size of circles are in data scale. Parameters ---------- x,y : scalar or array_like, shape (n, ) Input data s : scalar or array_like, shape (n, ) Radius of circle in data unit. c : color or sequence of color, optional, default : 'b' `c` can be a single color format string, or a sequence of color specifications of length `N`, or a sequence of `N` numbers to be mapped to colors using the `cmap` and `norm` specified via kwargs. Note that `c` should not be a single numeric RGB or RGBA sequence because that is indistinguishable from an array of values to be colormapped. (If you insist, use `color` instead.) `c` can be a 2-D array in which the rows are RGB or RGBA, however. vmin, vmax : scalar, optional, default: None `vmin` and `vmax` are used in conjunction with `norm` to normalize luminance data. If either are `None`, the min and max of the color array is used. kwargs : `~matplotlib.collections.Collection` properties Eg. alpha, edgecolor(ec), facecolor(fc), linewidth(lw), linestyle(ls), norm, cmap, transform, etc. Returns ------- paths : `~matplotlib.collections.PathCollection` Examples -------- a = np.arange(11) circles(a, a, a*0.2, c=a, alpha=0.5, edgecolor='none') plt.colorbar() License -------- This code is under [The BSD 3-Clause License] (http://opensource.org/licenses/BSD-3-Clause) """ import numpy as np import matplotlib.pyplot as plt if np.isscalar(c): kwargs.setdefault('color', c) c = None if 'fc' in kwargs: kwargs.setdefault('facecolor', kwargs.pop('fc')) if 'ec' in kwargs: kwargs.setdefault('edgecolor', kwargs.pop('ec')) if 'ls' in kwargs: kwargs.setdefault('linestyle', kwargs.pop('ls')) if 'lw' in kwargs: kwargs.setdefault('linewidth', kwargs.pop('lw')) patches = [Circle((x_, y_), s_) for x_, y_, s_ in np.broadcast(x, y, s)] collection = PatchCollection(patches, **kwargs) if c is not None: collection.set_array(np.asarray(c)) collection.set_clim(vmin, vmax) ax = plt.gca() ax.add_collection(collection) ax.autoscale_view() if c is not None: plt.sci(collection) return collection
ab = AnnotationBbox(offsetbox, xy, xybox=(1.02, xy[1]), xycoords='data', boxcoords=("axes fraction", "data"), box_alignment=(0., 0.5), arrowprops=dict(arrowstyle="->")) ax.add_artist(ab) # Define a 2nd position to annotate (don't display with a marker this time) xy = [0.3, 0.55] # Annotate the 2nd position with a circle patch da = DrawingArea(20, 20, 0, 0) p = Circle((10, 10), 10) da.add_artist(p) ab = AnnotationBbox(da, xy, xybox=(1.02, xy[1]), xycoords='data', boxcoords=("axes fraction", "data"), box_alignment=(0., 0.5), arrowprops=dict(arrowstyle="->")) ax.add_artist(ab) # Annotate the 2nd position with an image (a generated array of pixels) arr = np.arange(100).reshape((10, 10)) im = OffsetImage(arr, zoom=2)
def visualize(self, file_name=None, fig_size=(8, 6.5), buffer_size=0.10, max_reward_radius=0.35, min_reward_radius=0.15, visited_reward_transparency=0.25, trajectory_width=0.06, agent_length=0.2, agent_width=0.1): colors = {'reward': 'deepskyblue', 'boundary': 'firebrick'} agent_color = ['darkorange', 'seagreen', 'darkorchid', 'gold', 'grey'] trajectory_color = [ 'peachpuff', 'palegreen', 'plum', 'palegoldenrod', 'silver' ] z = {'reward': 1, 'trajectory': 2, 'boundary': 3, 'agent': 4} coords = self.coord_at_all_locations rewards = self.rewards_at_all_locations costs = self.costs_at_all_paths title_font = { 'fontname': 'Sans Serif', 'size': '16', 'color': 'black', 'weight': 'bold' } x_min = min(coord[0] for coord in coords.values()) - buffer_size \ - max_reward_radius x_max = max(coord[0] for coord in coords.values()) + buffer_size \ + max_reward_radius y_min = min(coord[1] for coord in coords.values()) - buffer_size \ - max_reward_radius y_max = max(coord[1] for coord in coords.values()) + buffer_size \ + max_reward_radius def rectangular_polygon_coords(loc_0, loc_f, width): """ Generates a rectangle between two points with a specific width :param loc_0: A tuple of (x,y) positions representing the start :param loc_f: A tuple of (x,y) positions representing the end :param width: A scalar width of the rectangular polygon :return: A numpy array of the Polygon coordinates to be plotted """ delta_y = loc_f[1] - loc_0[1] delta_x = loc_f[0] - loc_0[0] angle = math.atan2(delta_y, delta_x) rect_x = width / 2 * np.cos(angle - math.pi / 2) rect_y = width / 2 * np.sin(angle - math.pi / 2) rect = np.array([[loc_0[0] - rect_x, loc_0[1] - rect_y], [loc_f[0] - rect_x, loc_f[1] - rect_y], [loc_f[0] + rect_x, loc_f[1] + rect_y], [loc_0[0] + rect_x, loc_0[1] + rect_y]]) return rect # Initialize the figure fig = plt.figure(figsize=fig_size) ax = fig.add_subplot(111) # Plot the boundaries ll_corner = (x_min, y_min) lr_corner = (x_max, y_min) ul_corner = (x_min, y_max) ur_corner = (x_max, y_max) for (c1, c2) in [(ll_corner, ul_corner), (ul_corner, ur_corner), (ur_corner, lr_corner), (lr_corner, ll_corner)]: polygon_coords = rectangular_polygon_coords(c1, c2, buffer_size) ax.add_patch( Polygon(xy=polygon_coords, closed=True, color=colors['boundary'], zorder=z['boundary'])) # Plot rewards max_reward = max(rewards.values()) non_zero_rewards = [ reward for reward in rewards.values() if reward != 0 ] min_reward = min(rewards.values()) for node, location in coords.items(): reward = self.reward_at_location(node) reward_radius = ((reward - min_reward) * (max_reward_radius - min_reward_radius) / (max_reward - min_reward) + min_reward_radius) x, y = location ax.add_patch( Circle(xy=(x, y), radius=reward_radius, facecolor=colors['reward'], alpha=(visited_reward_transparency if node in self.visited else 1.0), zorder=z['reward'])) # Plot agents and trajectories for k in range(len(self._histories)): agent_history = self._histories[k] t_color = trajectory_color[k % len(self._histories)] a_color = agent_color[k % len(self._histories)] # Plot trajectories for completed actions for i in range(1, len(agent_history)): prev_loc_id = agent_history[i - 1] cur_loc_id = agent_history[i] prev_loc = coords[prev_loc_id] cur_loc = coords[cur_loc_id] polygon_coords = rectangular_polygon_coords( prev_loc, cur_loc, trajectory_width) ax.add_patch( Polygon(xy=polygon_coords, closed=True, color=t_color, zorder=z['trajectory'])) # Plot agents and trajectories for ongoing actions status = self._statuses[k] if status[2] == 0: x_c, y_c = coords[status[0]] if len(agent_history) <= 1: x_s, y_s = x_c, y_c - agent_length / 2 x_e, y_e = x_c, y_c + agent_length / 2 else: x_s, y_s = coords[agent_history[-2]] x_e, y_e = coords[agent_history[-1]] else: cost = costs[(status[0], status[1])] x_s, y_s = coords[status[0]] x_e, y_e = coords[status[1]] x_c = x_e - status[2] / cost * (x_e - x_s) y_c = y_e - status[2] / cost * (y_e - y_s) polygon_coords = rectangular_polygon_coords( (x_s, y_s), (x_c, y_c), trajectory_width) ax.add_patch( Polygon(xy=polygon_coords, closed=True, color=t_color, zorder=z['trajectory'])) if x_e == x_s: dx, dy = 0, agent_length * (1 if y_e >= y_s else -1) elif y_e == y_s: dx, dy = agent_length * float(1 if x_e >= x_s else -1), 0 else: asp_ratio = (x_e - x_s) / (y_e - y_s) dy = agent_length / (1 + asp_ratio**2)**0.5 dy *= float(1 if y_e >= y_s else -1) dx = dy * asp_ratio x_start = x_c - dx / 2 y_start = y_c - dy / 2 ax.add_patch( FancyArrow(x=x_start, y=y_start, dx=dx, dy=dy, fc=a_color, width=agent_width, head_width=agent_width, head_length=agent_length * 0.2, zorder=z['agent'], length_includes_head=True)) # Plotting plt.title( "Agents Trajectories \nAccumulated Reward: {0}\n" "Time Remaining: {1}".format( sum(reward for loc, reward in self.rewards_at_all_locations.items() if loc in self.visited), self._time_remains), title_font) plt.xlabel('x', title_font) plt.ylabel('y', title_font) ax.grid(False) ax.axis('equal') ax.set_xlim(x_min, x_max) ax.set_ylim(y_min - buffer_size, y_max + buffer_size) # Save and display #plt.show() if file_name is not None: plt.savefig(file_name) return fig
def create_model(model, domain, number_of_points=500000, stl_filename="output", path=".", points_per_circle=50, plotting=False, report=True): """Create a model with the input grain size distribution (log-normal), and a specified porosity, and write it to a Stereolithography file. PARAMETERS ---------- model : dict Dictionary containing parameters of the grain size distribution. Mandatory keywords: distribution : dict Dictionary representing a distribution, either directly as a distribution, or defined by field data. Mandatory keywords depend on distribution type. mindist : int, float Minimum distance between grains (mm). seed : bool, int If False, no specific seed will be used, else should be a seed for generating a realization of the grain size distribution. domain : dict Dictionary containing parameters of the modelling domain. Mandatory keywords: xmin : int, float Lower value of the domain size along the x-axis (mm). xmax : int, float Upper value of the domain size along the x-axis (mm). ymin : int, float Lower value of the domain size along the y-axis (mm). ymax : int, float Upper value of the domain size along the y-axis (mm). por_min : float Minimum porosity value of the model por_max : float Maximum porosity value of the model height : int, float Height of the domain (i.e. its thickness along the z-axis) (mm). number_of_points : int Amount of randomly generated points that will be tried out when trying to place a grain into the model stl_filename : str Filename of the output .stl file. path : str Path to which the output (.stl and data) files are written (either relative or absolute). points_per_circle : int Number of points representing a single circle in the output .stl file (more points give a more accurate representation). plotting : bool Whether or not to plot output and intermediate steps. report : bool Whether or not to print info to the screen. RETURNS ------- por_final : float The final porosity of the model.""" # Get domain extents from dictionary xmin = domain["xmin"] xmax = domain["xmax"] ymin = domain["ymin"] ymax = domain["ymax"] stl_height = domain["height"] por_min = domain["por_min"] por_max = domain["por_max"] # Get distribution statistics from dictionary # NOTE: when different distributions are available, the parameters will be different and the entire dictionary should probably be passed to a function! dist = model["distribution"] mindist = model["mindist"] seed = model["seed"] # Generate random points if seed is not False: np.random.seed(seed) # Generate random porosity within the specified range, and initialize random points to place the grains at por = np.random.rand() * (por_max - por_min) + por_min x = np.random.rand(number_of_points) * (xmax - xmin) + xmin y = np.random.rand(number_of_points) * (ymax - ymin) + ymin # Calculate mesh area mesh_area = (xmax - xmin) * (ymax - ymin) # Check which type of distribution to use (only one at the moment). if dist["type"] == "truncLogNormal": rmin = dist["rmin"] rmax = dist["rmax"] rmean = dist["rmean"] rstd = dist["rstd"] # Generate grains based on truncated log normal distribution pdf_gen = TruncLogNorm(rmin, rmax, loc=rmean, scale=rstd) elif dist["type"] == "data": data_points = dist["data_points"] c_freq = dist["c_freq"] pdf_gen = DataDistribution(data_points, c_freq) r = np.array([]) por_new = 1 # Add new grains, pulled from the specified distribution, until the right porosity is (approximately) reached. # Note: actual porosity will always be slightly lower than the randomly generated one while por_new > por: r = np.append(r, pdf_gen.rvs(1)) por_new = calc_porosity(r, mesh_area) # Remove grains if porosity has gotten below the minimum specified porosity. while por_new < por_min: r = r[:-1] por_new = calc_porosity(r, mesh_area) # Get total number of grains number_r = len(r) if plotting: fig, ax = plt.subplots() ax.hist(r, bins=number_r//5, density=True) pdf_x = np.arange(rmin, rmax, 0.01) pdf_y = pdf_gen.pdf(pdf_x) ax.plot(pdf_x, pdf_y, label="pdf") plt.xlabel("r [mm]") plt.ylabel("density") plt.legend() plt.show() # Sort grains from large to small r.sort() r = r[::-1] # Place grains into the model domain keeper_x, keeper_y, keeper_r, double_x, double_y, double_r = place_grains(r, x, y, xmin, xmax, ymin, ymax, mindist, report=report) # Report if not all grains were placed, and show new distribution of grains sizes if len(keeper_r) < number_r: print("WARNING: Not all grains were placed into the domain; specified number: {0}, new number: {1}".format(number_r, len(keeper_r))) if plotting: pdf_x = np.arange(rmin, rmax, 0.01) pdf_y = pdf_gen.pdf(pdf_x) fig, ax = plt.subplots() ax.hist(keeper_r, bins=len(r)//5, density=True) ax.plot(pdf_x, pdf_y, label="pdf") plt.legend() plt.show() # Calculate final mean grain size and porosity # Even though some of the 'keeper' grains are partly outside of the domain, # the porosity and mean radius of the domain is still defined as the total area of the 'keeper' grain divided by the mesh area, # since all grains at the edge have a corresponding grain at the other side of the model, saved as the 'double' grains. rmean_final = np.mean(keeper_r) por_final = calc_porosity(keeper_r, mesh_area) if report: print("Starting porosity: {0}\nPorosity before placing grains: {1}\nFinal porosity: {2}\nFinal mean: {3}".format(por, por_new, por_final, rmean_final)) por_file = open("{0}{1}porosity.dat".format(path, os.sep), "w") por_file.write(str(por_final) + "\n") por_file.close() if plotting: try: fig, ax = plt.subplots() for i in range(len(keeper_r)): c = Circle((keeper_x[i], keeper_y[i]), keeper_r[i]) ax.add_patch(c) for i in range(len(double_r)): c = Circle((double_x[i], double_y[i]), double_r[i]) ax.add_patch(c) ax.autoscale_view() plt.show() except: pass # Find a point inside the mesh that is half of mindist away from a grain, to ensure the point is not inside a grain # This will be used by OpenFOAM's snappyHexMesh tool to see which part of the geometry is outside of the grains. for i in range(len(keeper_r)): point_x, point_y = keeper_x[i], keeper_y[i] if xmax > point_x > xmin and ymax > point_y > ymin: if point_y + keeper_r[i] < ymax: point_y += (keeper_r[i] + mindist / 2) elif point_y - keeper_r[i] > ymin: point_y -= (keeper_r[i] + mindist / 2) # Check with grains duplicated for periodicity too if check_valid_grain_distances(point_x, point_y, 0, double_x, double_y, double_r): break location_file = open("locationInMesh.dat", "w") location_file.write("{0} {1} {2}".format(point_x, point_y, stl_height / 2)) location_file.close() # Write raw x, y and radius data to file raw_data_file = open("raw_data.dat", "w") raw_data_file.write("x,y,r\n") for i in range(len(keeper_r)): raw_data_file.write("{0},{1},{2}\n".format(keeper_x[i], keeper_y[i], keeper_r[i])) for i in range(len(double_r)): raw_data_file.write("{0},{1},{2}\n".format(double_x[i], double_y[i], double_r[i])) raw_data_file.close() # Given a number of vertices (pointsPerCirle) and a height (stl_height), create an .stl file containing triangulated pseudo-cylinders # from the circles in the model. mesh_objects = [] for i in range(len(keeper_r)): faces = stlTools.triangulate_circle((keeper_x[i], keeper_y[i]), keeper_r[i], stl_height, points_per_circle) mesh_object = stlTools.create_mesh_object(faces) mesh_objects.append(mesh_object) for i in range(len(double_r)): faces = stlTools.triangulate_circle((double_x[i], double_y[i]), double_r[i], stl_height, points_per_circle) mesh_object = stlTools.create_mesh_object(faces) mesh_objects.append(mesh_object) stlTools.write_stl(mesh_objects, "{0}{1}{2}".format(path, os.sep, stl_filename)) return por_final