def plot_graph_on_im(G_, im_test_file, figsize=(8, 8), show_endnodes=False, width_key='speed_m/s', width_mult=0.125, color='lime', title='', figname='', default_node_size=15, max_speeds_per_line=12, dpi=300, plt_save_quality=75, ax=None, verbose=False): ''' Overlay graph on image, if width_key == int, use a constant width''' try: im_cv2 = cv2.imread(im_test_file, 1) img_mpl = cv2.cvtColor(im_cv2, cv2.COLOR_BGR2RGB) except: img_sk = skimage.io.imread(im_test_file) # make sure image is h,w,channels (assume less than 20 channels) if (len(img_sk.shape) == 3) and (img_sk.shape[0] < 20): img_mpl = np.moveaxis(img_sk, 0, -1) else: img_mpl = img_sk h, w = img_mpl.shape[:2] node_x, node_y, lines, widths, title_vals = [], [], [], [], [] # get edge data for i, (u, v, edge_data) in enumerate(G_.edges(data=True)): # if type(edge_data['geometry_pix']) if type(edge_data['geometry_pix']) == str: coords = list(shapely.wkt.loads(edge_data['geometry_pix']).coords) else: coords = list(edge_data['geometry_pix'].coords) if verbose: # (i % 100) == 0: print("\n", i, u, v, edge_data) print("edge_data:", edge_data) print(" coords:", coords) lines.append(coords) node_x.append(coords[0][0]) node_x.append(coords[-1][0]) node_y.append(coords[0][1]) node_y.append(coords[-1][1]) if type(width_key) == str: if verbose: print("edge_data[width_key]:", edge_data[width_key]) width = int(np.rint(edge_data[width_key] * width_mult)) title_vals.append(int(np.rint(edge_data[width_key]))) else: width = width_key widths.append(width) if not ax: fig, ax = plt.subplots(1, 1, figsize=figsize) ax.imshow(img_mpl) # plot nodes? if show_endnodes: ax.scatter(node_x, node_y, color=color, s=default_node_size, alpha=0.5) # plot segments # print (lines) lc = mpl_collections.LineCollection(lines, colors=color, linewidths=widths, alpha=0.4, zorder=2) ax.add_collection(lc) ax.set_yticklabels([]) ax.set_xticklabels([]) #ax.axis('off') # title if len(title_vals) > 0 and len(title) > 0: if verbose: print("title_vals:", title_vals) title_strs = np.sort(np.unique(title_vals)).astype(str) # split title str if it's too long if len(title_strs) > max_speeds_per_line: # construct new title str n, b = max_speeds_per_line, title_strs title_strs = np.insert(b, range(n, len(b), n), "\n") # title_strs = '\n'.join(s[i:i+ds] for i in range(0, len(s), ds)) if verbose: print("title_strs:", title_strs) title = title + '\n' \ + width_key + " = " + " ".join(title_strs) if len(title): # plt.suptitle(title) ax.set_title(title) plt.tight_layout() # print("title:", title) if len(title) > 0: plt.subplots_adjust(top=0.9) # plt.subplots_adjust(left=1, bottom=1, right=1, top=1, wspace=5, hspace=5) # set dpi to approximate native resolution if verbose: print("img_mpl.shape:", img_mpl.shape) desired_dpi = int(np.max(img_mpl.shape) / np.max(figsize)) if verbose: print("desired dpi:", desired_dpi) # max out dpi at 3500 dpi = int(np.min([3500, desired_dpi])) if verbose: print("plot dpi:", dpi) if figname: plt.savefig(figname, dpi=dpi, quality=plt_save_quality) return ax
def streamplot(axes, x, y, u, v, density=1, linewidth=None, color=None, cmap=None, norm=None, arrowsize=1, arrowstyle='-|>', minlength=0.1, transform=None): """Draws streamlines of a vector flow. *x*, *y* : 1d arrays defines the grid. *u*, *v* : 2d arrays x and y-velocities. Number of rows should match length of y, and the number of columns should match x. *density* : float or 2-tuple Controls the closeness of streamlines. When `density = 1`, the domain is divided into a 25x25 grid---*density* linearly scales this grid. Each cell in the grid can have, at most, one traversing streamline. For different densities in each direction, use [density_x, density_y]. *linewidth* : numeric or 2d array vary linewidth when given a 2d array with the same shape as velocities. *color* : matplotlib color code, or 2d array Streamline color. When given an array with the same shape as velocities, *color* values are converted to colors using *cmap*. *cmap* : :class:`~matplotlib.colors.Colormap` Colormap used to plot streamlines and arrows. Only necessary when using an array input for *color*. *norm* : :class:`~matplotlib.colors.Normalize` Normalize object used to scale luminance data to 0, 1. If None, stretch (min, max) to (0, 1). Only necessary when *color* is an array. *arrowsize* : float Factor scale arrow size. *arrowstyle* : str Arrow style specification. See :class:`~matplotlib.patches.FancyArrowPatch`. *minlength* : float Minimum length of streamline in axes coordinates. Returns: *stream_container* : StreamplotSet Container object with attributes - lines: `matplotlib.collections.LineCollection` of streamlines - arrows: collection of `matplotlib.patches.FancyArrowPatch` objects representing arrows half-way along stream lines. This container will probably change in the future to allow changes to the colormap, alpha, etc. for both lines and arrows, but these changes should be backward compatible. """ grid = Grid(x, y) # Handle decreasing x and y by changing sign. The sign is changed # back after the integration routines (not totally happy with # this). x_increasing = grid.x[1] > grid.x[0] if not x_increasing: grid = Grid(-grid.x, grid.y) u = -u y_increasing = grid.y[1] > grid.y[0] if not y_increasing: grid = Grid(grid.x, -grid.y) v = -v mask = StreamMask(density) dmap = DomainMap(grid, mask) # default to data coordinates if transform is None: transform = axes.transData if color is None: color = axes._get_lines.color_cycle.next() if linewidth is None: linewidth = matplotlib.rcParams['lines.linewidth'] line_kw = {} arrow_kw = dict(arrowstyle=arrowstyle, mutation_scale=10 * arrowsize) use_multicolor_lines = isinstance(color, np.ndarray) if use_multicolor_lines: assert color.shape == grid.shape line_colors = [] if np.any(np.isnan(color)): color = np.ma.array(color, mask=np.isnan(color)) else: line_kw['color'] = color arrow_kw['color'] = color if isinstance(linewidth, np.ndarray): assert linewidth.shape == grid.shape line_kw['linewidth'] = [] else: line_kw['linewidth'] = linewidth arrow_kw['linewidth'] = linewidth ## Sanity checks. assert u.shape == grid.shape assert v.shape == grid.shape if np.any(np.isnan(u)): u = np.ma.array(u, mask=np.isnan(u)) if np.any(np.isnan(v)): v = np.ma.array(v, mask=np.isnan(v)) integrate = get_integrator(grid.x, grid.y, u, v, dmap, minlength) trajectories = [] for xm, ym in _gen_starting_points(mask.shape): if mask[ym, xm] == 0: xg, yg = dmap.mask2data(xm, ym) t = integrate(xg, yg) if t is not None: trajectories.append(t) if use_multicolor_lines: if norm is None: norm = mcolors.normalize(color.min(), color.max()) if cmap is None: cmap = cm.get_cmap(matplotlib.rcParams['image.cmap']) else: cmap = cm.get_cmap(cmap) streamlines = [] arrows = [] for t in trajectories: tx = np.array(t[0]) ty = np.array(t[1]) ## undoes the sign change put in place for the handling of ## decreasing x and y arrays. if not x_increasing: tx = -tx if not y_increasing: ty = -ty points = np.transpose([tx, ty]).reshape(-1, 1, 2) streamlines.extend(np.hstack([points[:-1], points[1:]])) # Add arrows half way along each trajectory. s = np.cumsum(np.sqrt(np.diff(tx)**2 + np.diff(ty)**2)) n = np.searchsorted(s, s[-1] / 2.) arrow_tail = (tx[n], ty[n]) arrow_head = (np.mean(tx[n:n + 2]), np.mean(ty[n:n + 2])) if isinstance(linewidth, np.ndarray): line_widths = interparray(grid, linewidth, tx, ty)[:-1] line_kw['linewidth'].extend(line_widths) arrow_kw['linewidth'] = line_widths[n] if use_multicolor_lines: color_values = interparray(grid, color, tx, ty)[:-1] line_colors.extend(color_values) arrow_kw['color'] = cmap(norm(color_values[n])) p = patches.FancyArrowPatch(arrow_tail, arrow_head, transform=transform, **arrow_kw) axes.add_patch(p) arrows.append(p) lc = mcollections.LineCollection(streamlines, transform=transform, **line_kw) if use_multicolor_lines: lc.set_array(np.asarray(line_colors)) lc.set_cmap(cmap) lc.set_norm(norm) axes.add_collection(lc) axes.update_datalim(((x.min(), y.min()), (x.max(), y.max()))) axes.autoscale_view(tight=True) ac = matplotlib.collections.PatchCollection(arrows) stream_container = StreamplotSet(lc, ac) return stream_container
def render(self, image_view=False, render_lines=True, line_colour='r', line_style='-', line_width=1, render_markers=True, marker_style='o', marker_size=5, marker_face_colour='r', marker_edge_colour='k', marker_edge_width=1., render_numbering=False, numbers_horizontal_align='center', numbers_vertical_align='bottom', numbers_font_name='sans-serif', numbers_font_size=10, numbers_font_style='normal', numbers_font_weight='normal', numbers_font_colour='k', render_axes=True, axes_font_name='sans-serif', axes_font_size=10, axes_font_style='normal', axes_font_weight='normal', axes_x_limits=None, axes_y_limits=None, axes_x_ticks=None, axes_y_ticks=None, figure_size=(10, 8), label=None): from matplotlib import collections as mc import matplotlib.pyplot as plt # Flip x and y for viewing if points are tied to an image points = self.points[:, ::-1] if image_view else self.points # parse axes limits min_x, min_y = np.min(points, axis=0) max_x, max_y = np.max(points, axis=0) axes_x_limits, axes_y_limits = _parse_axes_limits( min_x, max_x, min_y, max_y, axes_x_limits, axes_y_limits) # get current axes object ax = plt.gca() # Check if graph has edges to be rendered (for example a PointCloud # won't have any edges) if render_lines and np.array(self.edges).shape[0] > 0: # Get edges to be rendered lines = zip(points[self.edges[:, 0], :], points[self.edges[:, 1], :]) # Draw line objects lc = mc.LineCollection(lines, colors=line_colour, linestyles=line_style, linewidths=line_width, cmap=GLOBAL_CMAP, label=label) ax.add_collection(lc) # If a label is defined, it should only be applied to the lines, of # a PointGraph, which represent each one of the labels, unless a # PointCloud is passed in. label = None ax.autoscale() if render_markers: plt.plot(points[:, 0], points[:, 1], linewidth=0, markersize=marker_size, marker=marker_style, markeredgewidth=marker_edge_width, markeredgecolor=marker_edge_colour, markerfacecolor=marker_face_colour, label=label) # set numbering _set_numbering(ax, points, render_numbering=render_numbering, numbers_horizontal_align=numbers_horizontal_align, numbers_vertical_align=numbers_vertical_align, numbers_font_name=numbers_font_name, numbers_font_size=numbers_font_size, numbers_font_style=numbers_font_style, numbers_font_weight=numbers_font_weight, numbers_font_colour=numbers_font_colour) # set axes options _set_axes_options( ax, render_axes=render_axes, inverted_y_axis=image_view, axes_font_name=axes_font_name, axes_font_size=axes_font_size, axes_font_style=axes_font_style, axes_font_weight=axes_font_weight, axes_x_limits=axes_x_limits, axes_y_limits=axes_y_limits, axes_x_ticks=axes_x_ticks, axes_y_ticks=axes_y_ticks) # set equal aspect ratio ax.set_aspect('equal', adjustable='box') # set figure size _set_figure_size(self.figure, figure_size) return self
data_eli.head() # In[4]: %matplotlib inline # uncomment for interactive plot # %matplotlib notebook fontsize = 14 fig, ax = plt.subplots(1, figsize=(12, 10)) line_segments_cap = [[(data_cap.py[i], data_cap.px[i]),(data_cap.py[i+1], data_cap.px[i+1])] for i in range(0, data_cap.shape[0] - 1, 2) ] lc_cap = mc.LineCollection(line_segments_cap, linewidths=1, colors='C0', label=r"spherical cap PLIC elements") ax.add_collection(lc_cap) line_segments_eli = [[(data_eli.py[i], data_eli.px[i]),(data_eli.py[i+1], data_eli.px[i+1])] for i in range(0, data_eli.shape[0] - 1, 2) ] lc_eli = mc.LineCollection(line_segments_eli, linewidths=1, colors='C1', label=r"ellipse PLIC elements") ax.add_collection(lc_eli) ax.autoscale() x = [i[0] for j in line_segments_cap for i in j] y = [i[1] for j in line_segments_cap for i in j] ax.scatter(x, y, marker='x', color='C0', s=30, linewidth=0.5) x = [i[0] for j in line_segments_eli for i in j] y = [i[1] for j in line_segments_eli for i in j] ax.scatter(x, y, marker='x', color='C1', s=30, linewidth=0.5)
def draw(self, with_labels=True, blockade_radius=None, draw_graph=True, draw_half_radius=False): """Draws the entire register. Keyword args: with_labels(bool, default=True): If True, writes the qubit ID's next to each qubit. blockade_radius(float, default=None): The distance (in μm) between atoms below the Rydberg blockade effect occurs. draw_half_radius(bool, default=False): Whether or not to draw the half the blockade radius surrounding each atoms. If `True`, requires `blockade_radius` to be defined. draw_graph(bool, default=True): Whether or not to draw the interaction between atoms as edges in a graph. Will only draw if the `blockade_radius` is defined. Note: When drawing half the blockade radius, we say there is a blockade effect between atoms whenever their respective circles overlap. This representation is preferred over drawing the full Rydberg radius because it helps in seeing the interactions between atoms. """ if self._dim != 2: raise NotImplementedError("Can only draw register layouts in 2D.") pos = np.array(self._coords) diffs = np.max(pos, axis=0) - np.min(pos, axis=0) diffs[diffs < 9] *= 1.5 diffs[diffs < 9] += 2 if blockade_radius and draw_half_radius: diffs[diffs < blockade_radius] = blockade_radius big_side = max(diffs) proportions = diffs / big_side Ls = proportions * min(big_side / 4, 10) # Figsize is, at most, (10,10) fig, ax = plt.subplots(figsize=Ls) ax.scatter(pos[:, 0], pos[:, 1], s=30, alpha=0.7, c='darkgreen') ax.set_xlabel("µm") ax.set_ylabel("µm") ax.axis('equal') ax.spines['right'].set_color('none') ax.spines['top'].set_color('none') if with_labels: for q, coords in zip(self._ids, self._coords): ax.annotate(q, coords, fontsize=12, ha='left', va='bottom') if draw_half_radius: if blockade_radius is None: raise ValueError("Define 'blockade_radius' to draw.") if len(pos) == 1: raise NotImplementedError("Needs more than one atom to draw " "the blockade radius.") delta_um = np.linalg.norm(pos[1] - pos[0]) r_pts = np.linalg.norm( np.subtract(*ax.transData.transform( pos[:2]).tolist())) / delta_um * blockade_radius / 2 # A 'scatter' marker of size s has area pi/4 * s ax.scatter(pos[:, 0], pos[:, 1], s=4 * r_pts**2, alpha=0.1, c='darkgreen') if draw_graph and blockade_radius is not None: epsilon = 1e-9 # Accounts for rounding errors edges = KDTree(pos).query_pairs(blockade_radius * (1 + epsilon)) lines = pos[(tuple(edges), )] lc = mc.LineCollection(lines, linewidths=0.6, colors='grey') ax.add_collection(lc) else: # Only draw central axis lines when not drawing the graph ax.axvline(0, c='grey', alpha=0.5, linestyle=':') ax.axhline(0, c='grey', alpha=0.5, linestyle=':') plt.show()
def add_hlines( self, X=[], Y=[], # X-Y points in the graph. labels=[], legend=[], # Basic Labelling color=None, lw=2, alpha=1.0, # Basic line properties nf=0, na=0, # New axis. To plot in a new axis # TODO: shareX option ax=None, position=[], projection="2d", # Type of plot sharex=None, sharey=None, fontsize=20, fontsizeL=10, fontsizeA=15, # The font for the labels in the axis xlim=None, ylim=None, xlimPad=None, ylimPad=None, # Limits of vision ws=None, Ninit=0, loc="best", dataTransform=None, xaxis_mode=None, yaxis_mode=None, AxesStyle=None, # Automatically do some formatting :) marker=[" ", None, None]): # Management of the figure and properties ax = self.figure_management(nf, na, ax=ax, sharex=sharex, sharey=sharey, projection=projection, position=position) ## Preprocess the data given so that it meets the right format X, Y = self.preprocess_data(X, Y, dataTransform) NpY, NcY = Y.shape plots, plots_typ = self.init_WidgetData(ws) ############### CALL PLOTTING FUNCTION ########################### # X = X.astype(dt.datetime) # self.X = self.X.astype(dt.datetime) X = ul.preprocess_dates(X) self.X = X width_unit = self.get_barwidth(X) width = width_unit * (1 - 0.8) / 2 # TODO: might be wrong to use Npx due to subselection lines = [[(X[i].astype(dt.datetime) - width, Y[i, 0]), (X[i].astype(dt.datetime) + width, Y[i, 0])] for i in range(NpY)] # lines = [[(0, 1), (1, 1)], [(2, 3), (3, 3)], [(1, 2), (1, 3)]] # print mdates.date2num(X[i,0].astype(dt.datetime)), type(mdates.date2num(X[i,0].astype(dt.datetime))) lc = mc.LineCollection(lines, colors="k", linewidths=lw) ax.add_collection(lc) ax.autoscale() ax.margins(0.1) ############### Last setting functions ########################### self.update_legend(legend, NcY, ax=ax, loc=loc) # Update the legend self.set_labels(labels) self.set_zoom(ax=ax, xlim=xlim, ylim=ylim, xlimPad=xlimPad, ylimPad=ylimPad) self.format_xaxis(ax=ax, xaxis_mode=xaxis_mode) self.format_yaxis(ax=ax, yaxis_mode=yaxis_mode) self.apply_style(nf, na, AxesStyle) return ax
# Make some offsets xyo = rs.randn(npts, 2) # Make a list of colors cycling through the default series. colors = [ colors.to_rgba(c) for c in plt.rcParams['axes.prop_cycle'].by_key()['color'] ] fig, axes = plt.subplots(2, 2) fig.subplots_adjust(top=0.92, left=0.07, right=0.97, hspace=0.3, wspace=0.3) ((ax1, ax2), (ax3, ax4)) = axes # unpack the axes col = collections.LineCollection([spiral], offsets=xyo, transOffset=ax1.transData) trans = fig.dpi_scale_trans + transforms.Affine2D().scale(1.0 / 72.0) col.set_transform(trans) # the points to pixels transform # Note: the first argument to the collection initializer # must be a list of sequences of x,y tuples; we have only # one sequence, but we still have to put it in a list. ax1.add_collection(col, autolim=True) # autolim=True enables autoscaling. For collections with # offsets like this, it is neither efficient nor accurate, # but it is good enough to generate a plot that you can use # as a starting point. If you know beforehand the range of # x and y that you want to show, it is better to set them # explicitly, leave out the autolim kwarg (or set it to False), # and omit the 'ax1.autoscale_view()' call below.
def add_topo(self): """ Add topology; nodes and arcs with plotting properties set with plot_settings().""" # Lists used to update plot after manual editing of node positions, not necessary now when possibility # to change bus positions has been removed, but some code changes required to simplify... self.segments_index = [] # node index self.segments = [] # coordinates self.segments_object = [] # plotting object (LineCollection or plot) # buses + labels for s in np.unique(self.bus_set[self.bus_set >= 0]): lw, c = self.bus_lw[s], self.bus_color[s] fs, c2 = self.bus_name_fs[s], self.bus_name_color[s] ind = find(self.bus_set == s) x = self.bus.x.values[ind] y = self.bus.y.values[ind] text = arr([str(s) for s in self.bus.index.values[ind]]) if s == 0: label = '380 kV' elif s == 1: label = '300 kV' else: label = '220 kV or less' # plot buses gid = ['bus%d' % i for i in ind] self.segments_index.append(ind) self.segments.append(np.column_stack((x, y))) self.segments_object.append( self.ax.plot(x, y, ms=lw**2, marker='o', ls='', c=c, zorder=10, label=label, picker=5, gid=gid)[0]) # bus text if fs > 0: dy = lw * self.y_range / 2000 # displacement of text for n in range(len(ind)): self.ax.text(x[n], y[n] + dy, text[n], va='bottom', ha='center', color=c2, size=fs, zorder=15) # lines for s in np.unique(self.line_set[self.line_set >= 0]): ind = find(self.line_set == s) lw, c = self.line_lw[s], self.line_color[s] if self.line_colored is not None: c = self.line_colored[ind] # color depending on some variable if self.line_widthed is not None: lw = self.line_widthed[ ind] # line width depending on some variable # plot lines gid = ['line%d' % i for i in ind] coll = zip(self.line.x.values[ind], self.line.y.values[ind]) segments = [[(x, y) for x, y in zip(xx, yy)] for xx, yy in coll] self.segments.append(segments) lc = mcoll.LineCollection(segments, colors=c, linewidths=lw, gid=gid, zorder=5, picker=self.picker_arc) self.segments_object.append(self.ax.add_collection(lc)) # links lw, c = self.link_lw, self.link_color gid = ['link%d' % i for i in range(len(self.link))] coll = zip(self.link.x.values, self.link.y.values) segments = [[(x, y) for x, y in zip(xx, yy)] for xx, yy in coll] self.segments.append(segments) lc = mcoll.LineCollection(segments, colors=c, linewidths=lw, gid=gid, zorder=5, picker=self.picker_arc) self.segments_object.append(self.ax.add_collection(lc))
def get_collection(self): return mcoll.LineCollection(self.lines, **self.kwargs)
def barchart( self, X=[], Y=[], # X-Y points in the graph. labels=[], legend=[], # Basic Labelling color=None, lw=2, lw2=2, alpha=1.0, # Basic line properties nf=0, na=0, # New axis. To plot in a new axis # TODO: shareX option ax=None, position=[], projection="2d", # Type of plot sharex=None, sharey=None, fontsize=20, fontsizeL=10, fontsizeA=15, # The font for the labels in the axis xlim=None, ylim=None, xlimPad=None, ylimPad=None, # Limits of vision ws=None, Ninit=0, loc="best", dataTransform=None, xaxis_mode=None, yaxis_mode=None, AxesStyle=None # Automatically do some formatting :) ): # Management of the figure and properties ax = self.figure_management(nf, na, ax=ax, sharex=sharex, sharey=sharey, projection=projection, position=position) ## Preprocess the data given so that it meets the right format X, Y = self.preprocess_data(X, Y, dataTransform) NpY, NcY = Y.shape NpX, NcX = Y.shape plots, plots_typ = self.init_WidgetData(ws) ############### CALL PLOTTING FUNCTION ########################### # X = X.astype(dt.datetime) # self.X = self.X.astype(dt.datetime) # print X.shape High, Low, Open, Close = Y[:, 0], Y[:, 1], Y[:, 2], Y[:, 3] X = ul.preprocess_dates(X) self.X = X # print X width_unit = self.get_barwidth(X) dist = width_unit / 2.2 # High-Low linesHL = [[(X[i].astype(dt.datetime), Low[i]), (X[i].astype(dt.datetime), High[i])] for i in range(NpX)] linesO = [[(X[i].astype(dt.datetime) - dist, Open[i]), (X[i].astype(dt.datetime), Open[i])] for i in range(NpX)] linesC = [[(X[i].astype(dt.datetime), Close[i]), (X[i].astype(dt.datetime) + dist, Close[i])] for i in range(NpX)] # lines = [[(0, 1), (1, 1)], [(2, 3), (3, 3)], [(1, 2), (1, 3)]] # print mdates.date2num(X[i,0].astype(dt.datetime)), type(mdates.date2num(X[i,0].astype(dt.datetime))) self.zorder = self.zorder + 1 # Setting the properties colorFinal = self.get_color(color) lcHL = mc.LineCollection(linesHL, colors=colorFinal, linewidths=lw, antialiased=True) lcO = mc.LineCollection(linesO, colors=colorFinal, linewidths=lw2, antialiased=True) lcC = mc.LineCollection(linesC, colors=colorFinal, linewidths=lw2, antialiased=True) ax.add_collection(lcHL) ax.add_collection(lcO) ax.add_collection(lcC) ax.autoscale() # TODO: The zoom is not changed if we do not say it ! # ax.margins(0.1) ############### Last setting functions ########################### self.store_WidgetData(plots_typ, plots) # Store pointers to variables for interaction self.update_legend(legend, NcY, ax=ax, loc=loc) # Update the legend self.set_labels(labels) self.set_zoom(xlim, ylim, xlimPad, ylimPad) self.format_xaxis(ax=ax, xaxis_mode=xaxis_mode) self.format_yaxis(ax=ax, yaxis_mode=yaxis_mode) self.apply_style(nf, na, AxesStyle) # xfmt = mdates.DateFormatter('%b %d') # ax.xaxis.set_major_formatter(xfmt) return ax
def draw_report(title, time_axis, map_values, differences, imbalances, sums, image_file=None, numa_cpus={}): # Transpose heat map data to right axes map_values = np.array(map_values)[:-1, :].transpose() # Group CPU lines by NUMA nodes if numa_cpus: new_order = [] for k, v in numa_cpus.items(): new_order += v map_values = map_values[new_order] # Add blank row to correctly plot all rows with data map_values = np.vstack((map_values, np.zeros(map_values.shape[1]))) cmap = ListedColormap( ['#000000', '#305090', '#40b080', '#f0e020', '#f04010']) boundaries = [-0.5, 0.5, 1.5, 2.5, 3.5, 4.5] norm = BoundaryNorm(boundaries, cmap.N, clip=True) fig, axs = plt.subplots(nrows=3, ncols=1, gridspec_kw=dict(height_ratios=[4, 1, 2]), sharex=True, figsize=(20, 10)) # , constrained_layout=True) fig.subplots_adjust(hspace=0.05) # Draw the main heat map x_grid, y_grid = np.meshgrid(time_axis, range(len(map_values))) mesh = axs[0].pcolormesh(x_grid, y_grid, map_values, vmin=0, vmax=4, cmap=cmap, norm=norm) axs[0].set_xlim(time_axis[0], time_axis[-1]) axs[0].set_ylim([0, map_values.shape[0] - 1]) # Create colorbar cbar = fig.colorbar(mesh, cax=plt.axes([0.95, 0.05, 0.02, 0.9]), extend='max', ticks=range(5)) cbar.ax.set_yticklabels(['0', '1', '2', '3', '4+']) cbar.ax.set_ylabel("Number of tasks on CPU core") plt.subplots_adjust(bottom=0.05, right=0.9, top=0.95, left=0.05) # Draw line with differences axs[1].step(time_axis, differences, where='post', color='black', alpha=0.8) # Draw imbalances for i in imbalances: axs[1].plot(i[0][0], i[0][1], 'rx') lc = mc.LineCollection(imbalances, colors=np.tile((1, 0, 0, 1), (len(imbalances), 1)), linewidths=2) axs[1].add_collection(lc) # Draw line with sums axs[2].step(time_axis, sums, where='post', color='black', alpha=0.8) axs[0].set_ylabel("CPUs") axs[1].set_ylabel("Max difference") axs[2].set_ylabel("Sum of tasks") axs[2].set_xlabel("Timestamp (seconds)") axs[1].set_ylim(bottom=0) axs[1].grid() axs[2].set_ylim(bottom=0) axs[2].grid() # Separate CPUs with lines by NUMA nodes plt.sca(axs[0]) if numa_cpus: axs[0].grid(True, which='major', axis='y', linestyle='--', color='w') axs[0].yaxis.set_minor_locator(MultipleLocator(1)) plt.yticks( range(0, map_values.shape[0] - 1, len(numa_cpus[0])), map(lambda x: "Node " + str(x), range(len(numa_cpus.keys())))) else: axs[0].set_yticks(range(map_values.shape[0] - 1)) plt.title(title) if image_file: plt.savefig(image_file) else: plt.show()
def plot_individual_events(self, fit_err_limit=1000., tau2_range=2.5, title='', pdf=None): P = PH.regular_grid(3, 3, order='columns', figsize=(8., 8.), showgrid=False, verticalspacing=0.1, horizontalspacing=0.12, margins={ 'leftmargin': 0.12, 'rightmargin': 0.12, 'topmargin': 0.03, 'bottommargin': 0.1 }, labelposition=(-0.12, 0.95)) P.figure_handle.suptitle(title) all_evok = self.cell_summary[ 'indiv_evok'] # this is the list of ok events - a 2d list by all_notok = self.cell_summary['indiv_notok'] # print('all evok: ', all_evok) # print('len allevok: ', len(all_evok)) # # # print('all_notok: ', all_notok) # # print('indiv tau1: ', self.cell_summary['indiv_tau1']) # exit(1) trdat = [] trfit = [] trdecfit = [] for itr in range(len(all_evok)): # for each trace for evok in all_evok[itr]: # for each ok event in that trace P.axdict['A'].plot(self.cell_summary['indiv_tau1'][itr][evok], self.cell_summary['indiv_amp'][itr][evok], 'ko', markersize=3) P.axdict['B'].plot(self.cell_summary['indiv_tau2'][itr][evok], self.cell_summary['indiv_amp'][itr][evok], 'ko', markersize=3) P.axdict['C'].plot(self.cell_summary['indiv_tau1'][itr][evok], self.cell_summary['indiv_tau2'][itr][evok], 'ko', markersize=3) P.axdict['D'].plot( self.cell_summary['indiv_amp'][itr][evok], self.cell_summary['indiv_fiterr'][itr][evok], 'ko', markersize=3) P.axdict['H'].plot( self.cell_summary['indiv_tau1'][itr][evok], self.cell_summary['indiv_Qtotal'][itr][evok], 'ko', markersize=3) trdat.append( np.column_stack([ self.cell_summary['indiv_tb'][itr], self.cell_summary['allevents'][itr][evok] ])) #idl = len(self.cell_summary['best_decay_fit'][itr][evok]) trfit.append( np.column_stack([ self.cell_summary['indiv_tb'][itr], -self.cell_summary['best_fit'][itr][evok] ])) trdecfit.append( np.column_stack([ self.cell_summary['indiv_tb'][itr], -self.cell_summary['best_decay_fit'][itr][evok] ])) dat_coll = collections.LineCollection(trdat, colors='k', linewidths=0.5) fit_coll = collections.LineCollection(trfit, colors='r', linewidths=0.25) # decay_fit_coll = collections.LineCollection(trdecfit, colors='c', linewidths=0.3) P.axdict['G'].add_collection(dat_coll) P.axdict['G'].add_collection(fit_coll) # P.axdict['G'].add_collection(decay_fit_coll) n_trdat = [] n_trfit = [] for itr in range(len(all_notok)): for notok in all_notok[itr]: n_trdat.append( np.column_stack([ self.cell_summary['indiv_tb'][itr], self.cell_summary['allevents'][itr][notok] ])) n_trfit.append( np.column_stack([ self.cell_summary['indiv_tb'][itr], -self.cell_summary['best_fit'][itr][notok] ])) P.axdict['D'].plot( self.cell_summary['indiv_amp'][itr][notok], self.cell_summary['indiv_fiterr'][itr][notok], 'ro', markersize=3) n_dat_coll = collections.LineCollection(n_trdat, colors='b', linewidths=0.35) n_fit_coll = collections.LineCollection(n_trfit, colors='y', linewidths=0.25) P.axdict['E'].add_collection(n_dat_coll) P.axdict['E'].add_collection(n_fit_coll) P.axdict['A'].set_xlabel(r'$tau_1$ (ms)') P.axdict['A'].set_ylabel(r'Amp (pA)') P.axdict['B'].set_xlabel(r'$tau_2$ (ms)') P.axdict['B'].set_ylabel(r'Amp (pA)') P.axdict['C'].set_xlabel(r'$\tau_1$ (ms)') P.axdict['C'].set_ylabel(r'$\tau_2$ (ms)') P.axdict['D'].set_xlabel(r'Amp (pA)') P.axdict['D'].set_ylabel(r'Fit Error (cost)') P.axdict['H'].set_xlabel(r'$\tau_1$ (ms)') P.axdict['H'].set_ylabel(r'Qtotal') P.axdict['G'].set_ylim((-100., 20.)) P.axdict['G'].set_xlim((-2., 25.)) P.axdict['E'].set_ylim((-100., 20.)) P.axdict['E'].set_xlim((-2., 25.)) # put in averaged event too # self.cell_summary['averaged'].extend([{'tb': aj.avgeventtb, 'avg': aj.avgevent, 'fit': {'amplitude': aj.Amplitude, # 'tau1': aj.tau1, 'tau2': aj.tau2, 'risepower': aj.risepower}, 'best_fit': aj.avg_best_fit, # 'risetenninety': aj.risetenninety, 'decaythirtyseven': aj.decaythirtyseven}]) aev = self.cell_summary['averaged'] for i in range(len(aev)): P.axdict['F'].plot(aev[i]['tb'], aev[i]['avg'], 'k-', linewidth=0.8) P.axdict['F'].plot(aev[i]['tb'], aev[i]['best_fit'], 'r--', linewidth=0.4) if pdf is None: mpl.show() else: pdf.savefig(dpi=300) mpl.close()
def plot_graph_on_im_speed(G_, im_test_file, figsize=(8, 8), show_endnodes=False, width_key='speed_mph', width_mult=0.07, color_key='speed_mph', color_dict={}, static_color='lime', default_node_size=15, node_alpha=0.5, edge_alpha=0.7, title='', figname='', insert_text='', max_speeds_per_line=12, dpi=300, plt_save_quality=75, ax=None, verbose=False): ''' Overlay graph on image, if width_key == int, use a constant width''' fig_width, fig_height = figsize try: im_cv2 = cv2.imread(im_test_file, 1) img_mpl = cv2.cvtColor(im_cv2, cv2.COLOR_BGR2RGB) except: img_sk = skimage.io.imread(im_test_file) # make sure image is h,w,channels (assume less than 20 channels) if (len(img_sk.shape) == 3) and (img_sk.shape[0] < 20): img_mpl = np.moveaxis(img_sk, 0, -1) else: img_mpl = img_sk h, w = img_mpl.shape[:2] node_x, node_y, lines, widths, title_vals, colors = [], [], [], [], [], [] # get edge data for i, (u, v, edge_data) in enumerate(G_.edges(data=True)): color_key_val = int(edge_data[color_key]) # if type(edge_data['geometry_pix']) if type(edge_data['geometry_pix']) == str: coords = list(shapely.wkt.loads(edge_data['geometry_pix']).coords) else: coords = list(edge_data['geometry_pix'].coords) if verbose: # (i % 100) == 0: print("\n", i, u, v, edge_data) print("edge_data:", edge_data) print(" coords:", coords) lines.append(coords) node_x.append(coords[0][0]) node_x.append(coords[-1][0]) node_y.append(coords[0][1]) node_y.append(coords[-1][1]) if type(width_key) == str: if verbose: print("edge_data[width_key]:", edge_data[width_key]) width = max(1, int(np.rint(edge_data[width_key] * width_mult))) title_vals.append(int(np.rint(edge_data[width_key]))) else: width = width_key widths.append(width) # get colors if len(color_dict) == 0: colors.append(static_color) else: colors.append(color_dict[color_key_val]) if not ax: fig, ax = plt.subplots(1, 1, figsize=figsize) ax.imshow(img_mpl) # plot nodes? if show_endnodes: endnode_color = 'red' ax.scatter(node_x, node_y, color=endnode_color, s=default_node_size, alpha=node_alpha) # plot segments # print (lines) lc = mpl_collections.LineCollection(lines, colors=colors, linewidths=widths, alpha=edge_alpha, zorder=2) ax.add_collection(lc) ax.set_yticklabels([]) ax.set_xticklabels([]) ax.set_yticks([]) ax.set_xticks([]) #ax.axis('off') if len(title) > 0: # plt.suptitle(title) ax.set_title(title, fontsize=32) plt.tight_layout() #print("title:", title) if len(title): plt.subplots_adjust(top=.95) # plt.subplots_adjust(left=1, bottom=1, right=1, top=1, wspace=5, hspace=5) if len(insert_text) > 0: ax.text(0.02, 0.02, insert_text, fontsize=30, color='white', transform=ax.transAxes) # set dpi to approximate native resolution if verbose: print("img_mpl.shape:", img_mpl.shape) desired_dpi = int(np.max(img_mpl.shape) / np.max(figsize)) if verbose: print("desired dpi:", desired_dpi) # # max out dpi at 3500 # dpi = int(np.min([3500, desired_dpi])) # update dpi, if image if img_mpl is not None: # mpl can handle a max of 2^29 pixels, or 23170 on a side # recompute max_dpi max_dpi = int(23000 / max(figsize)) h, w = img_mpl.shape[:2] # try to set dpi to native resolution of imagery desired_dpi = max(dpi, 1.0 * h / fig_height) #desired_dpi = max(default_dpi, int( np.max(im.shape) / max(fig_height, fig_width) ) ) dpi = int(np.min([max_dpi, desired_dpi ])) if verbose: print("plot dpi:", dpi) if figname: plt.savefig(figname, dpi=dpi, quality=plt_save_quality) return ax
def plot_graph_on_im_yuge(G_, im_test_file, figsize=(12,12), show_endnodes=False, width_key='inferred_speed_mps', width_mult=0.125, default_node_size=15, node_color='#0086CC', # cosmiq logo color (blue) edge_color='#00a6ff', #node_color='#66ccff', #edge_color='#999999', node_edgecolor='none', title='', figname='', max_speeds_per_line=12, line_alpha=0.5, node_alpha=0.6, default_dpi=300, plt_save_quality=75, ax=None, verbose=True, super_verbose=False): ''' COPIED VERBATIM FROM APLS_TOOLS.PY Overlay graph on image, if width_key == int, use a constant width ''' # set dpi to approximate native resolution # mpl can handle a max of 2^29 pixels, or 23170 on a side # recompute max_dpi max_dpi = int(23000 / max(figsize)) try: im_cv2 = cv2.imread(im_test_file, 1) img_mpl = cv2.cvtColor(im_cv2, cv2.COLOR_BGR2RGB) except: img_sk = skimage.io.imread(im_test_file) # make sure image is h,w,channels (assume less than 20 channels) if (len(img_sk.shape) == 3) and (img_sk.shape[0] < 20): img_mpl = np.moveaxis(img_sk, 0, -1) else: img_mpl = img_sk h, w = img_mpl.shape[:2] # make figsize proportional to shape if h > w: figsize = (figsize[1] * 1.*w/h, figsize[1]) elif w > h: figsize = (figsize[0], figsize[0] * 1.*h/w) else: pass if h > 10000 or w > 10000: figsize = (2 * figsize[0], 2 * figsize[1]) max_dpi = int(23000 / max(figsize)) if verbose: print("img_mpl.shape: " + str(img_mpl.shape)) desired_dpi = max(default_dpi, int( np.max(img_mpl.shape) / np.max(figsize)) ) if verbose: print("desired dpi: " + str(desired_dpi)) # max out dpi at 3500 dpi = int(np.min([max_dpi, desired_dpi ])) if verbose: print("figsize: " + str(figsize)) print("plot dpi: " + str(dpi)) node_x, node_y, lines, widths, title_vals = [], [], [], [], [] #node_set = set() x_set, y_set = set(), set() # get edge data for i,(u, v, edge_data) in enumerate(G_.edges(data=True)): #if type(edge_data['geometry_pix']) coords = list(edge_data['geometry_pix'].coords) if super_verbose: #(i % 100) == 0: print("\n" + str(i) + " " + str(u) + " " + str(v) + " " \ + str(edge_data)) print("edge_data: " + str(edge_data)) #print(" edge_data['geometry'].coords", edge_data['geometry'].coords) print(" coords: " + str(coords)) lines.append( coords ) # point 0 xp = coords[0][0] yp = coords[0][1] if not ((xp in x_set) and (yp in y_set)): node_x.append(xp) x_set.add(xp) node_y.append(yp) y_set.add(yp) # point 1 xp = coords[-1][0] yp = coords[-1][1] if not ((xp in x_set) and (yp in y_set)): node_x.append(xp) x_set.add(xp) node_y.append(yp) y_set.add(yp) # if u not in node_set: # node_x.append( coords[0][0] ) # node_y.append( coords[0][1] ) # node_set.add(u) # if v not in node_set: # node_x.append( coords[-1][0] ) # node_y.append( coords[-1][1] ) # node_set.add(v) if type(width_key) == str: if super_verbose: print("edge_data[width_key]: " + str(edge_data[width_key])) width = int(np.rint(edge_data[width_key] * width_mult)) title_vals.append(int(np.rint( edge_data[width_key] ))) else: width = width_key widths.append(width) # get nodes if not ax: fig, ax = plt.subplots(1,1, figsize=figsize) ax.imshow(img_mpl) # plot segments # scale widths with dpi widths = (default_dpi / float(dpi)) * np.array(widths) lc = mpl_collections.LineCollection(lines, colors=edge_color, linewidths=widths, alpha=line_alpha)#, #zorder=2) ax.add_collection(lc) # plot nodes? if show_endnodes: # scale size with dpi node_size = max(0.01, (default_node_size * default_dpi / float(dpi))) #node_size = 3 if verbose: print("node_size: " + str(node_size)) ax.scatter(node_x, node_y, c=node_color, s=node_size, alpha=node_alpha, #linewidths=None, edgecolor=node_edgecolor, zorder=1, #marker='o' #'.' # marker='o' ) ax.axis('off') # title if len(title_vals) > 0: if verbose: print("title_vals: " + str(title_vals)) title_strs = np.sort(np.unique(title_vals)).astype(str) # split title str if it's too long if len(title_strs) > max_speeds_per_line: # construct new title str n, b = max_speeds_per_line, title_strs title_strs = np.insert(b, range(n, len(b), n), "\n") #title_strs = '\n'.join(s[i:i+ds] for i in range(0, len(s), ds)) if verbose: print("title_strs: " + str(title_strs)) title_new = title + '\n' \ + width_key + " = " + " ".join(title_strs) else: title_new = title if title: #plt.suptitle(title) ax.set_title(title_new) plt.tight_layout() if title: plt.subplots_adjust(top=0.96) #plt.subplots_adjust(left=1, bottom=1, right=1, top=1, wspace=5, hspace=5) if figname: print("Saving to: " + str(figname)) if dpi > 1000: plt_save_quality = 50 plt.savefig(figname, dpi=dpi, quality=plt_save_quality) return ax
""" plt.figure() #plt.plot(ts[:50], 'r.') #plt.plot(predicted_shifts[:50], 'b.') plt.plot(ts[:50].reshape(50), predicted_shifts[:50].reshape(50) plt.legend(['Target shift', 'Predicted shift']) plt.xlabel('Sample') plt.ylabel('Shift amount') plt.show() """ # How f*****g hard can it be to plot a vertical line between two points... # Apparently impossible, f**k this so much from matplotlib import collections as matcoll x = [] lines = [] for i in range(100): pair = [(i, ts[i]), (i, predicted_shifts[i])] lines.append(pair) linecoll = matcoll.LineCollection(lines, colors='k') fig, ax = plt.subplots() ax.plot(ts[:100], 'r.') ax.plot(predicted_shifts[:100], 'b.') plt.legend(['Target shift', 'Predicted shift']) ax.add_collection(linecoll)
def create_artists(self, legend, orig_handle, xdescent, ydescent, width, height, fontsize, trans): plotlines, caplines, barlinecols = orig_handle xdata, xdata_marker = self.get_xdata(legend, xdescent, ydescent, width, height, fontsize) ydata = np.full_like(xdata, (height - ydescent) / 2) legline = Line2D(xdata, ydata) xdata_marker = np.asarray(xdata_marker) ydata_marker = np.asarray(ydata[:len(xdata_marker)]) xerr_size, yerr_size = self.get_err_size(legend, xdescent, ydescent, width, height, fontsize) legline_marker = Line2D(xdata_marker, ydata_marker) # when plotlines are None (only errorbars are drawn), we just # make legline invisible. if plotlines is None: legline.set_visible(False) legline_marker.set_visible(False) else: self.update_prop(legline, plotlines, legend) legline.set_drawstyle('default') legline.set_marker('none') self.update_prop(legline_marker, plotlines, legend) legline_marker.set_linestyle('None') if legend.markerscale != 1: newsz = legline_marker.get_markersize() * legend.markerscale legline_marker.set_markersize(newsz) handle_barlinecols = [] handle_caplines = [] if orig_handle.has_xerr: verts = [((x - xerr_size, y), (x + xerr_size, y)) for x, y in zip(xdata_marker, ydata_marker)] coll = mcoll.LineCollection(verts) self.update_prop(coll, barlinecols[0], legend) handle_barlinecols.append(coll) if caplines: capline_left = Line2D(xdata_marker - xerr_size, ydata_marker) capline_right = Line2D(xdata_marker + xerr_size, ydata_marker) self.update_prop(capline_left, caplines[0], legend) self.update_prop(capline_right, caplines[0], legend) capline_left.set_marker("|") capline_right.set_marker("|") handle_caplines.append(capline_left) handle_caplines.append(capline_right) if orig_handle.has_yerr: verts = [((x, y - yerr_size), (x, y + yerr_size)) for x, y in zip(xdata_marker, ydata_marker)] coll = mcoll.LineCollection(verts) self.update_prop(coll, barlinecols[0], legend) handle_barlinecols.append(coll) if caplines: capline_left = Line2D(xdata_marker, ydata_marker - yerr_size) capline_right = Line2D(xdata_marker, ydata_marker + yerr_size) self.update_prop(capline_left, caplines[0], legend) self.update_prop(capline_right, caplines[0], legend) capline_left.set_marker("_") capline_right.set_marker("_") handle_caplines.append(capline_left) handle_caplines.append(capline_right) artists = [ *handle_barlinecols, *handle_caplines, legline, legline_marker, ] for artist in artists: artist.set_transform(trans) return artists
def plot0(self, nrow, ncol, clist): df_avg = self.df_avg ux2 = self.ux2 segs = self.segs e0 = self.e0 e1 = self.e1 map0 = self.map0 pfac = 2.8 ww = pfac * ncol hh = pfac * nrow fig, axes = plt.subplots(nrow, ncol, figsize=(ww, hh)) axes = axes.flatten() for i, ax in enumerate(axes): if i >= len(clist): ax.set_xticklabels([]) ax.set_yticklabels([]) ax.set_xticks([]) ax.set_yticks([]) ax.spines['left'].set_visible(False) ax.spines['right'].set_visible(False) ax.spines['bottom'].set_visible(False) ax.spines['top'].set_visible(False) continue color = df_avg.loc[map0, clist[i]].values vmax = np.amax(color) ecolor0 = color[e0] ecolor1 = color[e1] ecolor = .5 * (ecolor0 + ecolor1) ecolor = ecolor / vmax pnts = ax.scatter(ux2[:, 0], ux2[:, 1], s=15, c=color, cmap=mpl.cm.jet, vmin=0.0) rgba = mpl.cm.jet(ecolor) seg_col = mc.LineCollection(segs, color=rgba) #seg_col = mc.LineCollection(segs) fig.colorbar(pnts, ax=ax) ax.add_collection(seg_col) ax.set_xlabel(clist[i]) #ax.axis('equal') ax.set_xticklabels([]) ax.set_yticklabels([]) ax.set_xticks([]) ax.set_yticks([]) ax.spines['left'].set_visible(False) ax.spines['right'].set_visible(False) ax.spines['bottom'].set_visible(False) ax.spines['top'].set_visible(False) #plt.savefig("markers1.pdf",format='pdf',bbox_inches='tight') #plt.savefig("receptors_homing.pdf",format='pdf',bbox_inches='tight') plt.tight_layout() plt.show()
def bowtieRegions(p1, p2, bbox="envelope", lbl='1'): # calculate default bounding box if bbox == "envelope": bbox1 = p1['geometry'].envelope.exterior.coords bbox2 = p2['geometry'].envelope.exterior.coords #bbox1 = p1.envelope.exterior.coords #bbox2 = p2.envelope.exterior.coords minx = min(bbox1[0][0], bbox2[0][0]) miny = min(bbox1[0][1], bbox2[0][1]) maxx = max(bbox1[2][0], bbox2[2][0]) maxy = max(bbox1[2][1], bbox2[2][1]) bbox = Polygon([(minx, miny), (maxx, miny), (maxx, maxy), (minx, maxy)]) else: minx, miny, maxx, maxy = bbox.bounds # make perimeter segments explicit bbox_lines = { 'top': [(minx, maxy), (maxx, maxy)], 'bottom': [(minx, miny), (maxx, miny)], 'left': [(minx, maxy), (minx, miny)], 'right': [(maxx, maxy), (maxx, miny)] } #### # get original polygon and convex hull coordinates coords1 = p1['geometry'].convex_hull.exterior.coords coords2 = p2['geometry'].convex_hull.exterior.coords coords1_lst = p1['geometry'].exterior.coords[:] coords2_lst = p2['geometry'].exterior.coords[:] # calculate the vertices of the tangent lines rr = Bowties.rrPolyPoly(coords1, coords2) ll = Bowties.llPolyPoly(coords1, coords2) lr = Bowties.lrPolyPoly(coords1, coords2) rl = Bowties.rlPolyPoly(coords1, coords2) # get the initial points of tangent with the reference objects p1_ll = ll[0] p2_ll = ll[1] p1_lr = lr[0] p2_lr = lr[1] p1_rr = rr[0] p2_rr = rr[1] p1_rl = rl[0] p2_rl = rl[1] # get the points at the box perimeter. First just pick intersections of each line with the bbox lines ll_bb1, ll_bb2 = bbox_intersection(ll, bbox_lines) lr_bb1, lr_bb2 = bbox_intersection(lr, bbox_lines) rr_bb1, rr_bb2 = bbox_intersection(rr, bbox_lines) rl_bb1, rl_bb2 = bbox_intersection(rl, bbox_lines) # get the intersections between the tangent lines if p1_ll == p1_lr: ll_lr = p1_ll else: ll_lr = intersection(ll, lr) if p2_ll == p2_rl: ll_rl = p2_ll else: ll_rl = intersection(ll, rl) # lr_rl = intersection(lr, rl) if p2_rr == p2_lr: rr_lr = p2_rr else: rr_lr = intersection(rr, lr) if p1_rr == p1_rl: rr_rl = p1_rr else: rr_rl = intersection(rr, rl) # arrange the points on the perimeter in ccw order to correctly assign corner points perimeter = [ ll_bb1, ll_bb2, lr_bb1, lr_bb2, rr_bb1, rr_bb2, rl_bb1, rl_bb2 ] perimeter.extend(bbox.exterior.coords[:-1]) perimeter_array = np.asarray(perimeter) cn = perimeter_array.mean(axis=0) angles = np.arctan2(perimeter_array[:, 1] - cn[1], perimeter_array[:, 0] - cn[0]) perimeter_array = perimeter_array[np.argsort(angles)] perimeter = perimeter_array.tolist() # finally put together the regions # we pack the initial coordinate list in dictionary to simplify the code # we must make sure that the coordinates are all listed in ccw order and coords[0] == coords[-1] regions = { 'back': [rl_bb1, rr_rl, p1_rr, p1_ll, ll_lr, lr_bb1, rl_bb1], 'front': [rl_bb2, ll_rl, p2_ll, p2_rr, rr_lr, lr_bb2, rl_bb2], 'between': [ p1_rl, p1_rr, rr_rl, rr_lr, p2_rr, p2_lr, p2_rl, p2_ll, ll_rl, ll_lr, p1_ll, p1_lr, p1_rl ], 'left': [lr_bb1, ll_lr, ll_rl, rl_bb2, lr_bb1], 'right': [lr_bb2, rr_lr, rr_rl, rl_bb1, lr_bb2] } # first let's get rid of duplicates for region, vertices in regions.items(): vert_groups = [] idx = 0 while idx < len(vertices): vert_group = [idx] dup_idx = idx while vertices[(dup_idx + 1) % len(vertices)] == vertices[idx]: dup_idx = (dup_idx + 1) % len(vertices) if dup_idx > idx: idx = dup_idx + 1 else: idx += 1 vert_group.append(dup_idx) vert_groups.append(vert_group) vert_groups = [ vertices[vert_group[0]] for vert_group in vert_groups ] regions[region] = vert_groups # then find out which polygons contain the corner vertices and add them - this is where we need the ccw ordering def addVertices(region, vertices): perim_pos1 = perimeter.index(list(regions[region][-2])) perim_pos2 = perimeter.index(list(regions[region][-1])) perim_pos = (perim_pos1 + 1) % len(perimeter) while (perim_pos != perim_pos2): regions[region].insert(-1, tuple(perimeter[perim_pos])) perim_pos = (perim_pos + 1) % len(perimeter) for region, vertices in regions.items(): if region != 'between': addVertices(region, vertices) # finally append vertices from the polygons onto the boundary of the appropriate regions # the back region first if p1_ll != p1_rr: back_rr_idx = regions['back'].index(p1_rr) p1_ll_idx = coords1_lst.index(p1_ll) p1_rr_idx = coords1_lst.index(p1_rr) nv = (p1_ll_idx + 1) % len(coords1_lst) insert_pt = (back_rr_idx + 1) while nv != p1_rr_idx: regions['back'].insert(insert_pt, coords1_lst[nv]) nv = (nv + 1) % len(coords1_lst) # the front region next if p2_ll != p2_rr: front_ll_idx = regions['front'].index(p2_ll) p2_ll_idx = coords2_lst.index(p2_ll) p2_rr_idx = coords2_lst.index(p2_rr) nv = (p2_rr_idx + 1) % len(coords2_lst) insert_pt = (front_ll_idx + 1) while nv != p2_ll_idx: regions['front'].insert(insert_pt, coords2_lst[nv]) nv = (nv + 1) % len(coords2_lst) # the middle region last - there will be at most 6 boundary pieces to check 3 at each ref. polygon # start at p1 if p1_lr != p1_rl: mid_p1_lr_idx = regions['between'].index(p1_lr) p1_rl_idx = coords1_lst.index(p1_rl) p1_lr_idx = coords1_lst.index(p1_lr) nv = (p1_rl_idx + 1) % len(coords1_lst) insert_pt = (mid_p1_lr_idx + 1) while nv != p1_lr_idx: regions['between'].insert(insert_pt, coords1_lst[nv]) nv = (nv + 1) % len(coords1_lst) if p1_rr != p1_rl: mid_p1_rl_idx = regions['between'].index(p1_rl) p1_rl_idx = coords1_lst.index(p1_rl) p1_rr_idx = coords1_lst.index(p1_rr) nv = (p1_rr_idx + 1) % len(coords1_lst) insert_pt = (mid_p1_rl_idx + 1) while nv != p1_rl_idx: regions['between'].insert(insert_pt, coords1_lst[nv]) nv = (nv + 1) % len(coords1_lst) if p1_ll != p1_lr: mid_p1_ll_idx = regions['between'].index(p1_ll) p1_ll_idx = coords1_lst.index(p1_ll) p1_lr_idx = coords1_lst.index(p1_lr) nv = (p1_lr_idx + 1) % len(coords1_lst) insert_pt = (mid_p1_ll_idx + 1) while nv != p1_ll_idx: regions['between'].insert(insert_pt, coords1_lst[nv]) nv = (nv + 1) % len(coords1_lst) # then do p2 p2_rl_lr = [p2_lr, p2_rl] if p2_lr != p2_rl: mid_p2_lr_idx = regions['between'].index(p2_lr) p2_rl_idx = coords2_lst.index(p2_rl) p2_lr_idx = coords2_lst.index(p2_lr) nv = (p2_rl_idx + 1) % len(coords2_lst) insert_pt = (mid_p2_lr_idx + 1) ct = 0 while nv != p2_lr_idx: regions['between'].insert(insert_pt, coords2_lst[nv]) if ct < 100: ct += 1 p2_rl_lr.insert(1, coords2_lst[nv]) nv = (nv + 1) % len(coords2_lst) p2_lr_rr = [p2_rr, p2_lr] if p2_rr != p2_lr: mid_p2_rr_idx = regions['between'].index(p2_rr) p2_lr_idx = coords2_lst.index(p2_lr) p2_rr_idx = coords2_lst.index(p2_rr) nv = (p2_lr_idx + 1) % len(coords2_lst) insert_pt = (mid_p2_rr_idx + 1) ct = 0 while nv != p2_rr_idx: regions['between'].insert(insert_pt, coords2_lst[nv]) if ct < 100: ct += 1 p2_lr_rr.insert(1, coords2_lst[nv]) nv = (nv + 1) % len(coords2_lst) p2_ll_rl = [p2_rl, p2_ll] if p2_ll != p2_rl: mid_p2_rl_idx = regions['between'].index(p2_rl) p2_ll_idx = coords2_lst.index(p2_ll) p2_rl_idx = coords2_lst.index(p2_rl) nv = (p2_ll_idx + 1) % len(coords2_lst) insert_pt = (mid_p2_rl_idx + 1) ct = 0 while nv != p2_rl_idx: regions['between'].insert(insert_pt, coords2_lst[nv]) if ct < 100: ct += 1 p2_ll_rl.insert(1, coords2_lst[nv]) nv = (nv + 1) % len(coords2_lst) for region, geom_coords in regions.items(): regions[region] = Polygon(geom_coords) # last step is to add the original polygons to the tiles regions['p1'] = p1['geometry'] regions['p2'] = p2['geometry'] ########################## HERE ON JUST PLOTTING FOR DEBUG ########################## if True: #p1['attributes']['ssm_id'] in roi and p2['attributes']['ssm_id'] in roi: lines = [p2_rl_lr, p2_lr_rr, p2_ll_rl] lc = mc.LineCollection(lines, linewidths=1.5, colors=["cyan", "indigo", "fuchsia"]) else: lines = [ rl, [rl_bb1, rl_bb2], [lr_bb1, lr_bb2], [ll_bb1, ll_bb2], [rr_bb1, rr_bb2] ] lc = mc.LineCollection(lines, linewidths=1.5) # plot ridges with nullified vertices to see # fig, ax = plt.subplots() # fig.set_size_inches(10, 10) ## lc = mc.LineCollection(lines, linewidths=1.5) ## polys = [bbox.exterior.coords,regions['back'],regions['front'],regions['between'],regions['left'],regions['right'],p1['geometry'].exterior.coords, p2['geometry'].exterior.coords] # polys = [bbox.exterior.coords,regions['back'].exterior.coords,regions['front'].exterior.coords,regions['between'].exterior.coords,p1['geometry'].exterior.coords, p2['geometry'].exterior.coords] # pc = mc.PolyCollection(polys, facecolors=["white","grey","brown","gold","red","green"], linewidths=1.5) # # plt.annotate( 'p1_rl', xy=rl[0], xytext=(rl[0][0],rl[0][1])) # plt.annotate( 'p2_rl', xy=rl[1], xytext=(rl[1][0],rl[1][1])) # plt.annotate( 'p1_lr', xy=lr[0], xytext=(lr[0][0],lr[0][1])) # plt.annotate( 'p2_lr', xy=lr[1], xytext=(lr[1][0],lr[1][1])) # plt.annotate( 'p1_ll', xy=ll[0], xytext=(ll[0][0],ll[0][1])) # plt.annotate( 'p2_ll', xy=ll[1], xytext=(ll[1][0],ll[1][1])) # plt.annotate( 'p1_rr', xy=rr[0], xytext=(rr[0][0],rr[0][1])) # plt.annotate( 'p2_rr', xy=rr[1], xytext=(rr[1][0],rr[1][1])) # # plt.annotate( 'll_bb1', xy=ll_bb1, xytext=(ll_bb1[0],ll_bb1[1])) # plt.annotate( 'll_bb2', xy=ll_bb2, xytext=(ll_bb2[0],ll_bb2[1])) # plt.annotate( 'lr_bb1', xy=lr_bb1, xytext=(lr_bb1[0],lr_bb1[1])) # plt.annotate( 'lr_bb2', xy=lr_bb2, xytext=(lr_bb2[0],lr_bb2[1])) # plt.annotate( 'rr_bb1', xy=rr_bb1, xytext=(rr_bb1[0],rr_bb1[1])) # plt.annotate( 'rr_bb2', xy=rr_bb2, xytext=(rr_bb2[0],rr_bb2[1])) # plt.annotate( 'rl_bb1', xy=rl_bb1, xytext=(rl_bb1[0],rl_bb1[1])) # plt.annotate( 'rl_bb2', xy=rl_bb2, xytext=(rl_bb2[0],rl_bb2[1])) # # ax.add_collection(lc) # ax.add_collection(pc) ## ax.scatter(np.array(coords1)[:,0], np.array(coords1)[:,1], s=0.5, marker='x', color="red") ## ax.scatter(np.array(coords2)[:,0], np.array(coords2)[:,1], s=0.5, marker='x', color="blue") # #ax.autoscale() # ax.margins(0.1) # #plt.savefig('tangents_matplt_'+p1['attributes']['ssm_id']+'_'+p2['attributes']['ssm_id']+'_'+lbl+'.svg') # plt.show() # print(p1['attributes']['ssm_id']+' is_ccw?',p1['geometry'].exterior.is_ccw) # print(p2['attributes']['ssm_id']+' is_ccw?',p1['geometry'].exterior.is_ccw) plotTiles = [] try: for pid, polygon in regions.items(): plotTiles.append({ 'attributes': { 'feat_type': pid }, 'geometry': Polygon(polygon) }) except Exception as e: print('Region:', pid, '-- bad polygon', polygon) print(e.__dict__) lbl = 'tangent_tiles_' + p1['attributes']['ssm_id'] + '_' + p2[ 'attributes']['ssm_id'] + '_' + lbl #plotGPD(plotTiles, lbl) #UNCOMMENT HERE ########################## END OF DEBUG PLOTS ########################## # return our computed tiles return regions
xmax = max([ind.location[0] for ind in ts.individuals()]) ymax = max([ind.location[1] for ind in ts.individuals()]) ax.set_xlim(0, xmax) ax.set_ylim(0, ymax) # colors colormap = lambda x: plt.get_cmap("cool")(x/max(ts.individual_ages)) locs = ts.individual_locations inds = ts.individuals_by_time(num_gens) next_inds = ts.individuals_by_time(num_gens - 1) circles = ax.scatter(locs[inds, 0], locs[inds, 1], s=10, edgecolors=colormap([0 for _ in inds]), facecolors='none') filled = ax.scatter(locs[next_inds, 0], locs[next_inds, 1], s=10, facecolors=colormap([0 for _ in next_inds]), edgecolors='none') lc = cs.LineCollection([], colors='black', linewidths=0.5) ax.add_collection(lc) def update(frame): inds = ts.individuals_by_time(frame) next_inds = ts.individuals_by_time(frame - 1) circles.set_offsets(locs[inds,:]) filled.set_offsets(locs[next_inds,:]) # color based on age so far circles.set_color(colormap(ts.individuals_age(frame)[inds])) filled.set_color(colormap(ts.individuals_age(frame)[next_inds])) if frame > 0: new_inds = inds[ts.individuals_age(frame)[inds] == 0] pcs = ts.individual_parents(new_inds, time=frame) lc.set_paths([locs[pc,:] for pc in pcs]) return circles, filled, lc
def draw_bearing_correlogram(data: numpy.ndarray, title: str = "", symmetric: bool = True, alpha: float = 0.05, point_style: Optional[GradientPointStyle] = None, figoutput: Optional[FigOutput] = None): fig, axs = start_figure(figoutput, polar=True) # column order is: min_scale, max_scale, bearing, # pairs, expected, observed, sd, z, prob _, ncols = data.shape mindist_col = 0 b_col = 2 exp_col = 4 obs_col = 5 p_col = ncols - 1 dist_classes = sorted(set(data[:, mindist_col])) n_dists = len(dist_classes) deviation = data[:, obs_col] - data[:, exp_col] # one circle for each dist class, by ordinal rank, representing the expected value for that class base_circle = numpy.array([dist_classes.index(row[0]) + 1 for row in data]) # the radius of each point is its base circle plus its deviation from its expectation r = base_circle + deviation # the angle (theta) is just the bearing that was tested theta = numpy.radians(data[:, b_col]) if point_style is None: point_style = GradientPointStyle() pnt_sizes = [] edges = [] for p in data[:, p_col]: if p <= alpha: pnt_sizes.append(point_style.size) edges.append(point_style.edge_color) else: pnt_sizes.append(point_style.ns_size) edges.append(point_style.ns_edge_color) # need to normalize values for automatic color-coding if data[0, exp_col] == 1: # Geary's c normalize = colors.Normalize( vmin=0, vmax=2) # technically larger than this, but should suffice else: # Moran's I normalize = colors.Normalize(vmin=-1, vmax=1) cmap = cm.get_cmap(point_style.colormap) p_colors = cmap(normalize(data[:, obs_col])) if symmetric: r = numpy.append(r, r) theta = numpy.append(theta, theta + pi) pnt_sizes = numpy.append(pnt_sizes, pnt_sizes) p_colors = numpy.reshape(numpy.append(p_colors, p_colors), (-1, 4)) base_circle = numpy.append(base_circle, base_circle) edges = edges + edges drop_lines = [[(theta[i], base_circle[i]), (theta[i], r[i])] for i in range(len(r))] drop_collection = collections.LineCollection(drop_lines, colors="silver", zorder=1) axs.add_collection(drop_collection) axs.scatter(theta, r, facecolor=p_colors, edgecolor=edges, zorder=3, s=pnt_sizes, alpha=point_style.alpha, marker=point_style.marker, linewidths=point_style.edge_width) pyplot.yticks(numpy.arange(1, n_dists + 1)) axs.set_yticklabels([]) axs.set_ylim(0, n_dists + 1) if not symmetric: axs.set_xlim(0, pi) pyplot.colorbar(cm.ScalarMappable(norm=normalize, cmap=cmap), ax=axs) finalize_figure(fig, axs, figoutput, title)
def overlay_skeleton_2d_class(skeleton, *, image_cmap='gray', skeleton_color_source='path_means', skeleton_colormap='viridis', vmin=None, vmax=None, axes=None): """Plot the image, and overlay the skeleton over it. Parameters ---------- skeleton : skan.Skeleton object The input skeleton, which contains both the skeleton and the source image. Other Parameters ---------------- image_cmap : matplotlib colormap name or object, optional The colormap to use for the input image. Defaults to grayscale. skeleton_color_source : string or callable, optional The name of the method to use for the skeleton edge color. See the documentation of `skan.Skeleton` for valid choices. Most common choices would be: - path_means: the mean value of the skeleton along each path. - path_lengths: the length of each path. - path_stdev: the standard deviation of pixel values along the path. Alternatively, a callable can be provided that takes as input a Skeleton object and outputs a list of floating point values of the same length as the number of paths. skeleton_colormap : matplotlib colormap name or object, optional The colormap for the skeleton values. vmin, vmax : float, optional The minimum and maximum values for the colormap. Use this to pin the colormapped values to a certain range. axes : matplotlib Axes object, optional An Axes object on which to draw. If `None`, a new one is created. Returns ------- axes : matplotlib Axes object The Axes on which the plot is drawn. mappable : matplotlib ScalarMappable object The mappable values corresponding to the line colors. This can be used to create a colorbar for the plot. """ image = skeleton.source_image if axes is None: fig, axes = plt.subplots() axes.imshow(image, cmap=image_cmap) if callable(skeleton_color_source): values = skeleton_color_source(skeleton) elif hasattr(skeleton, skeleton_color_source): values = getattr(skeleton, skeleton_color_source)() else: raise ValueError('Unknown skeleton color source: %s. Provide an ' 'attribute of skan.csr.Skeleton or a callable.' % skeleton_color_source) cmap = plt.get_cmap(skeleton_colormap, min(len(np.unique(values)), 256)) if vmin is None: vmin = np.min(values) if vmax is None: vmax = np.max(values) mapping_values = (values - vmin) / (vmax - vmin) mappable = plt.cm.ScalarMappable(plt.Normalize(vmin, vmax), cmap) mappable._A = mapping_values colors = cmap(mapping_values) coordinates = [ skeleton.path_coordinates(i)[:, ::-1] for i in range(skeleton.n_paths) ] linecoll = collections.LineCollection(coordinates, colors=colors) axes.add_collection(linecoll) return axes, mappable
def eqplot(eq, ax=None, x=None, y=None, z=None, **kwargs): """ Plot the result of an equilibrium calculation. The type of plot is controlled by the degrees of freedom in the equilibrium calculation. Parameters ---------- eq : xarray.Dataset Result of equilibrium calculation. ax : matplotlib.Axes Default axes used if not specified. x : StateVariable, optional y : StateVariable, optional z : StateVariable, optional kwargs : kwargs Passed to `matplotlib.pyplot.scatter`. Returns ------- matplotlib AxesSubplot """ conds = OrderedDict([ (_map_coord_to_variable(key), unpack_condition(np.asarray(value))) for key, value in sorted(eq.coords.items(), key=str) if (key == 'T') or (key == 'P') or (key.startswith('X_')) ]) indep_comps = sorted([ key for key, value in conds.items() if isinstance(key, v.Composition) and len(value) > 1 ], key=str) indep_pots = [ key for key, value in conds.items() if ((key == v.T) or (key == v.P)) and len(value) > 1 ] # determine what the type of plot will be if len(indep_comps) == 1 and len(indep_pots) == 1: projection = None elif len(indep_comps) == 2 and len(indep_pots) == 0: projection = 'triangular' else: raise ValueError( 'The eqplot projection is not defined and cannot be autodetected. There are {} independent compositions and {} indepedent potentials.' .format(len(indep_comps), len(indep_pots))) if z is not None: raise NotImplementedError('3D plotting is not yet implemented') if ax is None: fig = plt.figure() ax = fig.gca(projection=projection) ax = plt.gca(projection=projection) if ax is None else ax # Handle cases for different plot types if projection is None: x = indep_comps[0] if x is None else x y = indep_pots[0] if y is None else y # plot settings ax.set_xlim([np.min(conds[x]) - 1e-2, np.max(conds[x]) + 1e-2]) ax.set_ylim([np.min(conds[y]), np.max(conds[y])]) elif projection == 'triangular': x = indep_comps[0] if x is None else x y = indep_comps[1] if y is None else y # plot settings ax.yaxis.label.set_rotation(60) # Here we adjust the x coordinate of the ylabel. # We make it reasonably comparable to the position of the xlabel from the xaxis # As the figure size gets very large, the label approaches ~0.55 on the yaxis # 0.55*cos(60 deg)=0.275, so that is the xcoord we are approaching. ax.yaxis.label.set_va('baseline') fig_x_size = ax.figure.get_size_inches()[0] y_label_offset = 1 / fig_x_size ax.yaxis.set_label_coords(x=(0.275 - y_label_offset), y=0.5) # get the active phases and support loading netcdf files from disk phases = map( str, sorted(set(np.array(eq.Phase.values.ravel(), dtype='U')) - {''}, key=str)) comps = map( str, sorted(np.array(eq.coords['component'].values, dtype='U'), key=str)) eq['component'] = np.array(eq['component'], dtype='U') eq['Phase'].values = np.array(eq['Phase'].values, dtype='U') # Select all two- and three-phase regions three_phase_idx = np.nonzero( np.sum(eq.Phase.values != '', axis=-1, dtype=np.int) == 3) two_phase_idx = np.nonzero( np.sum(eq.Phase.values != '', axis=-1, dtype=np.int) == 2) legend_handles, colorlist = phase_legend(phases) # For both two and three phase, cast the tuple of indices to an array and flatten # If we found two phase regions: if two_phase_idx[0].size > 0: found_two_phase = eq.Phase.values[two_phase_idx][..., :2] # get tieline endpoint compositions two_phase_x = eq.X.sel( component=x.species).values[two_phase_idx][..., :2] # handle special case for potential if isinstance(y, v.Composition): two_phase_y = eq.X.sel( component=y.species).values[two_phase_idx][..., :2] else: # it's a StateVariable. This must be True two_phase_y = np.take( eq[str(y)].values, two_phase_idx[list(str(i) for i in conds.keys()).index(str(y))]) # because the above gave us a shape of (n,) instead of (n,2) we are going to create it ourselves two_phase_y = np.array([two_phase_y, two_phase_y]).swapaxes(0, 1) # construct tielines tielines = np.array([ np.concatenate((two_phase_x[..., 0][..., np.newaxis], two_phase_y[..., 0][..., np.newaxis]), axis=-1), np.concatenate((two_phase_x[..., 1][..., np.newaxis], two_phase_y[..., 1][..., np.newaxis]), axis=-1) ]) tielines = np.rollaxis(tielines, 1) lc = mc.LineCollection(tielines, zorder=1, colors=[0, 1, 0, 1], linewidths=[0.5, 0.5]) # plot two phase points and tielines two_phase_plotcolors = np.array(list( map(lambda x: [colorlist[x[0]], colorlist[x[1]]], found_two_phase)), dtype='U') # from pycalphad ax.scatter(two_phase_x[..., 0], two_phase_y[..., 0], s=3, c=two_phase_plotcolors[:, 0], edgecolors='None', zorder=2, **kwargs) ax.scatter(two_phase_x[..., 1], two_phase_y[..., 1], s=3, c=two_phase_plotcolors[:, 1], edgecolors='None', zorder=2, **kwargs) ax.add_collection(lc) # If we found three phase regions: if three_phase_idx[0].size > 0: found_three_phase = eq.Phase.values[three_phase_idx][..., :3] # get tieline endpoints three_phase_x = eq.X.sel( component=x.species).values[three_phase_idx][..., :3] three_phase_y = eq.X.sel( component=y.species).values[three_phase_idx][..., :3] # three phase tielines three_phase_tielines = np.array([ np.concatenate((three_phase_x[..., 0][..., np.newaxis], three_phase_y[..., 0][..., np.newaxis]), axis=-1), np.concatenate((three_phase_x[..., 1][..., np.newaxis], three_phase_y[..., 1][..., np.newaxis]), axis=-1), np.concatenate((three_phase_x[..., 2][..., np.newaxis], three_phase_y[..., 2][..., np.newaxis]), axis=-1) ]) three_phase_tielines = np.rollaxis(three_phase_tielines, 1) three_lc = mc.LineCollection(three_phase_tielines, zorder=1, colors=[1, 0, 0, 1], linewidths=[0.5, 0.5]) # plot three phase points and tielines three_phase_plotcolors = np.array(list( map(lambda x: [colorlist[x[0]], colorlist[x[1]], colorlist[x[2]]], found_three_phase)), dtype='U') # from pycalphad ax.scatter(three_phase_x[..., 0], three_phase_y[..., 0], s=3, c=three_phase_plotcolors[:, 0], edgecolors='None', zorder=2, **kwargs) ax.scatter(three_phase_x[..., 1], three_phase_y[..., 1], s=3, c=three_phase_plotcolors[:, 1], edgecolors='None', zorder=2, **kwargs) ax.scatter(three_phase_x[..., 2], three_phase_y[..., 2], s=3, c=three_phase_plotcolors[:, 2], edgecolors='None', zorder=2, **kwargs) ax.add_collection(three_lc) # position the phase legend and configure plot box = ax.get_position() ax.set_position([box.x0, box.y0, box.width * 0.8, box.height]) ax.legend(handles=legend_handles, loc='center left', bbox_to_anchor=(1, 0.5)) ax.tick_params(axis='both', which='major', labelsize=14) ax.grid(True) plot_title = '-'.join([x.title() for x in sorted(comps) if x != 'VA']) ax.set_title(plot_title, fontsize=20) ax.set_xlabel(_axis_label(x), labelpad=15, fontsize=20) ax.set_ylabel(_axis_label(y), fontsize=20) return ax
## plt.figure(1).clf() fig, ax = plt.subplots(num=1) cell_mask = g.cell_clip_mask(clip) cc = g.cells_center() u = ds.ucxa.values v = ds.ucya.values ax.quiver(cc[cell_mask, 0], cc[cell_mask, 1], u[cell_mask], v[cell_mask]) from matplotlib import collections segs = [] for p in range(len(ptm.P)): seg = locs[:, p, :] sel = utils.within_2d(seg, clip) segs.append(seg[sel]) lcoll = collections.LineCollection(segs, color='b', lw=0.4) ax.add_collection(lcoll) ax.axis('equal') # HERE - can get some tracks for many samples, but some fail. # may need to diffuse out the velocity field, for cases where # a sample is too close? # this is failing on a particle 518,
# count tensions N_Ten += 1 MAP_Edge_to_Ten = np.array(MAP_Edge_to_Ten, dtype=int) print('DONE...') print('Number of tensions = ', N_Ten) print('Number of triple junctions =', N_TJ) ########################################## # # VISUALIZATION OF SETUP # ########################################## c = np.array([(1, 0, 0, 1), (0, 1, 0, 1), (0, 0, 1, 1)]) lc = mc.LineCollection(graph, colors=c, linewidths=2) fig, ax = pl.subplots(figsize=(10, 10)) ax.add_collection(lc) plt.title(dir) plt.grid() ax.margins(0.1) #plt.scatter(X, Y, marker='o', color='black') plt.show() # plt.savefig('mesh002_tj_only_visualization') ########################################## # # Matrix construction and solve system of equations # ##########################################
# PointsList.append([p2, 1]) # Segments plot preview i = 0 for i in range(0, len(PointsList), 2): lines.append([(PointsList[i][0].x, PointsList[i][0].y), (PointsList[i + 1][0].x, PointsList[i + 1][0].y)]) temparray.append([ random.uniform(0.3, 1), random.uniform(0.3, 1), random.uniform(0.3, 1), random.uniform(0.3, 1) ]) c = np.array(temparray) lc = mc.LineCollection(lines, colors=c, linewidths=3) fig, ax = pl.subplots() ax.add_collection(lc) ax.autoscale() ax.margins(0.1) # fig.show() fig.savefig('before.pdf', format='pdf') # Sweep line algorithm T = [] Q = PointsList Q.sort(key=lambda vec: vec[0].x) # Sorting Q by x value T.append(Q[0][0].segment) # Inserting initial point to T del Q[0] # removing initial point from Q Result = [] # List of final output while not len(Q) == 0: # Keep until Q empty
def streamplot(axes, x, y, u, v, density=1, linewidth=None, color=None, cmap=None, norm=None, arrowsize=1, arrowstyle='-|>', minlength=0.1, transform=None, zorder=None, start_points=None, maxlength=4.0, integration_direction='both'): """ Draw streamlines of a vector flow. Parameters ---------- x, y : 1D/2D arrays Evenly spaced strictly increasing arrays to make a grid. If 2D, all rows of *x* must be equal and all columns of *y* must be equal; i.e., they must be as if generated by ``np.meshgrid(x_1d, y_1d)``. u, v : 2D arrays *x* and *y*-velocities. The number of rows and columns must match the length of *y* and *x*, respectively. density : float or (float, float) Controls the closeness of streamlines. When ``density = 1``, the domain is divided into a 30x30 grid. *density* linearly scales this grid. Each cell in the grid can have, at most, one traversing streamline. For different densities in each direction, use a tuple (density_x, density_y). linewidth : float or 2D array The width of the stream lines. With a 2D array the line width can be varied across the grid. The array must have the same shape as *u* and *v*. color : color or 2D array The streamline color. If given an array, its values are converted to colors using *cmap* and *norm*. The array must have the same shape as *u* and *v*. cmap : `~matplotlib.colors.Colormap` Colormap used to plot streamlines and arrows. This is only used if *color* is an array. norm : `~matplotlib.colors.Normalize` Normalize object used to scale luminance data to 0, 1. If ``None``, stretch (min, max) to (0, 1). This is only used if *color* is an array. arrowsize : float Scaling factor for the arrow size. arrowstyle : str Arrow style specification. See `~matplotlib.patches.FancyArrowPatch`. minlength : float Minimum length of streamline in axes coordinates. start_points : Nx2 array Coordinates of starting points for the streamlines in data coordinates (the same coordinates as the *x* and *y* arrays). zorder : int The zorder of the stream lines and arrows. Artists with lower zorder values are drawn first. maxlength : float Maximum length of streamline in axes coordinates. integration_direction : {'forward', 'backward', 'both'}, default: 'both' Integrate the streamline in forward, backward or both directions. data : indexable object, optional DATA_PARAMETER_PLACEHOLDER Returns ------- StreamplotSet Container object with attributes - ``lines``: `.LineCollection` of streamlines - ``arrows``: `.PatchCollection` containing `.FancyArrowPatch` objects representing the arrows half-way along stream lines. This container will probably change in the future to allow changes to the colormap, alpha, etc. for both lines and arrows, but these changes should be backward compatible. """ grid = Grid(x, y) mask = StreamMask(density) dmap = DomainMap(grid, mask) if zorder is None: zorder = mlines.Line2D.zorder # default to data coordinates if transform is None: transform = axes.transData if color is None: color = axes._get_lines.get_next_color() if linewidth is None: linewidth = matplotlib.rcParams['lines.linewidth'] line_kw = {} arrow_kw = dict(arrowstyle=arrowstyle, mutation_scale=10 * arrowsize) _api.check_in_list(['both', 'forward', 'backward'], integration_direction=integration_direction) if integration_direction == 'both': maxlength /= 2. use_multicolor_lines = isinstance(color, np.ndarray) if use_multicolor_lines: if color.shape != grid.shape: raise ValueError("If 'color' is given, it must match the shape of " "the (x, y) grid") line_colors = [[]] # Empty entry allows concatenation of zero arrays. color = np.ma.masked_invalid(color) else: line_kw['color'] = color arrow_kw['color'] = color if isinstance(linewidth, np.ndarray): if linewidth.shape != grid.shape: raise ValueError("If 'linewidth' is given, it must match the " "shape of the (x, y) grid") line_kw['linewidth'] = [] else: line_kw['linewidth'] = linewidth arrow_kw['linewidth'] = linewidth line_kw['zorder'] = zorder arrow_kw['zorder'] = zorder # Sanity checks. if u.shape != grid.shape or v.shape != grid.shape: raise ValueError("'u' and 'v' must match the shape of the (x, y) grid") u = np.ma.masked_invalid(u) v = np.ma.masked_invalid(v) integrate = _get_integrator(u, v, dmap, minlength, maxlength, integration_direction) trajectories = [] if start_points is None: for xm, ym in _gen_starting_points(mask.shape): if mask[ym, xm] == 0: xg, yg = dmap.mask2grid(xm, ym) t = integrate(xg, yg) if t is not None: trajectories.append(t) else: sp2 = np.asanyarray(start_points, dtype=float).copy() # Check if start_points are outside the data boundaries for xs, ys in sp2: if not (grid.x_origin <= xs <= grid.x_origin + grid.width and grid.y_origin <= ys <= grid.y_origin + grid.height): raise ValueError("Starting point ({}, {}) outside of data " "boundaries".format(xs, ys)) # Convert start_points from data to array coords # Shift the seed points from the bottom left of the data so that # data2grid works properly. sp2[:, 0] -= grid.x_origin sp2[:, 1] -= grid.y_origin for xs, ys in sp2: xg, yg = dmap.data2grid(xs, ys) # Floating point issues can cause xg, yg to be slightly out of # bounds for xs, ys on the upper boundaries. Because we have # already checked that the starting points are within the original # grid, clip the xg, yg to the grid to work around this issue xg = np.clip(xg, 0, grid.nx - 1) yg = np.clip(yg, 0, grid.ny - 1) t = integrate(xg, yg) if t is not None: trajectories.append(t) if use_multicolor_lines: if norm is None: norm = mcolors.Normalize(color.min(), color.max()) cmap = cm.get_cmap(cmap) streamlines = [] arrows = [] for t in trajectories: tgx, tgy = t.T # Rescale from grid-coordinates to data-coordinates. tx, ty = dmap.grid2data(tgx, tgy) tx += grid.x_origin ty += grid.y_origin points = np.transpose([tx, ty]).reshape(-1, 1, 2) streamlines.extend(np.hstack([points[:-1], points[1:]])) # Add arrows half way along each trajectory. s = np.cumsum(np.hypot(np.diff(tx), np.diff(ty))) n = np.searchsorted(s, s[-1] / 2.) arrow_tail = (tx[n], ty[n]) arrow_head = (np.mean(tx[n:n + 2]), np.mean(ty[n:n + 2])) if isinstance(linewidth, np.ndarray): line_widths = interpgrid(linewidth, tgx, tgy)[:-1] line_kw['linewidth'].extend(line_widths) arrow_kw['linewidth'] = line_widths[n] if use_multicolor_lines: color_values = interpgrid(color, tgx, tgy)[:-1] line_colors.append(color_values) arrow_kw['color'] = cmap(norm(color_values[n])) p = patches.FancyArrowPatch( arrow_tail, arrow_head, transform=transform, **arrow_kw) arrows.append(p) lc = mcollections.LineCollection( streamlines, transform=transform, **line_kw) lc.sticky_edges.x[:] = [grid.x_origin, grid.x_origin + grid.width] lc.sticky_edges.y[:] = [grid.y_origin, grid.y_origin + grid.height] if use_multicolor_lines: lc.set_array(np.ma.hstack(line_colors)) lc.set_cmap(cmap) lc.set_norm(norm) axes.add_collection(lc) ac = matplotlib.collections.PatchCollection(arrows) # Adding the collection itself is broken; see #2341. for p in arrows: axes.add_patch(p) axes.autoscale_view() stream_container = StreamplotSet(lc, ac) return stream_container
def streamplot(axes, x, y, u, v, density=1, linewidth=None, color=None, cmap=None, norm=None, arrowsize=1, arrowstyle='-|>', minlength=0.1, transform=None, zorder=None, start_points=None, maxlength=4.0, integration_direction='both'): """ Draw streamlines of a vector flow. Parameters ---------- x, y : 1d arrays An evenly spaced grid. u, v : 2d arrays *x* and *y*-velocities. Number of rows should match length of *y*, and the number of columns should match *x*. density : float or 2-tuple Controls the closeness of streamlines. When ``density = 1``, the domain is divided into a 30x30 grid---*density* linearly scales this grid. Each cell in the grid can have, at most, one traversing streamline. For different densities in each direction, use [density_x, density_y]. linewidth : numeric or 2d array Vary linewidth when given a 2d array with the same shape as velocities. color : matplotlib color code, or 2d array Streamline color. When given an array with the same shape as velocities, *color* values are converted to colors using *cmap*. cmap : `~matplotlib.colors.Colormap` Colormap used to plot streamlines and arrows. Only necessary when using an array input for *color*. norm : `~matplotlib.colors.Normalize` Normalize object used to scale luminance data to 0, 1. If ``None``, stretch (min, max) to (0, 1). Only necessary when *color* is an array. arrowsize : float Factor scale arrow size. arrowstyle : str Arrow style specification. See `~matplotlib.patches.FancyArrowPatch`. minlength : float Minimum length of streamline in axes coordinates. start_points : Nx2 array Coordinates of starting points for the streamlines. In data coordinates, the same as the *x* and *y* arrays. zorder : int Any number. maxlength : float Maximum length of streamline in axes coordinates. integration_direction : ['forward' | 'backward' | 'both'] Integrate the streamline in forward, backward or both directions. default is ``'both'``. Returns ------- stream_container : StreamplotSet Container object with attributes - lines: `matplotlib.collections.LineCollection` of streamlines - arrows: collection of `matplotlib.patches.FancyArrowPatch` objects representing arrows half-way along stream lines. This container will probably change in the future to allow changes to the colormap, alpha, etc. for both lines and arrows, but these changes should be backward compatible. """ grid = Grid(x, y) mask = StreamMask(density) dmap = DomainMap(grid, mask) if zorder is None: zorder = mlines.Line2D.zorder # default to data coordinates if transform is None: transform = axes.transData if color is None: color = axes._get_lines.get_next_color() if linewidth is None: linewidth = matplotlib.rcParams['lines.linewidth'] line_kw = {} arrow_kw = dict(arrowstyle=arrowstyle, mutation_scale=10 * arrowsize) if integration_direction not in ['both', 'forward', 'backward']: errstr = ("Integration direction '%s' not recognised. " "Expected 'both', 'forward' or 'backward'." % integration_direction) raise ValueError(errstr) if integration_direction == 'both': maxlength /= 2. use_multicolor_lines = isinstance(color, np.ndarray) if use_multicolor_lines: if color.shape != grid.shape: raise ValueError( "If 'color' is given, must have the shape of 'Grid(x,y)'") line_colors = [] color = np.ma.masked_invalid(color) else: line_kw['color'] = color arrow_kw['color'] = color if isinstance(linewidth, np.ndarray): if linewidth.shape != grid.shape: raise ValueError( "If 'linewidth' is given, must have the shape of 'Grid(x,y)'") line_kw['linewidth'] = [] else: line_kw['linewidth'] = linewidth arrow_kw['linewidth'] = linewidth line_kw['zorder'] = zorder arrow_kw['zorder'] = zorder ## Sanity checks. if u.shape != grid.shape or v.shape != grid.shape: raise ValueError("'u' and 'v' must be of shape 'Grid(x,y)'") u = np.ma.masked_invalid(u) v = np.ma.masked_invalid(v) integrate = get_integrator(u, v, dmap, minlength, maxlength, integration_direction) trajectories = [] if start_points is None: for xm, ym in _gen_starting_points(mask.shape): if mask[ym, xm] == 0: xg, yg = dmap.mask2grid(xm, ym) t = integrate(xg, yg) if t is not None: trajectories.append(t) else: sp2 = np.asanyarray(start_points, dtype=float).copy() # Check if start_points are outside the data boundaries for xs, ys in sp2: if not (grid.x_origin <= xs <= grid.x_origin + grid.width and grid.y_origin <= ys <= grid.y_origin + grid.height): raise ValueError("Starting point ({}, {}) outside of data " "boundaries".format(xs, ys)) # Convert start_points from data to array coords # Shift the seed points from the bottom left of the data so that # data2grid works properly. sp2[:, 0] -= grid.x_origin sp2[:, 1] -= grid.y_origin for xs, ys in sp2: xg, yg = dmap.data2grid(xs, ys) t = integrate(xg, yg) if t is not None: trajectories.append(t) if use_multicolor_lines: if norm is None: norm = mcolors.Normalize(color.min(), color.max()) if cmap is None: cmap = cm.get_cmap(matplotlib.rcParams['image.cmap']) else: cmap = cm.get_cmap(cmap) streamlines = [] arrows = [] for t in trajectories: tgx = np.array(t[0]) tgy = np.array(t[1]) # Rescale from grid-coordinates to data-coordinates. tx, ty = dmap.grid2data(*np.array(t)) tx += grid.x_origin ty += grid.y_origin points = np.transpose([tx, ty]).reshape(-1, 1, 2) streamlines.extend(np.hstack([points[:-1], points[1:]])) # Add arrows half way along each trajectory. s = np.cumsum(np.hypot(np.diff(tx), np.diff(ty))) n = np.searchsorted(s, s[-1] / 2.) arrow_tail = (tx[n], ty[n]) arrow_head = (np.mean(tx[n:n + 2]), np.mean(ty[n:n + 2])) if isinstance(linewidth, np.ndarray): line_widths = interpgrid(linewidth, tgx, tgy)[:-1] line_kw['linewidth'].extend(line_widths) arrow_kw['linewidth'] = line_widths[n] if use_multicolor_lines: color_values = interpgrid(color, tgx, tgy)[:-1] line_colors.append(color_values) arrow_kw['color'] = cmap(norm(color_values[n])) p = patches.FancyArrowPatch(arrow_tail, arrow_head, transform=transform, **arrow_kw) axes.add_patch(p) arrows.append(p) lc = mcollections.LineCollection(streamlines, transform=transform, **line_kw) lc.sticky_edges.x[:] = [grid.x_origin, grid.x_origin + grid.width] lc.sticky_edges.y[:] = [grid.y_origin, grid.y_origin + grid.height] if use_multicolor_lines: lc.set_array(np.ma.hstack(line_colors)) lc.set_cmap(cmap) lc.set_norm(norm) axes.add_collection(lc) axes.autoscale_view() ac = matplotlib.collections.PatchCollection(arrows) stream_container = StreamplotSet(lc, ac) return stream_container
lines = [] color = [] for i in range(len(d) - 1): l = len(lines) if l % 3 == 0: l = plt.axvline(d[i][0], color="yellow") color.append("green") elif l % 3 == 1: color.append("blue") elif l % 3 == 2: color.append("red") lines.append((d[i], d[i + 1])) lc = mc.LineCollection(lines, colors=color, linewidths=2) ax.add_collection(lc) lines = [] color = [] for i in range(len(d) - 1): l = len(lines) if l % 3 == 0: l = plt.axvline(d[i][0], color="yellow") color.append("green") elif l % 3 == 1: color.append("blue") elif l % 3 == 2: color.append("red")
for i in range(number_of_points): plt.plot(plotting_X[i], plotting_Y[i], 'bo') # plot x and y using blue circle markers ''' input the number of lines along with the line. The line is given in the form of a start point and an end point ''' number_of_lines = int(file.readline()) for i in range(number_of_lines): temp = list() x1, y1, x2, y2 = file.readline().split() temp.append((float(x1), float(y1))) temp.append((float(x2), float(y2))) lines.append(temp) cost_val = float(file.readline()) plt.title(f"Cost value is: {cost_val}") #plotting the lines using the points inputted above lc = mc.LineCollection(lines, color='y', linewidths=4) ax.add_collection(lc) #printing the grid as well as closing it after we are done plt.grid() ax.autoscale_view() plt.show() file.close()
def plot_performance_spectrum(self, class_colors, ax, classifier=None, metric='', args=None, mask=None, start='start_time', end='end_time', order=None, compare='global', show_classes=None, vis_mask=False): """ Input: class_colors: list with rgba tuples, there should be a color for each class. ax: A Matplotlib axis object. mask: any Pandas mask on the Performance Spectrum Data Frame to be considered before plotting. Output: The Matplotlib axis object containing the plotted Performance Spectrum. """ if args is None: args = [] pf = self.pf.copy() if vis_mask: pf.loc[mask, 'class'] = 1 pf.loc[~mask, 'class'] = 0 else: if compare == 'global': if classifier is not None: pf = self.classify(pf, classifier, metric, args) if mask is not None: pf = pf[mask] elif compare == 'local': if mask is not None: pf = pf[mask] if classifier is not None: pf = self.classify(pf, classifier, metric, args) if show_classes is not None: pf = pf[pf['class'].isin(show_classes)] pf = self.build_coordinates(pf, start, end) plotting_order = range( len(class_colors)) if order == 'reversed' else reversed( range(len(class_colors))) for i in plotting_order: lines = [[start, end] for start, end in zip( pf[pf['class'] == i]['start'], pf[pf['class'] == i]['end'])] ax.add_collection( mc.LineCollection( lines, colors=[class_colors[i] for c in range(len(lines))], alpha=0.25)) ax.autoscale() props = dict(boxstyle='round', facecolor='white', alpha=0.5) for i, y in enumerate(self.y_s): text_str = f'{self.segments[i][0]} \n{self.segments[i][1]}' ax.add_collection(plt.hlines(y, 0, max(pf['end_time']), alpha=0.25)) ax.text(0.05, y[0] / (abs(ax.get_ylim()[0]) + abs(ax.get_ylim()[1])), text_str, transform=ax.transAxes, fontsize=12, verticalalignment='top', bbox=props)