def draw3d(self, renderer): xyslist = [ proj3d.proj_trans_points(points, renderer.M) for points in self.segments_3d] segments_2d = [zip(xs,ys) for (xs,ys,zs) in xyslist] self._segments = segments_2d self.draw2d(renderer)
def draw(self, renderer): orig_segments = self._segments xyslist = [proj3d.proj_trans_points(points, renderer.M) for points in self.segments_3d] segments_2d = [zip(xs, ys) for (xs, ys, zs) in xyslist] self._segments = segments_2d LineCollection.draw(self, renderer) self._segments = orig_segments
def draw3d(self, renderer): # segments_3d = [[juggle_axes(x, y, self.z, self.dir) for (x, y) in points] for points in self._segments] xyslist = [proj3d.proj_trans_points(points, renderer.M) for points in segments_3d] segments_2d = [zip(xs, ys) for (xs, ys, zs) in xyslist] # orig_segments = self._segments self._segments = segments_2d self.draw2d(renderer)
def draw_linec(self, renderer): orig_segments = self._segments segments_3d = [[(x, y, z) for (x, y), z in zip(points, zs)] for zs, points in zip(self.zs, self._segments)] xyslist = [proj3d.proj_trans_points(points, renderer.M) for points in segments_3d] segments_2d = [zip(xs, ys) for (xs, ys, zs) in xyslist] self._segments = segments_2d LineCollection.draw(self, renderer) self._segments = orig_segments
def draw3d(self, renderer): xyslist = [ proj3d.proj_trans_points(points, renderer.M) for points in self.segments_3d ] segments_2d = [zip(xs, ys) for (xs, ys, zs) in xyslist] self._segments = segments_2d self.draw2d(renderer)
def draw(self, renderer): orig_segments = self._segments xyslist = [ proj3d.proj_trans_points(points, renderer.M) for points in self.segments_3d ] segments_2d = [zip(xs, ys) for (xs, ys, zs) in xyslist] self._segments = segments_2d LineCollection.draw(self, renderer) self._segments = orig_segments
def draw_linec(self, renderer): orig_segments = self._segments segments_3d = [[(x, y, z) for (x, y), z in zip(points, zs)] for zs, points in zip(self.zs, self._segments)] xyslist = [ proj3d.proj_trans_points(points, renderer.M) for points in segments_3d ] segments_2d = [zip(xs, ys) for (xs, ys, zs) in xyslist] self._segments = segments_2d LineCollection.draw(self, renderer) self._segments = orig_segments
def draw_polyc(self, renderer): orig_segments = self._verts # process the list of lists of 2D points held in _verts to generate # a list of lists of 3D points segments_3d = [[(x, y, z) for (x, y), z in zip(points, self.zs)] for points in self._verts] # xyslist = [proj3d.proj_trans_points(points, renderer.M) for points in segments_3d] segments_2d = [zip(xs, ys) for (xs, ys, zs) in xyslist] self._verts = segments_2d PolyCollection.draw(self, renderer) self._verts = orig_segments
def draw(self, renderer): proj = proj3d.proj_trans_points([self._position3d, \ self._position3d + self._dir_vec], renderer.M) dx = proj[0][1] - proj[0][0] dy = proj[1][1] - proj[1][0] if dx==0. and dy==0.: angle = 0. else: angle = math.degrees(math.atan2(dy, dx)) self.set_position((proj[0][0], proj[1][0])) self.set_rotation(norm_text_angle(angle)) mtext.Text.draw(self, renderer)
def draw3d(self, renderer): # segments_3d = [[ juggle_axes(x, y, self.z, self.dir) for (x, y) in points ] for points in self._segments] xyslist = [ proj3d.proj_trans_points(points, renderer.M) for points in segments_3d ] segments_2d = [zip(xs, ys) for (xs, ys, zs) in xyslist] #orig_segments = self._segments self._segments = segments_2d self.draw2d(renderer)
def draw(self, renderer): proj = proj3d.proj_trans_points([self._position3d, \ self._position3d + self._dir_vec], renderer.M) dx = proj[0][1] - proj[0][0] dy = proj[1][1] - proj[1][0] if dx == 0. and dy == 0.: # atan2 raises ValueError: math domain error on 0,0 angle = 0. else: angle = math.degrees(math.atan2(dy, dx)) self.set_position((proj[0][0], proj[1][0])) self.set_rotation(norm_text_angle(angle)) mtext.Text.draw(self, renderer)
def do_3d_projection(self, renderer): ''' Project the points according to renderer matrix. ''' xyslist = [ proj3d.proj_trans_points(points, renderer.M) for points in self._segments3d] segments_2d = [zip(xs, ys) for (xs, ys, zs) in xyslist] LineCollection.set_segments(self, segments_2d) minz = 1e9 for (xs, ys, zs) in xyslist: minz = min(minz, min(zs)) return minz
def draw_polyc(self, renderer): orig_segments = self._verts # process the list of lists of 2D points held in _verts to generate # a list of lists of 3D points segments_3d = [[(x, y, z) for (x, y), z in zip(points, self.zs)] for points in self._verts] # xyslist = [ proj3d.proj_trans_points(points, renderer.M) for points in segments_3d ] segments_2d = [zip(xs, ys) for (xs, ys, zs) in xyslist] self._verts = segments_2d PolyCollection.draw(self, renderer) self._verts = orig_segments
def draw_outline(self, renderer, face_sign=1): info = self._axinfo index = info['i'] #if index != 1 : return #renderer.open_group('axis3d') self.label._transform = self.axes.transData renderer.open_group('axis3d_Outline') majorTicks = self.get_major_ticks() majorLocs = self.major.locator() # filter locations here so that no extra grid lines are drawn interval = self.get_view_interval() majorLocs = [loc for loc in majorLocs if \ interval[0] <= loc <= interval[1]] self.major.formatter.set_locs(majorLocs) mins, maxs, centers, tickdelta, tc, highs = self._get_coord_info(renderer) # Draw ticks tickdir = info['tickdir'] ticksign = np.where(highs == True, 1, -1) #isFront = [ highs[tickdir] * face_sign != 1], highs[tickdir] * face_sign != 1, highs[tickdir] * face_sign != 1 ] print ticksign if index == 0: ts = np.array( [( -ticksign[2],ticksign[2]), (-ticksign[1], ticksign[2]) , (-ticksign[1], -ticksign[2])]) isVisible = ticksign[tickdir] * np.array([ -1, 1, 1]) elif index == 1: ts = np.array( [( ticksign[0],ticksign[1]), (-ticksign[0], ticksign[2]) , (-ticksign[0], -ticksign[2])]) isVisible = ticksign[tickdir] * np.array([ -ticksign[0], -1, ticksign[0]]) elif index == 2: ts = np.array( [( ticksign[0],-ticksign[2]), (-ticksign[0], -ticksign[2]) , (-ticksign[0], -ticksign[1])]) isVisible = ticksign[tickdir] * np.array([ -ticksign[0], 1, ticksign[0]]) # Determine grid lines minmax = np.where(highs, maxs, mins) # Draw main axis line juggled = info['juggled'] # Plot auxilary axis edgep_21 = minmax.copy() edgep_21[juggled[0]] = get_flip_min_max(edgep_21, juggled[0], mins, maxs) edgep_21[juggled[2]] = get_flip_min_max(edgep_21, juggled[2], mins, maxs) edgep_22 = edgep_21.copy() edgep_22[juggled[1]] = get_flip_min_max(edgep_22, juggled[1], mins, maxs) pep_aux = proj3d.proj_trans_points([edgep_21, edgep_22], renderer.M) self.line_outline[0].set_data((pep_aux[0][0], pep_aux[0][1]), (pep_aux[1][0], pep_aux[1][1])) # 3rd axis edgep_31 = minmax.copy() edgep_31[juggled[2]] = get_flip_min_max(edgep_31, juggled[2], mins, maxs) edgep_32 = edgep_31.copy() edgep_32[juggled[1]] = get_flip_min_max(edgep_32, juggled[1], mins, maxs) pep_aux = proj3d.proj_trans_points([edgep_31, edgep_32], renderer.M) self.line_outline[1].set_data((pep_aux[0][0], pep_aux[0][1]), (pep_aux[1][0], pep_aux[1][1])) # 4th axis edgep_41 = minmax.copy() edgep_42 = edgep_41.copy() edgep_42[juggled[1]] = get_flip_min_max(edgep_41, juggled[1], mins, maxs) pep_aux = proj3d.proj_trans_points([edgep_41, edgep_42], renderer.M) self.line_outline[2].set_data((pep_aux[0][0], pep_aux[0][1]), (pep_aux[1][0], pep_aux[1][1])) # Ticks edgep = [edgep_21, edgep_31, edgep_41] #isFront = [ highs[tickdir] * face_sign != 1], highs[tickdir] * face_sign != 1, highs[tickdir] * face_sign != 1 ] #if (isVisible[1] * face_sign == 1) : self.line_outline[1].draw(renderer) #if (isVisible[2] * face_sign == 1) : self.line_outline[2].draw(renderer) """ if isVisible[0] : self.line_outline[0].draw(renderer) if isVisible[1] : self.line_outline[1].draw(renderer) if isVisible[2] : self.line_outline[2].draw(renderer) """ #self.line_outline[1].draw(renderer) #self.line_outline[2].draw(renderer) #if ticksign*face_sign == -1 : self.line_outline[2].draw(renderer) #for tick, loc, label in zip(majorTicks, majorLocs, majorLabels): for tick, loc in zip(majorTicks, majorLocs): #if tick is None: # continue # For outline # Get tick line positions for i in range(3): #if i != 2 : continue if (isVisible[i] * face_sign) != 1 : continue self.line_outline[i].draw(renderer) # Get tick line positions continue pos = copy.copy(edgep[i]) pos[index] = loc x0, y0, z0 = proj3d.proj_transform(pos[0], pos[1], pos[2], \ renderer.M) pos[tickdir] = edgep[i][tickdir] + ts[i][0] * info['tick']['inward_factor'] * \ tickdelta[tickdir] x1, y1, z1 = proj3d.proj_transform(pos[0], pos[1], pos[2], \ renderer.M) tick_update_position(tick, (x0, x1), (y0, y1), (0, 0), False) tick.draw(renderer) pos = copy.copy(edgep[i]) pos[index] = loc nt = tickdir + 1 if nt >2 : nt = 0 pos[nt] = edgep[i][nt] + ts[i][1] * info['tick']['inward_factor'] * tickdelta[nt] x2, y2, z2 = proj3d.proj_transform(pos[0], pos[1], pos[2], \ renderer.M) tick_update_position(tick, (x0, x2), (y0, y2), (0, 0), False) tick.draw(renderer) renderer.close_group('axis3d_Outline')
def draw(self, renderer): self.label._transform = self.axes.transData renderer.open_group('axis3d') # code from XAxis majorTicks = self.get_major_ticks() majorLocs = self.major.locator() # filter locations here so that no extra grid lines are drawn interval = self.get_view_interval() majorLocs = [loc for loc in majorLocs if \ interval[0] < loc < interval[1]] self.major.formatter.set_locs(majorLocs) majorLabels = [self.major.formatter(val, i) for i, val in enumerate(majorLocs)] # Determine bounds minx, maxx, miny, maxy, minz, maxz = self.axes.get_w_lims() mins = (minx, miny, minz) maxs = (maxx, maxy, maxz) centers = [(maxv + minv) / 2 for minv, maxv in zip(mins, maxs)] deltas = [(maxv - minv) / 12 for minv, maxv in zip(mins, maxs)] mins = [minv - delta / 4 for minv, delta in zip(mins, deltas)] maxs = [maxv + delta / 4 for maxv, delta in zip(maxs, deltas)] # Determine which planes should be visible by the avg z value vals = mins[0], maxs[0], mins[1], maxs[1], mins[2], maxs[2] tc = self.axes.tunit_cube(vals, renderer.M) avgz = [tc[p1][2] + tc[p2][2] + tc[p3][2] + tc[p4][2] for \ p1, p2, p3, p4 in self._PLANES] highs = [avgz[2*i] < avgz[2*i+1] for i in range(3)] # Draw plane info = self._AXINFO[self.adir] index = info['i'] if not highs[index]: plane = self._PLANES[2 * index] else: plane = self._PLANES[2 * index + 1] xys = [tc[p] for p in plane] self.set_pane(xys, info['color']) self.pane.draw(renderer) # Determine grid lines minmax = [] for i, val in enumerate(highs): if val: minmax.append(maxs[i]) else: minmax.append(mins[i]) # Draw main axis line juggled = art3d.juggle_axes(0, 2, 1, self.adir) edgep1 = copy.copy(minmax) edgep1[juggled[0]] = get_flip_min_max(edgep1, juggled[0], mins, maxs) edgep2 = copy.copy(edgep1) edgep2[juggled[1]] = get_flip_min_max(edgep2, juggled[1], mins, maxs) pep = proj3d.proj_trans_points([edgep1, edgep2], renderer.M) self.line.set_data((pep[0][0], pep[0][1]), (pep[1][0], pep[1][1])) self.line.draw(renderer) # Grid points where the planes meet xyz0 = [] for val in majorLocs: coord = copy.copy(minmax) coord[index] = val xyz0.append(coord) # Draw labels dy = pep[1][1] - pep[1][0] dx = pep[0][1] - pep[0][0] lxyz = [(v1 + v2) / 2 for v1, v2 in zip(edgep1, edgep2)] labeldeltas = [1.3 * x for x in deltas] lxyz = move_from_center(lxyz, centers, labeldeltas) tlx, tly, tlz = proj3d.proj_transform(lxyz[0], lxyz[1], lxyz[2], \ renderer.M) self.label.set_position((tlx, tly)) if self.get_rotate_label(self.label.get_text()): angle = art3d.norm_text_angle(math.degrees(math.atan2(dy, dx))) self.label.set_rotation(angle) self.label.set_va('center') self.label.draw(renderer) # Grid points at end of one plane xyz1 = copy.deepcopy(xyz0) newindex = (index + 1) % 3 newval = get_flip_min_max(xyz1[0], newindex, mins, maxs) for i in range(len(majorLocs)): xyz1[i][newindex] = newval # Grid points at end of the other plane xyz2 = copy.deepcopy(xyz0) newindex = (index + 2) % 3 newval = get_flip_min_max(xyz2[0], newindex, mins, maxs) for i in range(len(majorLocs)): xyz2[i][newindex] = newval lines = zip(xyz1, xyz0, xyz2) if self.axes._draw_grid: self.gridlines.set_segments(lines) self.gridlines.set_color([(0.9,0.9,0.9,1)] * len(lines)) self.gridlines.draw(renderer, project=True) # Draw ticks tickdir = info['tickdir'] tickdelta = deltas[tickdir] if highs[tickdir]: ticksign = 1 else: ticksign = -1 for tick, loc, label in zip(majorTicks, majorLocs, majorLabels): if tick is None: continue # Get tick line positions pos = copy.copy(edgep1) pos[index] = loc pos[tickdir] = edgep1[tickdir] + 0.1 * ticksign * tickdelta x1, y1, z1 = proj3d.proj_transform(pos[0], pos[1], pos[2], \ renderer.M) pos[tickdir] = edgep1[tickdir] - 0.2 * ticksign * tickdelta x2, y2, z2 = proj3d.proj_transform(pos[0], pos[1], pos[2], \ renderer.M) # Get position of label labeldeltas = [0.6 * x for x in deltas] axmask = [True, True, True] axmask[index] = False pos[tickdir] = edgep1[tickdir] pos = move_from_center(pos, centers, labeldeltas, axmask) lx, ly, lz = proj3d.proj_transform(pos[0], pos[1], pos[2], \ renderer.M) tick_update_position(tick, (x1, x2), (y1, y2), (lx, ly)) tick.set_label1(label) tick.set_label2(label) tick.draw(renderer) renderer.close_group('axis3d')
def draw(self, renderer): self.label._transform = self.axes.transData renderer.open_group('axis3d') # code from XAxis majorTicks = self.get_major_ticks() majorLocs = self.major.locator() info = self._axinfo index = info['i'] # filter locations here so that no extra grid lines are drawn locmin, locmax = self.get_view_interval() if locmin > locmax: locmin, locmax = locmax, locmin # Rudimentary clipping majorLocs = [loc for loc in majorLocs if locmin <= loc <= locmax] self.major.formatter.set_locs(majorLocs) majorLabels = [ self.major.formatter(val, i) for i, val in enumerate(majorLocs) ] mins, maxs, centers, deltas, tc, highs = self._get_coord_info(renderer) # Determine grid lines minmax = np.where(highs, maxs, mins) # Draw main axis line juggled = info['juggled'] edgep1 = minmax.copy() edgep1[juggled[0]] = get_flip_min_max(edgep1, juggled[0], mins, maxs) edgep2 = edgep1.copy() edgep2[juggled[1]] = get_flip_min_max(edgep2, juggled[1], mins, maxs) pep = proj3d.proj_trans_points([edgep1, edgep2], renderer.M) centpt = proj3d.proj_transform(centers[0], centers[1], centers[2], renderer.M) self.line.set_data((pep[0][0], pep[0][1]), (pep[1][0], pep[1][1])) self.line.draw(renderer) # Grid points where the planes meet xyz0 = [] for val in majorLocs: coord = minmax.copy() coord[index] = val xyz0.append(coord) # Draw labels peparray = np.asanyarray(pep) # The transAxes transform is used because the Text object # rotates the text relative to the display coordinate system. # Therefore, if we want the labels to remain parallel to the # axis regardless of the aspect ratio, we need to convert the # edge points of the plane to display coordinates and calculate # an angle from that. # TODO: Maybe Text objects should handle this themselves? dx, dy = (self.axes.transAxes.transform(peparray[0:2, 1]) - self.axes.transAxes.transform(peparray[0:2, 0])) lxyz = 0.5 * (edgep1 + edgep2) labeldeltas = info['label']['space_factor'] * deltas axmask = [True, True, True] axmask[index] = False lxyz = move_from_center(lxyz, centers, labeldeltas, axmask) tlx, tly, tlz = proj3d.proj_transform(lxyz[0], lxyz[1], lxyz[2], \ renderer.M) self.label.set_position((tlx, tly)) if self.get_rotate_label(self.label.get_text()): angle = art3d.norm_text_angle(math.degrees(math.atan2(dy, dx))) self.label.set_rotation(angle) self.label.set_va(info['label']['va']) self.label.set_ha(info['label']['ha']) self.label.draw(renderer) # Draw Offset text # Which of the two edge points do we want to # use for locating the offset text? if juggled[2] == 2: outeredgep = edgep1 outerindex = 0 else: outeredgep = edgep2 outerindex = 1 pos = copy.copy(outeredgep) pos = move_from_center(pos, centers, labeldeltas, axmask) olx, oly, olz = proj3d.proj_transform(pos[0], pos[1], pos[2], renderer.M) self.offsetText.set_text(self.major.formatter.get_offset()) self.offsetText.set_position((olx, oly)) angle = art3d.norm_text_angle(math.degrees(math.atan2(dy, dx))) self.offsetText.set_rotation(angle) # Must set rotation mode to "anchor" so that # the alignment point is used as the "fulcrum" for rotation. self.offsetText.set_rotation_mode('anchor') #----------------------------------------------------------------------- # Note: the following statement for determining the proper alignment of # the offset text. This was determined entirely by trial-and-error # and should not be in any way considered as "the way". There are # still some edge cases where alignment is not quite right, but # this seems to be more of a geometry issue (in other words, I # might be using the wrong reference points). # # (TT, FF, TF, FT) are the shorthand for the tuple of # (centpt[info['tickdir']] <= peparray[info['tickdir'], outerindex], # centpt[index] <= peparray[index, outerindex]) # # Three-letters (e.g., TFT, FTT) are short-hand for the array # of bools from the variable 'highs'. # --------------------------------------------------------------------- if centpt[info['tickdir']] > peparray[info['tickdir'], outerindex]: # if FT and if highs has an even number of Trues if (centpt[index] <= peparray[index, outerindex] and ((len(highs.nonzero()[0]) % 2) == 0)): # Usually, this means align right, except for the FTT case, # in which offset for axis 1 and 2 are aligned left. if highs.tolist() == [False, True, True] and index in (1, 2): align = 'left' else: align = 'right' else: # The FF case align = 'left' else: # if TF and if highs has an even number of Trues if (centpt[index] > peparray[index, outerindex] and ((len(highs.nonzero()[0]) % 2) == 0)): # Usually mean align left, except if it is axis 2 if index == 2: align = 'right' else: align = 'left' else: # The TT case align = 'right' self.offsetText.set_va('center') self.offsetText.set_ha(align) self.offsetText.draw(renderer) # Draw grid lines if len(xyz0) > 0: # Grid points at end of one plane xyz1 = copy.deepcopy(xyz0) newindex = (index + 1) % 3 newval = get_flip_min_max(xyz1[0], newindex, mins, maxs) for i in range(len(majorLocs)): xyz1[i][newindex] = newval # Grid points at end of the other plane xyz2 = copy.deepcopy(xyz0) newindex = (index + 2) % 3 newval = get_flip_min_max(xyz2[0], newindex, mins, maxs) for i in range(len(majorLocs)): xyz2[i][newindex] = newval lines = zip(xyz1, xyz0, xyz2) if self.axes._draw_grid: self.gridlines.set_segments(lines) self.gridlines.set_color([info['grid']['color']] * len(lines)) self.gridlines.draw(renderer, project=True) # Draw ticks tickdir = info['tickdir'] tickdelta = deltas[tickdir] if highs[tickdir]: ticksign = 1 else: ticksign = -1 for tick, loc, label in zip(majorTicks, majorLocs, majorLabels): if tick is None: continue # Get tick line positions pos = copy.copy(edgep1) pos[index] = loc pos[tickdir] = edgep1[tickdir] + info['tick']['outward_factor'] * \ ticksign * tickdelta x1, y1, z1 = proj3d.proj_transform(pos[0], pos[1], pos[2], \ renderer.M) pos[tickdir] = edgep1[tickdir] - info['tick']['inward_factor'] * \ ticksign * tickdelta x2, y2, z2 = proj3d.proj_transform(pos[0], pos[1], pos[2], \ renderer.M) # Get position of label labeldeltas = [ info['ticklabel']['space_factor'] * x for x in deltas ] axmask = [True, True, True] axmask[index] = False pos[tickdir] = edgep1[tickdir] pos = move_from_center(pos, centers, labeldeltas, axmask) lx, ly, lz = proj3d.proj_transform(pos[0], pos[1], pos[2], \ renderer.M) tick_update_position(tick, (x1, x2), (y1, y2), (lx, ly)) tick.set_label1(label) tick.set_label2(label) tick.draw(renderer) renderer.close_group('axis3d')
def draw(self, renderer): self.label._transform = self.axes.transData renderer.open_group('axis3d') # code from XAxis majorTicks = self.get_major_ticks() majorLocs = self.major.locator() # filter locations here so that no extra grid lines are drawn interval = self.get_view_interval() majorLocs = [loc for loc in majorLocs if \ interval[0] < loc < interval[1]] self.major.formatter.set_locs(majorLocs) majorLabels = [ self.major.formatter(val, i) for i, val in enumerate(majorLocs) ] # Determine bounds minx, maxx, miny, maxy, minz, maxz = self.axes.get_w_lims() mins = np.array((minx, miny, minz)) maxs = np.array((maxx, maxy, maxz)) centers = (maxs + mins) / 2. deltas = (maxs - mins) / 12. mins = mins - deltas / 4. maxs = maxs + deltas / 4. # Determine which planes should be visible by the avg z value vals = mins[0], maxs[0], mins[1], maxs[1], mins[2], maxs[2] tc = self.axes.tunit_cube(vals, renderer.M) #raise RuntimeError('WTF: p1=%s'%p1) avgz = [tc[p1][2] + tc[p2][2] + tc[p3][2] + tc[p4][2] for \ p1, p2, p3, p4 in self._PLANES] highs = np.array([avgz[2 * i] < avgz[2 * i + 1] for i in range(3)]) # Draw plane info = self._AXINFO[self.adir] index = info['i'] if not highs[index]: plane = self._PLANES[2 * index] else: plane = self._PLANES[2 * index + 1] xys = [tc[p] for p in plane] self.set_pane(xys, info['color']) self.pane.draw(renderer) # Determine grid lines minmax = np.where(highs, maxs, mins) # Draw main axis line juggled = art3d.juggle_axes(0, 2, 1, self.adir) edgep1 = minmax.copy() edgep1[juggled[0]] = get_flip_min_max(edgep1, juggled[0], mins, maxs) edgep2 = edgep1.copy() edgep2[juggled[1]] = get_flip_min_max(edgep2, juggled[1], mins, maxs) pep = proj3d.proj_trans_points([edgep1, edgep2], renderer.M) self.line.set_data((pep[0][0], pep[0][1]), (pep[1][0], pep[1][1])) self.line.draw(renderer) # Grid points where the planes meet xyz0 = [] for val in majorLocs: coord = minmax.copy() coord[index] = val xyz0.append(coord) # Draw labels dy = pep[1][1] - pep[1][0] dx = pep[0][1] - pep[0][0] lxyz = 0.5 * (edgep1 + edgep2) labeldeltas = 1.3 * deltas lxyz = move_from_center(lxyz, centers, labeldeltas) tlx, tly, tlz = proj3d.proj_transform(lxyz[0], lxyz[1], lxyz[2], \ renderer.M) self.label.set_position((tlx, tly)) if self.get_rotate_label(self.label.get_text()): angle = art3d.norm_text_angle(math.degrees(math.atan2(dy, dx))) self.label.set_rotation(angle) self.label.set_va('center') self.label.draw(renderer) # Grid points at end of one plane xyz1 = copy.deepcopy(xyz0) newindex = (index + 1) % 3 newval = get_flip_min_max(xyz1[0], newindex, mins, maxs) for i in range(len(majorLocs)): xyz1[i][newindex] = newval # Grid points at end of the other plane xyz2 = copy.deepcopy(xyz0) newindex = (index + 2) % 3 newval = get_flip_min_max(xyz2[0], newindex, mins, maxs) for i in range(len(majorLocs)): xyz2[i][newindex] = newval lines = zip(xyz1, xyz0, xyz2) if self.axes._draw_grid: self.gridlines.set_segments(lines) self.gridlines.set_color([(0.9, 0.9, 0.9, 1)] * len(lines)) self.gridlines.draw(renderer, project=True) # Draw ticks tickdir = info['tickdir'] tickdelta = deltas[tickdir] if highs[tickdir]: ticksign = 1 else: ticksign = -1 for tick, loc, label in zip(majorTicks, majorLocs, majorLabels): if tick is None: continue # Get tick line positions pos = copy.copy(edgep1) pos[index] = loc pos[tickdir] = edgep1[tickdir] + 0.1 * ticksign * tickdelta x1, y1, z1 = proj3d.proj_transform(pos[0], pos[1], pos[2], \ renderer.M) pos[tickdir] = edgep1[tickdir] - 0.2 * ticksign * tickdelta x2, y2, z2 = proj3d.proj_transform(pos[0], pos[1], pos[2], \ renderer.M) # Get position of label labeldeltas = [0.6 * x for x in deltas] axmask = [True, True, True] axmask[index] = False pos[tickdir] = edgep1[tickdir] pos = move_from_center(pos, centers, labeldeltas, axmask) lx, ly, lz = proj3d.proj_transform(pos[0], pos[1], pos[2], \ renderer.M) tick_update_position(tick, (x1, x2), (y1, y2), (lx, ly)) tick.set_label1(label) tick.set_label2(label) tick.draw(renderer) renderer.close_group('axis3d')
def draw(self, renderer): self.label._transform = self.axes.transData renderer.open_group('axis3d') # code from XAxis majorTicks = self.get_major_ticks() majorLocs = self.major.locator() info = self._axinfo index = info['i'] # filter locations here so that no extra grid lines are drawn locmin, locmax = self.get_view_interval() if locmin > locmax: locmin, locmax = locmax, locmin # Rudimentary clipping majorLocs = [loc for loc in majorLocs if locmin <= loc <= locmax] self.major.formatter.set_locs(majorLocs) majorLabels = [self.major.formatter(val, i) for i, val in enumerate(majorLocs)] mins, maxs, centers, deltas, tc, highs = self._get_coord_info(renderer) # Determine grid lines minmax = np.where(highs, maxs, mins) # Draw main axis line juggled = info['juggled'] edgep1 = minmax.copy() edgep1[juggled[0]] = get_flip_min_max(edgep1, juggled[0], mins, maxs) edgep2 = edgep1.copy() edgep2[juggled[1]] = get_flip_min_max(edgep2, juggled[1], mins, maxs) pep = proj3d.proj_trans_points([edgep1, edgep2], renderer.M) centpt = proj3d.proj_transform(centers[0], centers[1], centers[2], renderer.M) self.line.set_data((pep[0][0], pep[0][1]), (pep[1][0], pep[1][1])) self.line.draw(renderer) # Grid points where the planes meet xyz0 = [] for val in majorLocs: coord = minmax.copy() coord[index] = val xyz0.append(coord) # Draw labels peparray = np.asanyarray(pep) # The transAxes transform is used because the Text object # rotates the text relative to the display coordinate system. # Therefore, if we want the labels to remain parallel to the # axis regardless of the aspect ratio, we need to convert the # edge points of the plane to display coordinates and calculate # an angle from that. # TODO: Maybe Text objects should handle this themselves? dx, dy = (self.axes.transAxes.transform(peparray[0:2, 1]) - self.axes.transAxes.transform(peparray[0:2, 0])) lxyz = 0.5*(edgep1 + edgep2) labeldeltas = info['label']['space_factor'] * deltas axmask = [True, True, True] axmask[index] = False lxyz = move_from_center(lxyz, centers, labeldeltas, axmask) tlx, tly, tlz = proj3d.proj_transform(lxyz[0], lxyz[1], lxyz[2], \ renderer.M) self.label.set_position((tlx, tly)) if self.get_rotate_label(self.label.get_text()): angle = art3d.norm_text_angle(math.degrees(math.atan2(dy, dx))) self.label.set_rotation(angle) self.label.set_va(info['label']['va']) self.label.set_ha(info['label']['ha']) self.label.draw(renderer) # Draw Offset text # Which of the two edge points do we want to # use for locating the offset text? if juggled[2] == 2 : outeredgep = edgep1 outerindex = 0 else : outeredgep = edgep2 outerindex = 1 pos = copy.copy(outeredgep) pos = move_from_center(pos, centers, labeldeltas, axmask) olx, oly, olz = proj3d.proj_transform(pos[0], pos[1], pos[2], renderer.M) self.offsetText.set_text( self.major.formatter.get_offset() ) self.offsetText.set_position( (olx, oly) ) angle = art3d.norm_text_angle(math.degrees(math.atan2(dy, dx))) self.offsetText.set_rotation(angle) # Must set rotation mode to "anchor" so that # the alignment point is used as the "fulcrum" for rotation. self.offsetText.set_rotation_mode('anchor') #----------------------------------------------------------------------- # Note: the following statement for determining the proper alignment of # the offset text. This was determined entirely by trial-and-error # and should not be in any way considered as "the way". There are # still some edge cases where alignment is not quite right, but # this seems to be more of a geometry issue (in other words, I # might be using the wrong reference points). # # (TT, FF, TF, FT) are the shorthand for the tuple of # (centpt[info['tickdir']] <= peparray[info['tickdir'], outerindex], # centpt[index] <= peparray[index, outerindex]) # # Three-letters (e.g., TFT, FTT) are short-hand for the array # of bools from the variable 'highs'. # --------------------------------------------------------------------- if centpt[info['tickdir']] > peparray[info['tickdir'], outerindex] : # if FT and if highs has an even number of Trues if (centpt[index] <= peparray[index, outerindex] and ((len(highs.nonzero()[0]) % 2) == 0)) : # Usually, this means align right, except for the FTT case, # in which offset for axis 1 and 2 are aligned left. if highs.tolist() == [False, True, True] and index in (1, 2) : align = 'left' else : align = 'right' else : # The FF case align = 'left' else : # if TF and if highs has an even number of Trues if (centpt[index] > peparray[index, outerindex] and ((len(highs.nonzero()[0]) % 2) == 0)) : # Usually mean align left, except if it is axis 2 if index == 2 : align = 'right' else : align = 'left' else : # The TT case align = 'right' self.offsetText.set_va('center') self.offsetText.set_ha(align) self.offsetText.draw(renderer) # Draw grid lines if len(xyz0) > 0: # Grid points at end of one plane xyz1 = copy.deepcopy(xyz0) newindex = (index + 1) % 3 newval = get_flip_min_max(xyz1[0], newindex, mins, maxs) for i in range(len(majorLocs)): xyz1[i][newindex] = newval # Grid points at end of the other plane xyz2 = copy.deepcopy(xyz0) newindex = (index + 2) % 3 newval = get_flip_min_max(xyz2[0], newindex, mins, maxs) for i in range(len(majorLocs)): xyz2[i][newindex] = newval lines = zip(xyz1, xyz0, xyz2) if self.axes._draw_grid: self.gridlines.set_segments(lines) self.gridlines.set_color([info['grid']['color']] * len(lines)) self.gridlines.draw(renderer, project=True) # Draw ticks tickdir = info['tickdir'] tickdelta = deltas[tickdir] if highs[tickdir]: ticksign = 1 else: ticksign = -1 for tick, loc, label in zip(majorTicks, majorLocs, majorLabels): if tick is None: continue # Get tick line positions pos = copy.copy(edgep1) pos[index] = loc pos[tickdir] = edgep1[tickdir] + info['tick']['outward_factor'] * \ ticksign * tickdelta x1, y1, z1 = proj3d.proj_transform(pos[0], pos[1], pos[2], \ renderer.M) pos[tickdir] = edgep1[tickdir] - info['tick']['inward_factor'] * \ ticksign * tickdelta x2, y2, z2 = proj3d.proj_transform(pos[0], pos[1], pos[2], \ renderer.M) # Get position of label labeldeltas = [info['ticklabel']['space_factor'] * x for x in deltas] axmask = [True, True, True] axmask[index] = False pos[tickdir] = edgep1[tickdir] pos = move_from_center(pos, centers, labeldeltas, axmask) lx, ly, lz = proj3d.proj_transform(pos[0], pos[1], pos[2], \ renderer.M) tick_update_position(tick, (x1, x2), (y1, y2), (lx, ly)) tick.set_label1(label) tick.set_label2(label) tick.draw(renderer) renderer.close_group('axis3d')
def draw(self, renderer): self.label._transform = self.axes.transData renderer.open_group('axis3d') # code from XAxis majorTicks = self.get_major_ticks() majorLocs = self.major.locator() info = self._AXINFO[self.adir] index = info['i'] # filter locations here so that no extra grid lines are drawn interval = self.get_view_interval() majorLocs = [loc for loc in majorLocs if \ interval[0] <= loc <= interval[1]] self.major.formatter.set_locs(majorLocs) majorLabels = [self.major.formatter(val, i) for i, val in enumerate(majorLocs)] mins, maxs, centers, deltas, tc, highs = self._get_coord_info(renderer) # Determine grid lines minmax = np.where(highs, maxs, mins) # Draw main axis line juggled = info['juggled'] edgep1 = minmax.copy() edgep1[juggled[0]] = get_flip_min_max(edgep1, juggled[0], mins, maxs) edgep2 = edgep1.copy() edgep2[juggled[1]] = get_flip_min_max(edgep2, juggled[1], mins, maxs) pep = proj3d.proj_trans_points([edgep1, edgep2], renderer.M) self.line.set_data((pep[0][0], pep[0][1]), (pep[1][0], pep[1][1])) self.line.draw(renderer) # Grid points where the planes meet xyz0 = [] for val in majorLocs: coord = minmax.copy() coord[index] = val xyz0.append(coord) # Draw labels peparray = np.asanyarray(pep) # The transAxes transform is used because the Text object # rotates the text relative to the display coordinate system. # Therefore, if we want the labels to remain parallel to the # axis regardless of the aspect ratio, we need to convert the # edge points of the plane to display coordinates and calculate # an angle from that. # TODO: Maybe Text objects should handle this themselves? dx, dy = (self.axes.transAxes.transform(peparray[0:2, 1]) - self.axes.transAxes.transform(peparray[0:2, 0])) lxyz = 0.5*(edgep1 + edgep2) labeldeltas = 1.3 * deltas axmask = [True, True, True] axmask[index] = False lxyz = move_from_center(lxyz, centers, labeldeltas, axmask) tlx, tly, tlz = proj3d.proj_transform(lxyz[0], lxyz[1], lxyz[2], \ renderer.M) self.label.set_position((tlx, tly)) if self.get_rotate_label(self.label.get_text()): angle = art3d.norm_text_angle(math.degrees(math.atan2(dy, dx))) self.label.set_rotation(angle) self.label.set_va('center') self.label.set_ha('center') self.label.draw(renderer) # Grid points at end of one plane xyz1 = copy.deepcopy(xyz0) newindex = (index + 1) % 3 newval = get_flip_min_max(xyz1[0], newindex, mins, maxs) for i in range(len(majorLocs)): xyz1[i][newindex] = newval # Grid points at end of the other plane xyz2 = copy.deepcopy(xyz0) newindex = (index + 2) % 3 newval = get_flip_min_max(xyz2[0], newindex, mins, maxs) for i in range(len(majorLocs)): xyz2[i][newindex] = newval lines = zip(xyz1, xyz0, xyz2) if self.axes._draw_grid: self.gridlines.set_segments(lines) self.gridlines.set_color([(0.9,0.9,0.9,1)] * len(lines)) self.gridlines.draw(renderer, project=True) # Draw ticks tickdir = info['tickdir'] tickdelta = deltas[tickdir] if highs[tickdir]: ticksign = 1 else: ticksign = -1 for tick, loc, label in zip(majorTicks, majorLocs, majorLabels): if tick is None: continue # Get tick line positions pos = copy.copy(edgep1) pos[index] = loc pos[tickdir] = edgep1[tickdir] + 0.1 * ticksign * tickdelta x1, y1, z1 = proj3d.proj_transform(pos[0], pos[1], pos[2], \ renderer.M) pos[tickdir] = edgep1[tickdir] - 0.2 * ticksign * tickdelta x2, y2, z2 = proj3d.proj_transform(pos[0], pos[1], pos[2], \ renderer.M) # Get position of label labeldeltas = [0.6 * x for x in deltas] axmask = [True, True, True] axmask[index] = False pos[tickdir] = edgep1[tickdir] pos = move_from_center(pos, centers, labeldeltas, axmask) lx, ly, lz = proj3d.proj_transform(pos[0], pos[1], pos[2], \ renderer.M) tick_update_position(tick, (x1, x2), (y1, y2), (lx, ly)) tick.set_label1(label) tick.set_label2(label) tick.draw(renderer) renderer.close_group('axis3d')
def draw(self, renderer): self.label._transform = self.axes.transData renderer.open_group('axis3d') majorTicks = self.get_major_ticks() majorLocs = self.major.locator() interval = self.get_view_interval() majorLocs = [loc for loc in majorLocs if \ interval[0] < loc < interval[1]] self.major.formatter.set_locs(majorLocs) majorLabels = [self.major.formatter(val, i) for i, val in enumerate(majorLocs)] minx, maxx, miny, maxy, minz, maxz = self.axes.get_w_lims() mins = np.array((minx, miny, minz)) maxs = np.array((maxx, maxy, maxz)) centers = (maxs + mins) / 2. deltas = (maxs - mins) / 12. mins = mins - deltas / 4. maxs = maxs + deltas / 4. vals = mins[0], maxs[0], mins[1], maxs[1], mins[2], maxs[2] tc = self.axes.tunit_cube(vals, renderer.M) avgz = [tc[p1][2] + tc[p2][2] + tc[p3][2] + tc[p4][2] for \ p1, p2, p3, p4 in self._PLANES] highs = np.array([avgz[2*i] < avgz[2*i+1] for i in range(3)]) info = self._AXINFO[self.adir] index = info['i'] if not highs[index]: plane = self._PLANES[2 * index] else: plane = self._PLANES[2 * index + 1] xys = [tc[p] for p in plane] self.set_pane(xys, info['color']) self.pane.draw(renderer) minmax = np.where(highs, maxs, mins) juggled = art3d.juggle_axes(0, 2, 1, self.adir) edgep1 = minmax.copy() edgep1[juggled[0]] = get_flip_min_max(edgep1, juggled[0], mins, maxs) edgep2 = edgep1.copy() edgep2[juggled[1]] = get_flip_min_max(edgep2, juggled[1], mins, maxs) pep = proj3d.proj_trans_points([edgep1, edgep2], renderer.M) self.line.set_data((pep[0][0], pep[0][1]), (pep[1][0], pep[1][1])) self.line.draw(renderer) xyz0 = [] for val in majorLocs: coord = minmax.copy() coord[index] = val xyz0.append(coord) dy = pep[1][1] - pep[1][0] dx = pep[0][1] - pep[0][0] lxyz = 0.5*(edgep1 + edgep2) labeldeltas = 1.3 * deltas lxyz = move_from_center(lxyz, centers, labeldeltas) tlx, tly, tlz = proj3d.proj_transform(lxyz[0], lxyz[1], lxyz[2], \ renderer.M) self.label.set_position((tlx, tly)) if self.get_rotate_label(self.label.get_text()): angle = art3d.norm_text_angle(math.degrees(math.atan2(dy, dx))) self.label.set_rotation(angle) self.label.set_va('center') self.label.draw(renderer) xyz1 = copy.deepcopy(xyz0) newindex = (index + 1) % 3 newval = get_flip_min_max(xyz1[0], newindex, mins, maxs) for i in range(len(majorLocs)): xyz1[i][newindex] = newval xyz2 = copy.deepcopy(xyz0) newindex = (index + 2) % 3 newval = get_flip_min_max(xyz2[0], newindex, mins, maxs) for i in range(len(majorLocs)): xyz2[i][newindex] = newval lines = zip(xyz1, xyz0, xyz2) if self.axes._draw_grid: self.gridlines.set_segments(lines) self.gridlines.set_color([(0.9,0.9,0.9,1)] * len(lines)) self.gridlines.draw(renderer, project=True) tickdir = info['tickdir'] tickdelta = deltas[tickdir] if highs[tickdir]: ticksign = 1 else: ticksign = -1 for tick, loc, label in zip(majorTicks, majorLocs, majorLabels): if tick is None: continue pos = copy.copy(edgep1) pos[index] = loc pos[tickdir] = edgep1[tickdir] + 0.1 * ticksign * tickdelta x1, y1, z1 = proj3d.proj_transform(pos[0], pos[1], pos[2], \ renderer.M) pos[tickdir] = edgep1[tickdir] - 0.2 * ticksign * tickdelta x2, y2, z2 = proj3d.proj_transform(pos[0], pos[1], pos[2], \ renderer.M) labeldeltas = [0.6 * x for x in deltas] axmask = [True, True, True] axmask[index] = False pos[tickdir] = edgep1[tickdir] pos = move_from_center(pos, centers, labeldeltas, axmask) lx, ly, lz = proj3d.proj_transform(pos[0], pos[1], pos[2], \ renderer.M) tick_update_position(tick, (x1, x2), (y1, y2), (lx, ly)) tick.set_label1(label) tick.set_label2(label) tick.draw(renderer) renderer.close_group('axis3d')
def draw(self, renderer): self.label._transform = self.axes.transData renderer.open_group("axis3d") # code from XAxis majorTicks = self.get_major_ticks() majorLocs = self.major.locator() info = self._AXINFO[self.adir] index = info["i"] # filter locations here so that no extra grid lines are drawn interval = self.get_view_interval() majorLocs = [loc for loc in majorLocs if interval[0] <= loc <= interval[1]] self.major.formatter.set_locs(majorLocs) majorLabels = [self.major.formatter(val, i) for i, val in enumerate(majorLocs)] mins, maxs, centers, deltas, tc, highs = self._get_coord_info(renderer) # Determine grid lines minmax = np.where(highs, maxs, mins) # Draw main axis line juggled = info["juggled"] edgep1 = minmax.copy() edgep1[juggled[0]] = get_flip_min_max(edgep1, juggled[0], mins, maxs) edgep2 = edgep1.copy() edgep2[juggled[1]] = get_flip_min_max(edgep2, juggled[1], mins, maxs) pep = proj3d.proj_trans_points([edgep1, edgep2], renderer.M) self.line.set_data((pep[0][0], pep[0][1]), (pep[1][0], pep[1][1])) self.line.draw(renderer) # Grid points where the planes meet xyz0 = [] for val in majorLocs: coord = minmax.copy() coord[index] = val xyz0.append(coord) # Draw labels dy = pep[1][1] - pep[1][0] dx = pep[0][1] - pep[0][0] lxyz = 0.5 * (edgep1 + edgep2) labeldeltas = 1.3 * deltas lxyz = move_from_center(lxyz, centers, labeldeltas) tlx, tly, tlz = proj3d.proj_transform(lxyz[0], lxyz[1], lxyz[2], renderer.M) self.label.set_position((tlx, tly)) if self.get_rotate_label(self.label.get_text()): angle = art3d.norm_text_angle(math.degrees(math.atan2(dy, dx))) self.label.set_rotation(angle) self.label.set_va("center") self.label.draw(renderer) # Grid points at end of one plane xyz1 = copy.deepcopy(xyz0) newindex = (index + 1) % 3 newval = get_flip_min_max(xyz1[0], newindex, mins, maxs) for i in range(len(majorLocs)): xyz1[i][newindex] = newval # Grid points at end of the other plane xyz2 = copy.deepcopy(xyz0) newindex = (index + 2) % 3 newval = get_flip_min_max(xyz2[0], newindex, mins, maxs) for i in range(len(majorLocs)): xyz2[i][newindex] = newval lines = zip(xyz1, xyz0, xyz2) if self.axes._draw_grid: self.gridlines.set_segments(lines) self.gridlines.set_color([(0.9, 0.9, 0.9, 1)] * len(lines)) self.gridlines.draw(renderer, project=True) # Draw ticks tickdir = info["tickdir"] tickdelta = deltas[tickdir] if highs[tickdir]: ticksign = 1 else: ticksign = -1 for tick, loc, label in zip(majorTicks, majorLocs, majorLabels): if tick is None: continue # Get tick line positions pos = copy.copy(edgep1) pos[index] = loc pos[tickdir] = edgep1[tickdir] + 0.1 * ticksign * tickdelta x1, y1, z1 = proj3d.proj_transform(pos[0], pos[1], pos[2], renderer.M) pos[tickdir] = edgep1[tickdir] - 0.2 * ticksign * tickdelta x2, y2, z2 = proj3d.proj_transform(pos[0], pos[1], pos[2], renderer.M) # Get position of label labeldeltas = [0.6 * x for x in deltas] axmask = [True, True, True] axmask[index] = False pos[tickdir] = edgep1[tickdir] pos = move_from_center(pos, centers, labeldeltas, axmask) lx, ly, lz = proj3d.proj_transform(pos[0], pos[1], pos[2], renderer.M) tick_update_position(tick, (x1, x2), (y1, y2), (lx, ly)) tick.set_label1(label) tick.set_label2(label) tick.draw(renderer) renderer.close_group("axis3d")