def addArrow(ax, scene): phi = num.nanmean(scene.phi) los_dx = num.cos(phi + num.pi) * .0625 los_dy = num.sin(phi + num.pi) * .0625 az_dx = num.cos(phi - num.pi / 2) * .125 az_dy = num.sin(phi - num.pi / 2) * .125 anchor_x = .9 if los_dx < 0 else .1 anchor_y = .85 if los_dx < 0 else .975 az_arrow = patches.FancyArrow(x=anchor_x - az_dx, y=anchor_y - az_dy, dx=az_dx, dy=az_dy, head_width=.025, alpha=.5, fc='k', head_starts_at_zero=False, length_includes_head=True, transform=ax.transAxes) los_arrow = patches.FancyArrow(x=anchor_x - az_dx / 2, y=anchor_y - az_dy / 2, dx=los_dx, dy=los_dy, head_width=.02, alpha=.5, fc='k', head_starts_at_zero=False, length_includes_head=True, transform=ax.transAxes) ax.add_artist(az_arrow) ax.add_artist(los_arrow)
def draw(self): cx1, cy1 = self.canvascoords(self.x1, self.y1) cx2, cy2 = self.canvascoords(self.x2, self.y2) cx3, cy3 = self.canvascoords(self.x3, self.y3) cr = self.setup_cr(transform=None, head_width=10, head_length=15, length_includes_head=True, overhang=0.20) cr.set(facecolor=cr.get_color(self.color)) cr.update_line(self) # draw North line and arrowhead dx, dy = cx2 - cx1, cy2 - cy1 p = patches.FancyArrow(cx1, cy1, dx, dy, **cr.kwdargs) cr.axes.add_patch(p) # draw East line and arrowhead dx, dy = cx3 - cx1, cy3 - cy1 p = patches.FancyArrow(cx1, cy1, dx, dy, **cr.kwdargs) cr.axes.add_patch(p) # draw "N" & "E" if not self.fontsize: fontsize = self.scale_font() else: fontsize = self.fontsize font = cr.get_font(self.font, fontsize, self.color) cx, cy = self.get_textpos(cr, 'N', cx1, cy1, cx2, cy2, font) cr.axes.text(cx, cy, 'N', fontdict=font) cx, cy = self.get_textpos(cr, 'E', cx1, cy1, cx3, cy3, font) cr.axes.text(cx, cy, 'E', fontdict=font) if self.cap: self.draw_caps(cr, self.cap, ((cx1, cy1), ))
def create_boxes(labels, display_center_boxes=True, types_to_display=DEFAULT_TYPES_TO_DISPLAY): """ This function create boxes according to a dictionnary of labels Argument: labels -- list of dictionnaries containing the spacial info. display_center_boxes -- True / False to indicate the center of the boxes types_to_display -- list of the type of object to display Returns: boxes_to_display -- list of patches.Rectangle objects """ boxes_to_display = [] for obj in labels: if obj['type'] in types_to_display: # If there is no angle in the dictionary and no center need to drawn if 'alpha' in obj and not display_center_boxes: box_angle = obj['alpha'] else: box_angle = 0 bbox = obj['bbox'] boxes_to_display.append( patches.Rectangle( (bbox['x_min'], bbox['y_min']), # (x,y) bbox['x_max'] - bbox['x_min'], # width bbox['y_max'] - bbox['y_min'], # height box_angle, # rotation angle linewidth=3, # linewidth edgecolor=COLOR_TYPE[obj['type']], # color corres. to type facecolor='none' # not fill )) if display_center_boxes: # Mark the center of the box boxes_to_display.append( patches.FancyArrow(bbox['x_min'], bbox['y_min'], bbox['x_max'] - bbox['x_min'], bbox['y_max'] - bbox['y_min'], head_length=0, linewidth=2, edgecolor=COLOR_TYPE[obj['type']])) boxes_to_display.append( patches.FancyArrow(bbox['x_max'], bbox['y_min'], bbox['x_min'] - bbox['x_max'], bbox['y_max'] - bbox['y_min'], head_length=0, linewidth=2, edgecolor=COLOR_TYPE[obj['type']])) return boxes_to_display
def animate(id): head_label = head_labels[id] hand_label = hand_labels[id] x_head, y_head, z_head, phi_head = head_label[0], head_label[ 1], head_label[2], head_label[3] x_hand, y_hand, z_hand, phi_hand = hand_label[0], hand_label[ 1], hand_label[2], hand_label[3] str1 = "x_head={:05.3f}, y_head={:05.3f}, z_head={:05.3f}, phi_head={:05.3f} {}".format( x_head, y_head, z_head, phi_head, "\n") str1 = str1 + "x_hand={:05.3f}, y_hand={:05.3f}, z_hand={:05.3f}, phi_hand={:05.3f} {}".format( x_hand, y_hand, z_hand, phi_hand, "\n") phi_head = -phi_head - np.pi / 2 phi_hand = -phi_hand - np.pi / 2 annotation.set_text(str1) plot1gthead.set_data(np.array([y_head, x_head])) plot1gthand.set_data(np.array([y_hand, x_hand])) if (len(ax1.patches) > 1): ax1.patches.pop() ax1.patches.pop() patch1 = patches.FancyArrow(y_head, x_head, 0.5 * np.cos(phi_head), 0.5 * np.sin(phi_head), head_width=0.05, head_length=0.05, color='green') patch2 = patches.FancyArrow(y_hand, x_hand, 0.5 * np.cos(phi_hand), 0.5 * np.sin(phi_hand), head_width=0.05, head_length=0.05, color='blue') ax1.add_patch(patch1) ax1.add_patch(patch2) scatter2gthead.set_offsets(np.array([-0.05, z_head])) scatter2gthand.set_offsets(np.array([-0.0, z_hand])) frame = frames[id].astype(np.uint8) if isGray == False: frame = frame.transpose(1, 2, 0) imgplot.set_array(frame) annotation2.set_text('Frame {}'.format(id)) #use the first one for viz on screen and second one for video recording #return plot1gt, plot1pr, patch1, patch2, scatter2gt, scatter2pr, imgplot, ax1, ax3, annotation, annotation2 return plot1gthead, plot1gthand, patch1, patch2, scatter2gthead, scatter2gthand, imgplot, annotation, annotation2
def draw_bodies(ax, poses, size, Vs_hat): """Draw rectangles for all given poses.""" ax.clear() ax.set_xlim((-size, size)) ax.set_ylim((-size, size)) for sTb in poses: rect = rect_of_pose2(sTb, width=0.4, height=0.4) ax.add_artist(rect) v = np.dot(Vs_hat, [sTb.x(), sTb.y(), 1]) ax.add_artist(mpatches.FancyArrow(sTb.x(), sTb.y(), v[0], v[1], color='r', **arrowOptions)) ax.add_artist(mpatches.FancyArrow(0, 0, Vs_hat[0,2], Vs_hat[1,2], color='g', **arrowOptions))
def animate(id): label = labels[id] camPose = camPoses[id] x_gt, y_gt, phi_gt = MoveToWorldFrame(label, camPose) x_cam, y_cam, z_cam, phi_cam = camPose[0], camPose[1], camPose[ 2], camPose[3] str1 = "x_cam={:05.3f}, y_cam={:05.3f}, phi_cam={:05.3f} {}".format( x_cam, y_cam, phi_cam, "\n") str1 = str1 + "x_gt={:05.3f}, y_gt={:05.3f}, phi_gt={:05.3f} {}".format( x_gt, y_gt, phi_gt, "\n") annotation.set_text(str1) plot1gt.set_data(np.array([y_gt, x_gt])) plot1cam.set_data(np.array([y_cam, x_cam])) if (len(ax1.patches) > 1): ax1.patches.pop() ax1.patches.pop() patch1 = patches.FancyArrow(y_gt, x_gt, 0.5 * np.sin(phi_gt), 0.5 * np.cos(phi_gt), head_width=0.05, head_length=0.05, color='green') patch2 = patches.FancyArrow(y_cam, x_cam, 0.5 * np.sin(phi_cam), 0.5 * np.cos(phi_cam), head_width=0.05, head_length=0.05, color='k') ax1.add_patch(patch1) ax1.add_patch(patch2) frame = frames[id].astype(np.uint8) if isGray == False: frame = frame.transpose(1, 2, 0) imgplot.set_array(frame) annotation2.set_text('Frame {}'.format(id)) # use the first one for viz on screen and second one for video recording # return plot1gt, plot1pr, patch1, patch2, scatter2gt, scatter2pr, imgplot, ax1, ax3, annotation, annotation2 #return plot1gt, plot1pr, patch1, patch2, scatter2gt, scatter2pr, imgplot, annotation, annotation2 return plot1gt, plot1cam, patch1, patch2, imgplot, annotation, annotation2
def animate(t0): """Animate the motion of spinning square, with time t0 as parameter""" # t0 = (40/180) * np.pi init() # draw square center at t0 # artist_list = [] arrow_kw = { 'head_width': 0.2, 'head_length': 0.3, 'width': 0.03, 'length_includes_head': True } arr_center = patches.FancyArrow(*([0, 0]), *sq_center(t0), color='green', **arrow_kw) ax.add_artist(arr_center) # artist_list.append(ax.add_artist(arr_center)) # draw XY axes at t0 ori_XY = sq_center(t0) + center_to_oriXY(t0) arr_X = patches.FancyArrow(*ori_XY, *np.array([1.5, 0]), color='red', **arrow_kw) arr_Y = patches.FancyArrow(*ori_XY, *np.array([0, 1.5]), color='red', **arrow_kw) ax.add_artist(arr_X) ax.add_artist(arr_Y) # artist_list.append(ax.add_artist(arr_X)) # artist_list.append(ax.add_artist(arr_Y)) # draw square at t0 square_kw = dict(linewidth=2, edgecolor='black', facecolor='red', fill=False) # NOTE: rotation angle is in degrees, not radian square = patches.Rectangle(sq_center(t0) + center_to_corner(t0), edge, edge, angle=(w_spin * t0) / np.pi * 180, **square_kw) ax.add_artist(square) # artist_list.append(ax.add_artist(square)) # add text text_kw = dict(fontsize=14, transform=ax.transAxes) ax.text(0.1, 0.9, 'In $xy$ system', text_kw)
def testTranslateOverwrite(self): """ The translate overwrites previous translate. """ drawing = patches.FancyArrow(x=5, y=-5, dx=0, dy=10, width=0.1, fc='k', ec='k', head_length=1, head_width=1, length_includes_head=True) fig, axes = plt.subplots() axes.add_patch(drawing) transform = transforms.Affine2D().translate(10, 0) drawing.set_transform(transform + axes.transData) transform = transforms.Affine2D().translate(15, 0) drawing.set_transform(transform + axes.transData) axes.set_ylim(-10, 10) axes.set_xlim(0, 20) plt.title("Graphic at x=5 + Translate x=+15 (Overwrites previous +10)") plt.show()
def testScaleTransformDoesNotScalePositionBeforeTranslate(self): """ This (2x2) scaling does not affect the position of the drawing if the translation is done after the scaling and the drawing is instantiated at x=0 """ drawing = patches.FancyArrow(x=0, y=-5, dx=0, dy=10, width=0.1, fc='k', ec='k', head_length=1, head_width=1, length_includes_head=True) fig, axes = plt.subplots() axes.add_patch(drawing) transform = transforms.Affine2D().scale( 2, 2) + transforms.Affine2D().translate(10, 0) drawing.set_transform(transform + axes.transData) axes.set_ylim(-10, 10) axes.set_xlim(0, 20) plt.title( "Scale Transform\nGraphic is (0.1 x 10) at x=0 + Scale (2 x 2) + Translate x=10" ) plt.show()
def testScaleTransformAlsoScalesPositionAfterTranslate(self): """ This (2x2) scaling affects the position of the drawing after translation even if it was instantiated at x=0 """ drawing = patches.FancyArrow(x=0, y=-5, dx=0, dy=10, width=0.1, fc='k', ec='k', head_length=1, head_width=1, length_includes_head=True) fig, axes = plt.subplots() axes.add_patch(drawing) transform = transforms.Affine2D().translate( 10, 0) + transforms.Affine2D().scale(2, 2) drawing.set_transform(transform + axes.transData) axes.set_ylim(-10, 10) axes.set_xlim(0, 20) plt.title( "Scale Transform\nGraphic is (0.1 x 10) at x=0 + Translate x=10 + Scale (2 x 2)" ) plt.show()
def generateObj2(mfo): fig, ax = plt.subplots(1) image = cv2.imread("walking_frame0.jpg") for k in range(len(mfo.fobs)): image2 = cv2.imread("walking_frame%d.jpg" % mfo.fobs[k].frame) for i in range(int(mfo.fobs[k].tl_y), int(mfo.fobs[k].br_y)): for j in range(int(mfo.fobs[k].tl_x), int(mfo.fobs[k].br_x)): if (i >= 0) & (i < image.shape[0]) & (j >= 0) & ( j < image.shape[1]): image[i][j] = image2[i][j] ax.imshow(image) for o in mfo.fobs: rect = patches.Rectangle((o.tl_x, o.tl_y), o.w, o.h, linewidth=1, edgecolor='r', facecolor='none', label=o.cat) ax.add_patch(rect) for i in range(len(mfo.fobs) - 1): arrow = patches.FancyArrow(mfo.fobs[i].c_x, mfo.fobs[i].c_y, mfo.fobs[i + 1].c_x - mfo.fobs[i].c_x, mfo.fobs[i + 1].c_y - mfo.fobs[i].c_y, width=1, head_width=10, head_length=12) ax.add_patch(arrow) plt.show()
def legend_arrow(width, height, **_): return mpatches.FancyArrow(0, 0.5 * height, width, 0, length_includes_head=True, head_width=0.75 * height)
def update(frame_number): pose = simulation.pose if self.arrow is not None: self.arrow.remove() self.circle.remove() # ax.clear() # plt.arrow(pose.position.x, pose.position.y, 100 * sin(pose.orientation), 100 * cos(pose.orientation), # width=40, head_width=100, head_length=40, fc="none", ec="r", alpha=0.5, **arrow_params) unit_offset_x = sin(pose.orientation) unit_offset_y = cos(pose.orientation) self.arrow = ax.add_patch( patches.FancyArrow(pose.position.x + unit_offset_x * 50, pose.position.y + unit_offset_y * 50, 25 * sin(pose.orientation), 25 * cos(pose.orientation), **arrow_params)) ax.add_artist( plt.Circle((pose.position.x, pose.position.y), 5, color=(0.4, 1.0, 0.2, 0.5), ec=edge_colour)) self.circle = plt.Circle((pose.position.x, pose.position.y), 50, color=(0.4, 1.0, 0.2, 0.5), ec=edge_colour) ax.add_artist(self.circle)
def get_patches(self): if self.position is not None: jet = cm = plt.get_cmap('Greens') cNorm = colors.Normalize(vmin=0, vmax=100) scalarMap = cmx.ScalarMappable(norm=cNorm, cmap=jet) patches = [] arrow = mplpatch.ArrowStyle.Simple() for connection in self.connections: dx, dy = connection.platform.position - self.position c = (0, 0, 0) #Test that the arrow length is non-zero. Zero length error crashes matplotlib if dx**2 + dy**2 > 0.01: patch = mplpatch.FancyArrow(self.position[0], self.position[1], dx, dy, head_width=0, width=4, zorder=-1, ec=c, fc=c) patches.append(patch) return patches else: return []
def arrow(s, e, estyle): delta = tuple((ev - sv for sv, ev in zip(s, e))) l = math.sqrt(delta[0] * delta[0] + delta[1] * delta[1]) unit = (delta[0] / l, delta[1] / l) start = (s[0] + unit[0] * radius, s[1] + unit[1] * radius) edel = (delta[0] - unit[0] * (hl + 2 * radius), delta[1] - unit[1] * (hl + 2 * radius)) return mpatches.FancyArrow(start[0], start[1], edel[0], edel[1], head_length=hl, head_width=0.05, **estyle)
def animate(id): label = self.labels[id] x_gt, y_gt, z_gt, phi_gt = label[0], label[1], label[2], label[3] str1 = "x_gt={:05.3f}, y_gt={:05.3f}, z_gt={:05.3f}, phi_gt={:05.3f} {}".format( x_gt, y_gt, z_gt, phi_gt, "\n") phi_gt = -phi_gt - np.pi / 2 annotation.set_text(str1) plot1gt.set_data(np.array([y_gt, x_gt])) if (len(ax1.patches) > 1): ax1.patches.pop() patch1 = patches.FancyArrow(y_gt, x_gt, 0.5 * np.cos(phi_gt), 0.5 * np.sin(phi_gt), head_width=0.05, head_length=0.05, color='green') ax1.add_patch(patch1) scatter2gt.set_offsets(np.array([-0.05, z_gt])) frame = self.frames[id].astype(np.uint8) imgplot.set_array(frame) annotation2.set_text('Frame {}'.format(id)) #use the first one for viz on screen and second one for video recording #return plot1gt, scatter2gt, imgplot, annotation, annotation2 return plot1gt, patch1, scatter2gt, imgplot, annotation, annotation2
def _generate_edges(self, trellis_length, grid, state_order, state_radius, edge_colors): """ Private method """ edge_patches = [] for current_time_index in range(trellis_length - 1): grid_subset = grid[:, self.number_states * current_time_index:] for state_count_1 in range(self.number_states): input_count = 0 for state_count_2 in range(self.number_states): dx = grid_subset[0, state_count_2 + self.number_states] - grid_subset[ 0, state_count_1] - 2 * state_radius dy = grid_subset[1, state_count_2 + self.number_states] - grid_subset[ 1, state_count_1] if np.count_nonzero(self.next_state_table[ state_order[state_count_1], :] == state_order[state_count_2]): found_index = np.where( self.next_state_table[state_order[state_count_1]] == state_order[state_count_2]) edge_patch = mpatches.FancyArrow( grid_subset[0, state_count_1] + state_radius, grid_subset[1, state_count_1], dx, dy, width=0.005, length_includes_head=True, color=edge_colors[found_index[0][0] - 1]) edge_patches.append(edge_patch) input_count = input_count + 1 return edge_patches
def testScaleTransformOnTranslatedDrawing(self): """ In order to correctly scale a drawing previously translated, we have to reset its transforms (automatically done with set_transform) and re-apply the required translation after. """ drawing = patches.FancyArrow( x=0, y=-5, dx=0, dy=10, width=0.1, fc='k', ec='k', head_length=1, head_width=1, length_includes_head=True) fig, axes = plt.subplots() axes.add_patch(drawing) transform = transforms.Affine2D().translate(10, 0) # initial positioning of the drawing drawing.set_transform(transform + axes.transData) # some code... # later if a rescaling is required we need to reapply the translation (in 2nd place) transform = transforms.Affine2D().scale(2, 2) + transforms.Affine2D().translate(10, 0) drawing.set_transform(transform + axes.transData) if self.SHOWPLOT: axes.set_ylim(-10, 10) axes.set_xlim(0, 20) plt.title("Scale Transform after translation requires a reset\nGraphic is (0.1 x 10) at x=0 + Scale (2 x " "2) + Translate x=10") plt.show()
def fixed_arrow(self, handle_name, x, y, dx, dy, **kwargs): if handle_name not in self.patches: p = patches.FancyArrow(x, y, dx, dy, **kwargs) self.patches[handle_name] = p self.ax.add_patch(p) h = self.patches[handle_name] self.ax.draw_artist(h)
def _draw_beta(ax,start,stop,label="",linewidth=1.2): ''' This is a private function which draws a named arrow on a matplotlib axis frim start to stop at 0.5 height ''' ax.add_patch(mpatches.FancyArrow(start-0.5, 0.5, stop-start, 0,width=0.5, head_width=1, head_length=1,edgecolor='k',facecolor='k')) ax.text(start+(stop-start)/2,-1,label,style='italic',horizontalalignment= 'center', verticalalignment= 'baseline')
def make_legend_arrow_rl(legend, orig_handle, xdescent, ydescent, width, height, fontsize): return patches.FancyArrow(x=width, y=height / 2, dx=-width, dy=0, length_includes_head=True, head_width=0.75 * height)
def arrow_by_start_size_angle(start, size, angle, **kwargs): return patches.FancyArrow( start[0], start[1], size * np.cos(angle), size * np.sin(angle), **kwargs )
def arrow_by_start_end(start, end, **kwargs): return patches.FancyArrow( start[0], start[1], end[0] - start[0], end[1] - start[1], **kwargs )
def make_legend_arrow(legend, orig_handle, xdescent, ydescent, width, height, fontsize): p = mpatches.FancyArrow(0, 0.5 * height, width, 0, length_includes_head=True, head_width=0.75 * height) return p
def arrow_by_start_size_dir(start, size, direction, **kwargs): angle = np.arctan2(*direction) return patches.FancyArrow( start[0], start[1], size * np.cos(angle), size * np.sin(angle), **kwargs )
def draw_edge(canvas, p1, p2, color='blue', **kwargs): """ Draws a line segment between points p1 and p2.""" line = patches.FancyArrow(p1.x, p1.y, p2.x - p1.x, p2.y - p1.y, color=color, linewidth='3.3', **kwargs) canvas.ax.add_patch(line)
def make_sheet_fancy_arrow(self, start, length): return m_patches.FancyArrow(start + self.x, self.width / 2 + self.y, # x, y of tail length, 0, # dx, dy=0 -> flat arrow length_includes_head=True, head_length=length / 4, head_width=self.sheet_head_height - 0.001, width=self.sheet_tail_height, facecolor=self.fc_sheet, edgecolor=self.edgecolor, linewidth=self.edge_thickness)
def add_arrow(self, cell, arrow_position, arrow_direction, annotation='', annotation_kwargs=None, **kwargs): """ Draws an arrow in a cell. If an arrow exists already at this position, it is replaced. Args: cell: cell coordinate as tuple (x,y) arrow_position: each cell has 9 possible positions specified as tuple e.g. upper left (-1, 1) arrow_direction: direction of the arrow as (x,y) tuple annotation: text to display at end of arrow annotation_kwargs: dict passed to matplotlib Text for annotation kwargs: arguments passed directly to the FancyArrow patch of matplotlib """ cell_midpoint = (0.5 + cell[0], 0.5 + cell[1]) kwargs.setdefault('width', 0.05) kwargs.setdefault('color', 'k') if annotation_kwargs is None: annotation_kwargs = {} annotation_kwargs.setdefault('horizontalalignment', 'center') annotation_kwargs.setdefault('verticalalignment', 'center') if arrow_position == (0, 0): del kwargs['width'] self.arrows[(cell, arrow_position)] = patches.Circle(cell_midpoint, radius=0.03, **kwargs) if annotation: self.annotations[(cell, arrow_position)] = Text( *cell_midpoint, annotation, **annotation_kwargs) else: arrow_midpoint = (cell_midpoint[0] + arrow_position[0] * 0.25, cell_midpoint[1] + arrow_position[1] * 0.25) length = 0.75 arrow_start = (arrow_midpoint[0] - arrow_direction[0] * 0.25 * length, arrow_midpoint[1] - arrow_direction[1] * 0.25 * length) arrow_direction = (0.25 * length * arrow_direction[0], 0.25 * length * arrow_direction[1]) arrow_end = tuple(a + b for a, b in zip(arrow_start, arrow_direction)) patch = patches.FancyArrow(*arrow_start, *arrow_direction, **kwargs) self.arrows[(cell, arrow_position)] = patch if annotation: self.annotations[(cell, arrow_position)] = Text( arrow_end[0], arrow_end[1], annotation, **annotation_kwargs)
def plotPathfindingProblem(globalWindDirectionDegrees, dimensions, start, goal, obstacles, headingDegrees): # Clear plot if already there plt.cla() # Create plot with start and goal x_min, y_min, x_max, y_max = dimensions markersize = min(x_max - x_min, y_max - y_min) / 2 plt.ion() axes = plt.gca() goalPlot, = axes.plot(goal[0], goal[1], marker='*', color='y', markersize=markersize) # Yellow star # Red triangle with correct heading. The (-90) is because the triangle # default heading 0 points North, but this heading has 0 be East. startPlot, = axes.plot(start[0], start[1], marker=(3, 0, headingDegrees - 90), color='r', markersize=markersize) # Setup plot xy limits and labels axes.set_xlim(x_min, x_max) axes.set_ylim(y_min, y_max) axes.set_aspect('equal') plt.grid(True) axes.set_xlabel('X distance to position (km)') axes.set_ylabel('Y distance to position (km)') axes.set_title('Setup of pathfinding problem') # Add boats and wind speed arrow for obstacle in obstacles: obstacle.addPatch(axes) arrowLength = min(dimensions[2] - dimensions[0], dimensions[3] - dimensions[1]) / 15 arrowCenter = (dimensions[0] + 1.5 * arrowLength, dimensions[3] - 1.5 * arrowLength) arrowStart = (arrowCenter[0] - 0.5 * arrowLength * math.cos(math.radians(globalWindDirectionDegrees)), arrowCenter[1] - 0.5 * arrowLength * math.sin(math.radians(globalWindDirectionDegrees))) windDirection = patches.FancyArrow( arrowStart[0], arrowStart[1], arrowLength * math.cos(math.radians(globalWindDirectionDegrees)), arrowLength * math.sin(math.radians(globalWindDirectionDegrees)), width=arrowLength / 4) axes.add_patch(windDirection) # Draw plot plt.draw() plt.pause(0.001)
def draw_lines(self, ax, passes, cosmetics=_pass_cosmetics, adjust=True): """ Add Passes to Particular Axes Parameters --------- ax: matplotlib Axes object passes: list of pass coordinates eg. - >>> [(x, y, end_x, end_y)] cosmetics: dict of keyword arguments for patches.FancyArrow() default = {'length_includes_head': True, 'head_width': 2, 'head_length': 2, 'width': 0.5, 'facecolor': (0, 0, 1, 0.6), 'edgecolor': (0, 0, 0, 0)} Examples ------- >>> from from northpitch.pitch import Pitch >>> import matplotlib.pyplot as plot >>> fig, ax = plt.subplots() >>> pitch = Pitch() >>> pitch.create_pitch(ax) >>> passes = [(60,60,25,25), (20,20, 50,50)] >>> pitch.draw_passes(ax, passes) >>> plt.ylim(pitch.ylim) >>> plt.xlim(pitch.xlim) >>> plt.show() """ # TODO Accept Different Pass Vector Formats for x, y, end_x, end_y in passes: y = (self.y_scale - y) if self.vert else y end_y = (self.y_scale - end_y) if self.vert else end_y dx = end_x - x dy = end_y - y if adjust: attributes = { 'x': self.y_adj(y) if self.vert else self.x_adj(x), 'y': self.x_adj(x) if self.vert else self.y_adj(y), 'dx': self.y_adj(dy) if self.vert else self.x_adj(dx), 'dy': self.x_adj(dx) if self.vert else self.y_adj(dy) } else: attributes = { 'x': y if self.vert else x, 'y': x if self.vert else y, 'dx': dy if self.vert else dx, 'dy': dx if self.vert else dy } ax.add_patch(patches.FancyArrow(**attributes, **cosmetics))