def createHTriangles(xData, yData, NUM_PROD, coloring, NUM_SENSORS, focalLocs, a): patches = [] # triangle patches array for prod in np.arange(NUM_PROD): if prod >= 2: # only for non-Velo sensors; 6 mounted around vehicle # rot = rotation. Each product displays for each rotation for rot in np.arange(NUM_SENSORS): # amount range needs to be rotated r = mpl.transforms.Affine2D().rotate_deg_around( focalLocs[rot][0], focalLocs[rot][1], sensorAngle[rot]) + a # x translation of sensor origin xAdd = focalLocs[rot][0] # y translation of sensor origin yAdd = focalLocs[rot][1] # new points with translation applied polyPoints = np.array( [[xData[0][prod] + xAdd, yData[0][prod] + yAdd], [xData[1][prod] + xAdd, yData[1][prod] + yAdd], [xData[2][prod] + xAdd, yData[2][prod] + yAdd]]) # creates polygon from points poly = Polygon(polyPoints, True, label=products[prod], alpha=0.3, color=coloring[prod]) # rotates the polygon poly.set_transform(r) # appends polygon to array patches.append(poly) return patches
def drawPolygon2d(self, polygon, color, alpha): points = polygon.toArray() polygon_draw = Polygon(points, True, facecolor=self.getColor(color), edgecolor=self.getColor(color), alpha=alpha) t_start = self.axes.transData polygon_draw.set_transform(t_start) self.axes.add_patch(polygon_draw) center = polygon.center self.axes.plot(center[0], center[1], color=self.getColor(color))
class MplPolygonalROI(AbstractMplRoi): """ Matplotlib ROI for polygon selections Parameters ---------- axes : :class:`matplotlib.axes.Axes` The Matplotlib axes to draw to. roi : :class:`glue.core.roi.Roi`, optional If specified, this ROI will be used and updated, otherwise a new one will be created. """ _roi_cls = PolygonalROI def __init__(self, axes, roi=None, data_space=True): super(MplPolygonalROI, self).__init__(axes, roi=roi, data_space=data_space) self.plot_opts = { 'edgecolor': PATCH_COLOR, 'facecolor': PATCH_COLOR, 'alpha': 0.3 } self._patch = Polygon(np.array(list(zip([0, 1], [0, 1]))), zorder=100) self._patch.set_visible(False) if not self._data_space: self._patch.set_transform(self._axes.transAxes) self._axes.add_patch(self._patch) def _sync_patch(self): if self._roi.defined(): x, y = self._roi.to_polygon() self._patch.set_xy(list(zip(x + [x[0]], y + [y[0]]))) self._patch.set_visible(True) self._patch.set(**self.plot_opts) else: self._patch.set_visible(False) def start_selection(self, event, scrubbing=False): if event.inaxes != self._axes: return False if self._data_space: xval = event.xdata yval = event.ydata else: axes_trans = self._axes.transAxes.inverted() xval, yval = axes_trans.transform([event.x, event.y]) if scrubbing or event.key == SCRUBBING_KEY: if not self._roi.defined(): return False elif not self._roi.contains(xval, yval): return False self._store_previous_roi() self._store_background() if scrubbing or event.key == SCRUBBING_KEY: self._scrubbing = True self._cx = xval self._cy = yval else: self.reset() self._roi.add_point(xval, yval) self._mid_selection = True self._sync_patch() self._draw() def update_selection(self, event): if not self._mid_selection or event.inaxes != self._axes: return False if event.key == SCRUBBING_KEY: if not self._roi.defined(): return False if self._data_space: xval = event.xdata yval = event.ydata else: axes_trans = self._axes.transAxes.inverted() xval, yval = axes_trans.transform([event.x, event.y]) if self._scrubbing: self._roi.move_to(xval - self._cx, yval - self._cy) self._cx = xval self._cy = yval else: self._roi.add_point(xval, yval) self._sync_patch() self._draw() def finalize_selection(self, event): self._scrubbing = False self._mid_selection = False self._patch.set_visible(False) self._draw()
class WindroseAxes(PolarAxes): """ Makes a windrose axes """ RESOLUTION = 100 def __init__(self, *args, **kwargs): """ See Axes base class for args and kwargs documentation """ PolarAxes.__init__(self, *args, **kwargs) self.set_aspect('equal', adjustable='box', anchor='C') self.radii_angle = 67.5 self.cla() def _init_axis(self): self.xaxis = None self.yaxis = None def cla(self): """ Clear the current axes """ self._get_lines = _process_plot_var_args(self) self._get_patches_for_fill = _process_plot_var_args(self, 'fill') self._gridOn = matplotlib.rcParams['polaraxes.grid'] self.thetagridlabels = [] self.thetagridlines = [] self.rgridlabels = [] self.rgridlines = [] self.lines = [] self.images = [] self.patches = [] self.artists = [] self.collections = [] self.texts = [] # text in axis coords self.legend_ = None self.grid(self._gridOn) self.title = Text( x=0.5, y=1.05, text='', fontproperties=FontProperties( size=matplotlib.rcParams['axes.titlesize']), verticalalignment='bottom', horizontalalignment='center', ) self.title.set_transform(self.transAxes) self._set_artist_props(self.title) self.thetas = N.linspace(0, 2 * N.pi, self.RESOLUTION) verts = list(zip(self.thetas, N.ones(self.RESOLUTION))) self.axesPatch = Polygon( verts, facecolor=self._axisbg, edgecolor=matplotlib.rcParams['axes.edgecolor'], ) self.axesPatch.set_figure(self.figure) self.axesPatch.set_transform(self.transData) self.axesPatch.set_linewidth(matplotlib.rcParams['axes.linewidth']) self.axison = True self.rintv = Interval(Value(0), Value(1)) self.rintd = Interval(Value(0), Value(1)) self.rformatter = ScalarFormatter() self.rformatter.set_view_interval(self.rintv) self.rformatter.set_data_interval(self.rintd) class RadialLocator(AutoLocator): 'enforce strictly positive radial ticks' def __call__(self): ticks = AutoLocator.__call__(self) return [t for t in ticks if t > 0] self.rlocator = RadialLocator() self.rlocator.set_view_interval(self.rintv) self.rlocator.set_data_interval(self.rintd) self.theta_angles = N.arange(0, 360, 45) self.theta_labels = ['E', 'N-E', 'N', 'N-W', 'W', 'S-W', 'S', 'S-E'] self.set_thetagrids(angles=self.theta_angles, labels=self.theta_labels) self._info = {'dir': list(), 'bins': list(), 'table': list()} self.patches_list = list() def _colors(self, cmap, n): ''' Returns a list of n colors based on the colormap cmap ''' return [cmap(i) for i in N.linspace(0.0, 1.0, n)] def set_radii_angle(self, **kwargs): """ Set the radii labels angle """ null = popd(kwargs, 'labels', None) angle = popd(kwargs, 'angle', None) if angle is None: angle = self.radii_angle self.radii_angle = angle radii = N.linspace(0.1, self.get_rmax(), 6) radii_labels = ["%.1f" % r for r in radii] radii_labels[0] = "" #Removing label 0 null = self.set_rgrids(radii=radii, labels=radii_labels, angle=self.radii_angle, **kwargs) def _update(self): self.regrid(self.get_rmax()) self.set_radii_angle(angle=self.radii_angle) def legend(self, loc='lower left', **kwargs): """ Sets the legend location and her properties. The location codes are 'best' : 0, 'upper right' : 1, 'upper left' : 2, 'lower left' : 3, 'lower right' : 4, 'right' : 5, 'center left' : 6, 'center right' : 7, 'lower center' : 8, 'upper center' : 9, 'center' : 10, If none of these are suitable, loc can be a 2-tuple giving x,y in axes coords, ie, loc = (0, 1) is left top loc = (0.5, 0.5) is center, center and so on. The following kwargs are supported: isaxes=True # whether this is an axes legend prop = FontProperties(size='smaller') # the font property pad = 0.2 # the fractional whitespace inside the legend border shadow # if True, draw a shadow behind legend labelsep = 0.005 # the vertical space between the legend entries handlelen = 0.05 # the length of the legend lines handletextsep = 0.02 # the space between the legend line and legend text axespad = 0.02 # the border between the axes and legend edge """ def get_handles(): handles = list() for p in self.patches_list: if isinstance(p, matplotlib.patches.Polygon) or \ isinstance(p, matplotlib.patches.Rectangle): color = p.get_facecolor() elif isinstance(p, matplotlib.lines.Line2D): color = p.get_color() else: raise AttributeError("Can't handle patches") handles.append( Rectangle((0, 0), 0.2, 0.2, facecolor=color, edgecolor='black')) return handles def get_labels(): labels = N.copy(self._info['bins']) labels = ["[%.1f : %0.1f[" %(labels[i], labels[i+1]) \ for i in range(len(labels)-1)] return labels null = popd(kwargs, 'labels', None) null = popd(kwargs, 'handles', None) handles = get_handles() labels = get_labels() self.legend_ = matplotlib.legend.Legend(self, handles, labels, loc, **kwargs) return self.legend_ def _init_plot(self, dir, var, **kwargs): """ Internal method used by all plotting commands """ #self.cla() null = popd(kwargs, 'zorder', None) #Init of the bins array if not set bins = popd(kwargs, 'bins', None) if bins is None: bins = N.linspace(N.min(var), N.max(var), 6) if isinstance(bins, int): bins = N.linspace(N.min(var), N.max(var), bins) nbins = len(bins) #Init of the number of sectors nsector = popd(kwargs, 'nsector', None) if nsector is None: nsector = 16 #Sets the colors table based on the colormap or the "colors" argument colors = popd(kwargs, 'colors', None) cmap = popd(kwargs, 'cmap', None) if colors is not None: if isinstance(colors, str): colors = [colors] * nbins if isinstance(colors, (tuple, list)): if len(colors) != nbins: raise ValueError("colors and bins must have same length") else: if cmap is None: cmap = cm.jet colors = self._colors(cmap, nbins) #Building the list of angles angles = N.arange(0, -2 * N.pi, -2 * N.pi / nsector) + N.pi / 2 normed = popd(kwargs, 'normed', False) blowto = popd(kwargs, 'blowto', False) #Set the global information dictionnary self._info['dir'], self._info['bins'], self._info['table'] = histogram( dir, var, bins, nsector, normed, blowto) return bins, nbins, nsector, colors, angles, kwargs def contour(self, dir, var, **kwargs): """ Plot a windrose in linear mode. For each var bins, a line will be draw on the axes, a segment between each sector (center to center). Each line can be formated (color, width, ...) like with standard plot pylab command. Mandatory: * dir : 1D array - directions the wind blows from, North centred * var : 1D array - values of the variable to compute. Typically the wind speeds Optional: * nsector: integer - number of sectors used to compute the windrose table. If not set, nsectors=16, then each sector will be 360/16=22.5°, and the resulting computed table will be aligned with the cardinals points. * bins : 1D array or integer- number of bins, or a sequence of bins variable. If not set, bins=6, then bins=linspace(min(var), max(var), 6) * blowto : bool. If True, the windrose will be pi rotated, to show where the wind blow to (usefull for pollutant rose). * colors : string or tuple - one string color ('k' or 'black'), in this case all bins will be plotted in this color; a tuple of matplotlib color args (string, float, rgb, etc), different levels will be plotted in different colors in the order specified. * cmap : a cm Colormap instance from matplotlib.cm. - if cmap == None and colors == None, a default Colormap is used. others kwargs : see help(pylab.plot) """ bins, nbins, nsector, colors, angles, kwargs = self._init_plot( dir, var, **kwargs) #closing lines angles = N.hstack((angles, angles[0])) vals = N.hstack((self._info['table'], N.reshape(self._info['table'][:, 0], (self._info['table'].shape[0], 1)))) offset = 0 for i in range(nbins): val = vals[i, :] + offset offset += vals[i, :] zorder = nbins - i patch = self.plot(angles, val, color=colors[i], zorder=zorder, **kwargs) self.patches_list.extend(patch) self._update() def contourf(self, dir, var, **kwargs): """ Plot a windrose in filled mode. For each var bins, a line will be draw on the axes, a segment between each sector (center to center). Each line can be formated (color, width, ...) like with standard plot pylab command. Mandatory: * dir : 1D array - directions the wind blows from, North centred * var : 1D array - values of the variable to compute. Typically the wind speeds Optional: * nsector: integer - number of sectors used to compute the windrose table. If not set, nsectors=16, then each sector will be 360/16=22.5°, and the resulting computed table will be aligned with the cardinals points. * bins : 1D array or integer- number of bins, or a sequence of bins variable. If not set, bins=6, then bins=linspace(min(var), max(var), 6) * blowto : bool. If True, the windrose will be pi rotated, to show where the wind blow to (usefull for pollutant rose). * colors : string or tuple - one string color ('k' or 'black'), in this case all bins will be plotted in this color; a tuple of matplotlib color args (string, float, rgb, etc), different levels will be plotted in different colors in the order specified. * cmap : a cm Colormap instance from matplotlib.cm. - if cmap == None and colors == None, a default Colormap is used. others kwargs : see help(pylab.plot) """ bins, nbins, nsector, colors, angles, kwargs = self._init_plot( dir, var, **kwargs) null = popd(kwargs, 'facecolor', None) null = popd(kwargs, 'edgecolor', None) offset = 0 for i in range(nbins): val = self._info['table'][i, :] + offset offset += self._info['table'][i, :] zorder = nbins - i patch = self.fill(angles, val, facecolor=colors[i], edgecolor=colors[i], zorder=zorder, **kwargs) self.patches_list.extend(patch) def bar(self, dir, var, **kwargs): """ Plot a windrose in bar mode. For each var bins and for each sector, a colored bar will be draw on the axes. Mandatory: * dir : 1D array - directions the wind blows from, North centred * var : 1D array - values of the variable to compute. Typically the wind speeds Optional: * nsector: integer - number of sectors used to compute the windrose table. If not set, nsectors=16, then each sector will be 360/16=22.5°, and the resulting computed table will be aligned with the cardinals points. * bins : 1D array or integer- number of bins, or a sequence of bins variable. If not set, bins=6 between min(var) and max(var). * blowto : bool. If True, the windrose will be pi rotated, to show where the wind blow to (usefull for pollutant rose). * colors : string or tuple - one string color ('k' or 'black'), in this case all bins will be plotted in this color; a tuple of matplotlib color args (string, float, rgb, etc), different levels will be plotted in different colors in the order specified. * cmap : a cm Colormap instance from matplotlib.cm. - if cmap == None and colors == None, a default Colormap is used. edgecolor : string - The string color each edge bar will be plotted. Default : no edgecolor * opening : float - between 0.0 and 1.0, to control the space between each sector (1.0 for no space) """ bins, nbins, nsector, colors, angles, kwargs = self._init_plot( dir, var, **kwargs) null = popd(kwargs, 'facecolor', None) edgecolor = popd(kwargs, 'edgecolor', None) if edgecolor is not None: if not isinstance(edgecolor, str): raise ValueError('edgecolor must be a string color') opening = popd(kwargs, 'opening', None) if opening is None: opening = 0.8 dtheta = 2 * N.pi / nsector opening = dtheta * opening for j in range(nsector): offset = 0 for i in range(nbins): if i > 0: offset += self._info['table'][i - 1, j] val = self._info['table'][i, j] zorder = nbins - i patch = Rectangle((angles[j] - opening / 2, offset), opening, val, facecolor=colors[i], edgecolor=edgecolor, zorder=zorder, **kwargs) self.add_patch(patch) if j == 0: self.patches_list.append(patch) self._update() def box(self, dir, var, **kwargs): """ Plot a windrose in proportional bar mode. For each var bins and for each sector, a colored bar will be draw on the axes. Mandatory: * dir : 1D array - directions the wind blows from, North centred * var : 1D array - values of the variable to compute. Typically the wind speeds Optional: * nsector: integer - number of sectors used to compute the windrose table. If not set, nsectors=16, then each sector will be 360/16=22.5°, and the resulting computed table will be aligned with the cardinals points. * bins : 1D array or integer- number of bins, or a sequence of bins variable. If not set, bins=6 between min(var) and max(var). * blowto : bool. If True, the windrose will be pi rotated, to show where the wind blow to (usefull for pollutant rose). * colors : string or tuple - one string color ('k' or 'black'), in this case all bins will be plotted in this color; a tuple of matplotlib color args (string, float, rgb, etc), different levels will be plotted in different colors in the order specified. * cmap : a cm Colormap instance from matplotlib.cm. - if cmap == None and colors == None, a default Colormap is used. edgecolor : string - The string color each edge bar will be plotted. Default : no edgecolor """ bins, nbins, nsector, colors, angles, kwargs = self._init_plot( dir, var, **kwargs) null = popd(kwargs, 'facecolor', None) edgecolor = popd(kwargs, 'edgecolor', None) if edgecolor is not None: if not isinstance(edgecolor, str): raise ValueError('edgecolor must be a string color') opening = N.linspace(0.0, N.pi / 16, nbins) for j in range(nsector): offset = 0 for i in range(nbins): if i > 0: offset += self._info['table'][i - 1, j] val = self._info['table'][i, j] zorder = nbins - i patch = Rectangle((angles[j] - opening[i] / 2, offset), opening[i], val, facecolor=colors[i], edgecolor=edgecolor, zorder=zorder, **kwargs) self.add_patch(patch) if j == 0: self.patches_list.append(patch) self._update()
def visualize_workspace(figure, motion_mdp_edges, WS_d, WS_node_dict, raw_pose, cell_pose, status, show_next): pyplot.cla() fig = figure ax = fig.add_subplot(111) [l, u, m] = status #----- draw the robot cell_pose print 'robot cell pose', cell_pose xl = cell_pose[0] yl = cell_pose[1] dl = cell_pose[2] if m == 0: Ecolor = 'green' elif m == 1: Ecolor = 'magenta' elif m == 2: Ecolor = 'black' elif m > 2: Ecolor = 'magenta' if dl == 'N': car=[(xl-0.1,yl-0.1), (xl-0.1,yl+0.1), (xl, yl+0.2), (xl+0.1, yl+0.1), (xl+0.1,yl-0.1)] elif dl == 'E': car=[(xl-0.1,yl+0.1), (xl+0.1,yl+0.1), (xl+0.2, yl), (xl+0.1, yl-0.1), (xl-0.1,yl-0.1)] elif dl == 'S': car=[(xl+0.1,yl+0.1), (xl+0.1,yl-0.1), (xl, yl-0.2), (xl-0.1, yl-0.1), (xl-0.1,yl+0.1)] elif dl == 'W': car=[(xl+0.1,yl-0.1), (xl-0.1,yl-0.1), (xl-0.2, yl), (xl-0.1, yl+0.1), (xl+0.1,yl+0.1)] polygon = Polygon(car, fill = False, facecolor='grey', edgecolor='black', linestyle='dashed', lw=1.5, zorder = 2) ax.add_patch(polygon) #----- draw the robot raw_pose print 'robot raw pose', raw_pose xl = raw_pose[0] yl = raw_pose[1] dl = raw_pose[2] Ecolor = 'green' if m == 0: Ecolor = 'green' elif m == 1: Ecolor = 'magenta' elif m == 2: Ecolor = 'black' elif m > 2: Ecolor = 'magenta' car=[(xl-0.1,yl-0.1), (xl-0.1,yl+0.1), (xl, yl+0.2), (xl+0.1, yl+0.1), (xl+0.1,yl-0.1)] polygon2 = Polygon(car, fill = True, facecolor=Ecolor, edgecolor=Ecolor, lw=5, zorder = 2) ts = ax.transData coords = ts.transform([xl, yl]) tr = matplotlib.transforms.Affine2D().rotate_deg_around(coords[0], coords[1], dl*180/3.14 -90) t= ts + tr polygon2.set_transform(t) ax.add_patch(polygon2) # u = tuple(u) actstr = r'' for s in u: actstr += s ax.text(xl, yl+0.15, r'$%s$' %str(actstr), fontsize = 16, fontweight = 'bold', color='red') # plot shadow x = cell_pose[:] t_x_list = [] for (f_x, t_x) in motion_mdp_edges.iterkeys(): if f_x == tuple(x): prop = motion_mdp_edges[(f_x, t_x)] if (show_next and (u in prop.keys())): t_x_list.append((t_x, prop[u][0])) # for new_x in t_x_list: xl = new_x[0][0] yl = new_x[0][1] dl = new_x[0][2] if dl == 'N': car=[(xl-0.1,yl-0.1), (xl-0.1,yl+0.1), (xl, yl+0.2), (xl+0.1, yl+0.1), (xl+0.1,yl-0.1)] elif dl == 'E': car=[(xl-0.1,yl+0.1), (xl+0.1,yl+0.1), (xl+0.2, yl), (xl+0.1, yl-0.1), (xl-0.1,yl-0.1)] elif dl == 'S': car=[(xl+0.1,yl+0.1), (xl+0.1,yl-0.1), (xl, yl-0.2), (xl-0.1, yl-0.1), (xl-0.1,yl+0.1)] elif dl == 'W': car=[(xl+0.1,yl-0.1), (xl-0.1,yl-0.1), (xl-0.2, yl), (xl-0.1, yl+0.1), (xl+0.1,yl+0.1)] polygon = Polygon(car, fill = False, hatch = 'x', edgecolor='grey', lw=5, zorder = 1, alpha=0.5) ax.add_patch(polygon) prob = new_x[1] ax.text(xl, yl, r'$%s$' %str(prob), fontsize = 15, fontweight = 'bold', color='red') #---------------- draw the workspace for node, prop in WS_node_dict.iteritems(): if node != (x[0], x[1]): S = [] P = [] for s, p in prop.iteritems(): S.append(s) P.append(p) rdn = random.random() pc = 0 for k, p in enumerate(P): pc += p if pc> rdn: break current_s = S[k] if node == (x[0], x[1]): current_s = set([l,]) #------ if current_s == set(['base1','base']): text = '$base1$' color = 'yellow' elif current_s == set(['base2','base']): text = '$base2$' color = 'yellow' elif current_s == set(['base3', 'base']): text = '$base3$' color = 'yellow' elif current_s == set(['obstacle','low']): text = '$Obs$' color = 'red' elif current_s == set(['supply',]): text = '$Sply$' color = '#0000ff' else: text = None color = 'white' rec = matplotlib.patches.Rectangle((node[0]-WS_d, node[1]-WS_d), WS_d*2, WS_d*2, fill = True, facecolor = color, edgecolor = 'black', linewidth = 1, alpha =0.8) ax.add_patch(rec) if text: ax.text(node[0]-0.15, node[1], r'%s' %text, fontsize = 13, fontweight = 'bold') ax.set_aspect('equal') ax.set_xlim(-0.2, 2.6) ax.set_ylim(-0.2, 1.7) ax.set_xlabel(r'$x(m)$') ax.set_ylabel(r'$y(m)$') #fig.subplots_adjust(0.003,0.062,0.97,0.94) pyplot.pause(0.5) return fig
def create_figure(): f = plt.figure(frameon=False) f.set_size_inches(1, 1) ax = plt.Axes(f, [0.0, 0.0, 1.0, 1.0]) #ax.set_axis_off() f.add_axes(ax) ax.set_xlim([0, 50]) ax.set_ylim([0, 50]) # # Circe of random size # f.patch.set_facecolor("black") ax.patch.set_facecolor("black") n = np.random.randint(0, 20) for i in range(n): r = np.random.uniform(5, 10) x, y = np.random.uniform(0, 100, size=2) circle = plt.Circle((x, y), r, color="white") ax.add_artist(circle) # # Random triangle # n = np.random.randint(0, 20) for i in range(n): r = np.random.uniform(2, 10) x, y = np.random.uniform(0, 100, size=2) v0 = np.array([x, y]) v1 = v0 + np.array([r, 0]) v2 = np.array([x + 0.5 * r, y + r * np.sin(60.0 / 180.0 * np.pi)]) points = np.stack([v0, v1, v2]) midpoint = (v0 + v1 + v2) / 3.0 polygon = Polygon(points, color="white") theta = np.random.uniform(0, 360) r = Affine2D().rotate_around(midpoint[0], midpoint[1], theta) tra = r + ax.transData polygon.set_transform(tra) ax.add_artist(polygon) # # Random line # n = np.random.randint(0, 20) for i in range(n): l = 2 * np.random.normal() + 10 x, y = np.random.uniform(0, 100, size=2) theta = np.random.uniform(0, 360) v0 = np.array([x, y]) v1 = v0 + np.array([np.cos(theta)]) v0 = np.array([x, y]) theta = np.random.uniform(0, 2 * np.pi) v1 = v0 + np.array([l * np.cos(theta), l * np.sin(theta)]) ax.plot([v0[0], v1[0]], [v0[1], v1[1]], c="white", lw=3) return f