def display_points(self, view): visible_points_coords = self.database.get_visible_points_coords( view.current_image) self.clear_artists(view) for point_id, coords in visible_points_coords.items(): color = distinct_colors[divmod(hash(point_id), 19)[1]] text_path = TextPath((0, 0), point_id, size=10) p1 = PathPatch(text_path, transform=IdentityTransform(), alpha=1, color=color) offsetbox2 = AuxTransformBox(IdentityTransform()) offsetbox2.add_artist(p1) ab = AnnotationBbox(offsetbox2, ((coords[0] + 30), (coords[1] + 30)), bboxprops=dict(alpha=0.05)) circle = mpatches.Circle((coords[0], coords[1]), 10, color=color, fill=False) dot = mpatches.Circle((coords[0], coords[1]), 2, color=color, fill=False) for art in (ab, circle, dot): view.plt_artists.append(art) view.subplot.add_artist(art) view.figure.canvas.draw()
def display_points(self, image_idx, image): visible_points_coords = self.database.get_visible_points_coords(image) self.clear_images(image_idx) for point_id, coords in visible_points_coords.items(): color = distinct_colors[divmod(hash(point_id), 19)[1]] text_path = TextPath((0, 0), point_id, size=10) p1 = PathPatch(text_path, transform=IdentityTransform(), alpha=1, color=color) offsetbox2 = AuxTransformBox(IdentityTransform()) offsetbox2.add_artist(p1) ab = AnnotationBbox(offsetbox2, ((coords[0] + 30), (coords[1] + 30)), bboxprops=dict(alpha=0.05)) circle = mpatches.Circle((coords[0], coords[1]), 20, color=color, fill=False) self.plt_artists[image_idx].append(ab) self.plt_artists[image_idx].append(circle) self.subplots[image_idx].add_artist(ab) self.subplots[image_idx].add_artist(circle) self.figures[image_idx].canvas.draw_idle()
def _set_lim_and_transforms(self): self.transAxes = BboxTransformTo(self.bbox) # Transforms the x and y axis separately by a scale factor # It is assumed that this part will have non-linear components self.transScale = TransformWrapper(IdentityTransform()) # A (possibly non-linear) projection on the (already scaled) # data. This one is aware of rmin self.transProjection = self.PolarTransform(self) # This one is not aware of rmin self.transPureProjection = self.PolarTransform() # An affine transformation on the data, generally to limit the # range of the axes self.transProjectionAffine = self.PolarAffine(self.transScale, self.viewLim) # The complete data transformation stack -- from data all the # way to display coordinates self.transData = self.transScale + self.transProjection + \ (self.transProjectionAffine + self.transAxes) # This is the transform for theta-axis ticks. It is # equivalent to transData, except it always puts r == 1.0 at # the edge of the axis circle. self._xaxis_transform = ( self.transPureProjection + self.PolarAffine(IdentityTransform(), Bbox.unit()) + self.transAxes) # The theta labels are moved from radius == 0.0 to radius == 1.1 self._theta_label1_position = Affine2D().translate(0.0, 1.1) self._xaxis_text1_transform = ( self._theta_label1_position + self._xaxis_transform) self._theta_label2_position = Affine2D().translate(0.0, 1.0 / 1.1) self._xaxis_text2_transform = ( self._theta_label2_position + self._xaxis_transform) # This is the transform for r-axis ticks. It scales the theta # axis so the gridlines from 0.0 to 1.0, now go from 0.0 to # 2pi. self._yaxis_transform = ( Affine2D().scale(np.pi * 2.0, 1.0) + self.transData) # The r-axis labels are put at an angle and padded in the r-direction self._r_label1_position = Affine2D().translate(22.5, self._rpad) self._yaxis_text1_transform = ( self._r_label1_position + Affine2D().scale(1.0 / 360.0, 1.0) + self._yaxis_transform ) self._r_label2_position = Affine2D().translate(22.5, self._rpad) self._yaxis_text2_transform = ( self._r_label2_position + Affine2D().scale(1.0 / 360.0, 1.0) + self._yaxis_transform )
def text_banner(axes, text, facecolor="red", edgecolor="darkred", linewidth=1, alpha=0.3, angleadjust=True, zorder=0): """ Paint text across a hole axes. For height > width, angleadjust should be False. """ # draw the text into a patch textpath = TextPath((0, 0), text, size=20, transform=axes.transAxes) tp_bbox = textpath.get_extents() patch = PathPatch(textpath, fc=facecolor, ec=edgecolor, lw=linewidth, alpha=alpha, transform=IdentityTransform(), zorder=11) # get angle and scale to transform text to axes coordinates ax_bbox = axes.get_window_extent() angle = math.atan2(ax_bbox.height, ax_bbox.width) * \ (ax_bbox.height/ax_bbox.width if angleadjust else 1) scale = min(*rotated_scale(tp_bbox.width, tp_bbox.height, angle, ax_bbox.width, ax_bbox.height))*0.95 # paint the patch into the axes offsetbox = AuxTransformBox(Affine2D().rotate(angle).scale(scale)) offsetbox.add_artist(patch) artist = AnnotationBbox(offsetbox, (0.5, 0.5), xycoords='axes fraction', frameon=False) artist.set_zorder(zorder) axes.add_artist(artist)
def _set_lim_and_transforms(self): """ Overrides the method with the same name in the PolarAxes-class. This method replaces the same method in the PolarAxes-class. It ensures that the limits and label placement fit the north-polar projection. """ PolarAxes._set_lim_and_transforms(self) self.transProjection = self.NorthPolarTransform() # pylint: attribute-defined-outside-init,invalid-name self.transData = (self.transScale + self.transProjection + (self.transProjectionAffine + self.transAxes)) # pylint: attribute-defined-outside-init,invalid-name self._xaxis_transform = ( self.transProjection + self.PolarAffine(IdentityTransform(), Bbox.unit()) + self.transAxes ) # pylint: attribute-defined-outside-init self._xaxis_text1_transform = ( self._theta_label1_position + self._xaxis_transform ) # pylint: attribute-defined-outside-init self._yaxis_transform = (Affine2D().scale(np.pi * 2.0, 1.0) + self.transData ) # pylint: attribute-defined-outside-init self._yaxis_text1_transform = ( Affine2D().scale(1.0 / 360.0, 1.0) + self._yaxis_transform ) # pylint: attribute-defined-outside-init
def __init__(self, ax): """ :param ax: A matplotlib Axes object to attach the graphical ROI to """ AbstractMplRoi.__init__(self, ax) self.plot_opts = { 'edgecolor': PATCH_COLOR, 'facecolor': PATCH_COLOR, 'alpha': 0.3 } self._xi = None self._yi = None self._patch = Ellipse( (0., 0.), transform=IdentityTransform(), width=0., height=0., ) self._patch.set_zorder(100) self._patch.set(**self.plot_opts) self._ax.add_patch(self._patch) self._sync_patch()
def __init__(self, fig, labelstr, props=None, hoverprops=None, on_select=None): super().__init__() self.set_figure(fig) self.labelstr = labelstr self.props = props if props is not None else ItemProperties() self.hoverprops = (hoverprops if hoverprops is not None else ItemProperties()) if self.props.fontsize != self.hoverprops.fontsize: raise NotImplementedError( 'support for different font sizes not implemented') self.on_select = on_select # Setting the transform to IdentityTransform() lets us specify # coordinates directly in pixels. self.label = fig.text(0, 0, labelstr, transform=IdentityTransform(), size=props.fontsize) self.text_bbox = self.label.get_window_extent( fig.canvas.get_renderer()) self.rect = patches.Rectangle((0, 0), 1, 1) # Will be updated later. self.set_hover_props(False) fig.canvas.mpl_connect('button_release_event', self.check_select)
def chunk_limit_setup(): N = 100_000 dpi = 500 w = 5 * dpi h = 6 * dpi # just fit in the width x = np.linspace(0, w, N) # and go top-to-bottom y = np.ones(N) * h y[::2] = 0 idt = IdentityTransform() # make a renderer ra = RendererAgg(w, h, dpi) # setup the minimal gc to draw a line gc = ra.new_gc() gc.set_linewidth(1) gc.set_foreground('r') # make a Path p = Path(np.vstack((x, y)).T) # effectively disable path simplification (but leaving it "on") p.simplify_threshold = 0 return ra, gc, p, idt
def test_ParasiteAxesAuxTrans(): # Remove this line when this test image is regenerated. plt.rcParams['pcolormesh.snap'] = False data = np.ones((6, 6)) data[2, 2] = 2 data[0, :] = 0 data[-2, :] = 0 data[:, 0] = 0 data[:, -2] = 0 x = np.arange(6) y = np.arange(6) xx, yy = np.meshgrid(x, y) funcnames = ['pcolor', 'pcolormesh', 'contourf'] fig = plt.figure() for i, name in enumerate(funcnames): ax1 = SubplotHost(fig, 1, 3, i + 1) fig.add_subplot(ax1) ax2 = ParasiteAxes(ax1, IdentityTransform()) ax1.parasites.append(ax2) if name.startswith('pcolor'): getattr(ax2, name)(xx, yy, data[:-1, :-1]) else: getattr(ax2, name)(xx, yy, data) ax1.set_xlim((0, 5)) ax1.set_ylim((0, 5)) ax2.contour(xx, yy, data, colors='k')
def __init__(self, bbox, **kwargs): if "transform" in kwargs: raise ValueError("transform should not be set") kwargs["transform"] = IdentityTransform() Patch.__init__(self, **kwargs) self.bbox = bbox
def _set_lim_and_transforms(self): PolarAxes._set_lim_and_transforms(self) try: theta_position = self._theta_label1_position except AttributeError: theta_position = self.get_theta_offset() self.transProjection = self.GlobeCrossSectionTransform() self.transData = ( self.transScale + self.transProjection + (self.transProjectionAffine + self.transAxes)) self._xaxis_transform = ( self.transProjection + self.PolarAffine(IdentityTransform(), Bbox.unit()) + self.transAxes) self._xaxis_text1_transform = ( theta_position + self._xaxis_transform) self._yaxis_transform = ( Affine2D().scale(num.pi * 2.0, 1.0) + self.transData) try: rlp = getattr(self, '_r_label1_position') except AttributeError: rlp = getattr(self, '_r_label_position') self._yaxis_text1_transform = ( rlp + Affine2D().scale(1.0 / 360.0, 1.0) + self._yaxis_transform)
def mocked_axes(extent, projection=ccrs.PlateCarree()): return mock.MagicMock(get_extent=mock.Mock(return_value=extent), projection=projection, spec=geoaxes.GeoAxes, transData=IdentityTransform(), patch=mock.sentinel.patch, figure=mock.sentinel.figure)
def make_image(self, renderer, magnification=1.0, unsampled=False): if self._A is None: raise RuntimeError('You must first set the image array') if unsampled: raise ValueError('unsampled not supported on PColorImage') fc = self.axes.patch.get_facecolor() bg = mcolors.to_rgba(fc, 0) bg = (np.array(bg)*255).astype(np.uint8) l, b, r, t = self.axes.bbox.extents width = (np.round(r) + 0.5) - (np.round(l) - 0.5) height = (np.round(t) + 0.5) - (np.round(b) - 0.5) # The extra cast-to-int is only needed for python2 width = int(np.round(width * magnification)) height = int(np.round(height * magnification)) if self._rgbacache is None: A = self.to_rgba(self._A, bytes=True) self._rgbacache = A if self._A.ndim == 2: self.is_grayscale = self.cmap.is_gray() else: A = self._rgbacache vl = self.axes.viewLim im = _image.pcolor2(self._Ax, self._Ay, A, height, width, (vl.x0, vl.x1, vl.y0, vl.y1), bg) return im, l, b, IdentityTransform()
def test_ParasiteAxesAuxTrans(): data = np.ones((6, 6)) data[2, 2] = 2 data[0, :] = 0 data[-2, :] = 0 data[:, 0] = 0 data[:, -2] = 0 x = np.arange(6) y = np.arange(6) xx, yy = np.meshgrid(x, y) funcnames = ['pcolor', 'pcolormesh', 'contourf'] fig = plt.figure() for i, name in enumerate(funcnames): ax1 = SubplotHost(fig, 1, 3, i + 1) fig.add_subplot(ax1) ax2 = ParasiteAxesAuxTrans(ax1, IdentityTransform()) ax1.parasites.append(ax2) getattr(ax2, name)(xx, yy, data) ax1.set_xlim((0, 5)) ax1.set_ylim((0, 5)) ax2.contour(xx, yy, data, colors='k')
def _setup_patch(self): self._patch = Ellipse((0., 0.), transform=IdentityTransform(), width=0., height=0.,) self._patch.set_zorder(100) self._patch.set(**self.plot_opts) self._axes.add_patch(self._patch) self._patch.set_visible(False) self._sync_patch()
def test_ternary_perpendicular_transform(corners, index): np.random.seed(1986) points = np.random.rand(300).reshape(-1, 2) points /= np.sum(points, axis=1)[:, None] trans = TernaryPerpendicularTransform(IdentityTransform(), corners, index) points_transformed = trans.transform(points) np.testing.assert_almost_equal( points, trans.inverted().transform(points_transformed))
def _init_bbox_image(self, im): bbox_image = BboxImage(self.get_window_extent, norm=None, origin=None, ) bbox_image.set_transform(IdentityTransform()) bbox_image.set_data(im) self.bbox_image = bbox_image
def _init_offsetText(self, direction): x, y, va, ha = self._offsetText_pos[direction] self.offsetText = mtext.Annotation( "", xy=(x, y), xycoords="axes fraction", xytext=(0, 0), textcoords="offset points", color=rcParams['xtick.color'], horizontalalignment=ha, verticalalignment=va, ) self.offsetText.set_transform(IdentityTransform()) self.axes._set_artist_props(self.offsetText)
def _set_lim_and_transforms(self): PolarAxes._set_lim_and_transforms(self) self.transProjection = self.GalPolarTransform() self.transData = (self.transScale + self.transProjection + (self.transProjectionAffine + self.transAxes)) self._xaxis_transform = (self.transProjection + self.PolarAffine( IdentityTransform(), Bbox.unit()) + self.transAxes) self._xaxis_text1_transform = (self._theta_label1_position + self._xaxis_transform) self._yaxis_transform = (Affine2D().scale(sc.pi * 2.0, 1.0) + self.transData) self._yaxis_text1_transform = (self._r_label1_position + Affine2D().scale(1.0 / 360.0, 1.0) + self._yaxis_transform)
def _get_text(txt, x, y, dx, dy, ha="center", va="center", **kwargs): if "color" in kwargs: textcolor = kwargs["color"] elif "markeredgecolor" in kwargs: textcolor = kwargs["markeredgecolor"] ann = Annotation(txt, (x, y), xytext=(dx, dy), xycoords='data', textcoords="offset points", ha=ha, va=va, **kwargs) ann.set_transform(IdentityTransform()) return ann
def __init__(self, axes): super(MplCircularROI, self).__init__(axes) self.plot_opts = {'edgecolor': PATCH_COLOR, 'facecolor': PATCH_COLOR, 'alpha': 0.3} self._xi = None self._yi = None self._patch = Ellipse((0., 0.), transform=IdentityTransform(), width=0., height=0., zorder=100) self._patch.set_visible(False) self._axes.add_patch(self._patch)
def __init__(self, center, width, height, thick, angle=0.0, **kwargs): """ Draw an elliptical ring centered at *x*, *y* center with outer width (horizontal diameter) *width* and outer height (vertical diameter) *height* with a ring thickness of *thick* Valid kwargs are: %(Patch)s """ super().__init__(**kwargs) self.center = center self.height, self.width = height, width self.thick = thick self.angle = angle self._recompute_path() # Note: This cannot be calculated until this is added to an Axes self._patch_transform = IdentityTransform()
def _get_text(txt, x, y, dx, dy, ha="center", va="center", **kwargs): if "color" in kwargs: textcolor = kwargs["color"] del kwargs["color"] elif "markeredgecolor" in kwargs: textcolor = kwargs["markeredgecolor"] else: import matplotlib as mpl textcolor = mpl.rcParams['text.color'] ann = Annotation(txt, (x, y), xytext=(dx, dy), xycoords='data', textcoords="offset points", color=textcolor, ha=ha, va=va, **kwargs) ann.set_transform(IdentityTransform()) return ann
def __init__(self, axis_artist, line_path, transform, line_mutation_scale): self._axis_artist = axis_artist self._line_transform = transform self._line_path = line_path self._line_mutation_scale = line_mutation_scale FancyArrowPatch.__init__(self, path=self._line_path, arrowstyle=self._ARROW_STYLE, patchA=None, patchB=None, shrinkA=0., shrinkB=0., mutation_scale=line_mutation_scale, mutation_aspect=None, transform=IdentityTransform(), )
def __init__(self, bbox1, bbox2, loc1, loc2=None, **kwargs): """ Connect two bboxes with a straight line. Parameters ---------- bbox1, bbox2 : `matplotlib.transforms.Bbox` Bounding boxes to connect. loc1 : {1, 2, 3, 4} Corner of *bbox1* to draw the line. Valid values are:: 'upper right' : 1, 'upper left' : 2, 'lower left' : 3, 'lower right' : 4 loc2 : {1, 2, 3, 4}, optional Corner of *bbox2* to draw the line. If None, defaults to *loc1*. Valid values are:: 'upper right' : 1, 'upper left' : 2, 'lower left' : 3, 'lower right' : 4 **kwargs Patch properties for the line drawn. Valid arguments include: %(Patch:kwdoc)s """ if "transform" in kwargs: raise ValueError("transform should not be set") kwargs["transform"] = IdentityTransform() if 'fill' in kwargs: super().__init__(**kwargs) else: fill = bool({'fc', 'facecolor', 'color'}.intersection(kwargs)) super().__init__(fill=fill, **kwargs) self.bbox1 = bbox1 self.bbox2 = bbox2 self.loc1 = loc1 self.loc2 = loc2
def __init__(self, bbox, **kwargs): """ Patch showing the shape bounded by a Bbox. Parameters ---------- bbox : `matplotlib.transforms.Bbox` Bbox to use for the extents of this patch. **kwargs Patch properties. Valid arguments include: %(Patch)s """ if "transform" in kwargs: raise ValueError("transform should not be set") kwargs["transform"] = IdentityTransform() Patch.__init__(self, **kwargs) self.bbox = bbox
def get_patches(self, ax): ranges = LineCollection(self._cap_ranges, linestyle="solid") links = LineCollection(self._oob_links, linestyle="dotted", colors=colorConverter.to_rgba_array("#808080")) color = colorConverter.to_rgba_array("#DC143C") scales = np.array((20, )) marker_obj = MarkerStyle("o") path = marker_obj.get_path().transformed(marker_obj.get_transform()) offsets = PathCollection((path, ), scales, facecolors=color, offsets=self._oob_offsets, transOffset=ax.transData) offsets.set_transform(IdentityTransform()) return [ranges, links, offsets]
def __init__(self, bbox, cmap=None, norm=None, interpolation=None, origin=None, filternorm=1, filterrad=4.0, resample=False, interp_at_native=True, **kwargs ): """ cmap is a colors.Colormap instance norm is a colors.Normalize instance to map luminance to 0-1 interp_at_native is a flag that determines whether or not interpolation should still be applied when the image is displayed at its native resolution. A common use case for this is when displaying an image for annotational purposes; it is treated similarly to Photoshop (interpolation is only used when displaying the image at non-native resolutions). kwargs are an optional list of Artist keyword args """ super(BboxImage, self).__init__( None, cmap=cmap, norm=norm, interpolation=interpolation, origin=origin, filternorm=filternorm, filterrad=filterrad, resample=resample, **kwargs ) self.bbox = bbox self.interp_at_native = interp_at_native self._transform = IdentityTransform()
def __init__(self, arr, reverse=True): from matplotlib.transforms import Affine2D, IdentityTransform from matplotlib.backends.backend_agg import RendererAgg self.arr = arr self.height, self.width, _ = self.arr.shape renderer = RendererAgg(self.width, self.height, 90) img = mpl.image.BboxImage(renderer.bbox) img.set_data(arr) img.draw(renderer) self.renderer = renderer if not reverse: self.trans_offset = self.trans = IdentityTransform() else: self.trans_offset = Affine2D().scale(1, -1) self.trans = Affine2D().scale(1, -1).translate(0, self.height) self.parameters = {}
def test_shorthand_inversion(): """Test that the Matplotlib subtraction shorthand for composing and inverting transformations works.""" w1 = WCS(naxis=2) w1.wcs.ctype = ['RA---TAN', 'DEC--TAN'] w1.wcs.crpix = [256.0, 256.0] w1.wcs.cdelt = [-0.05, 0.05] w1.wcs.crval = [120.0, -19.0] w2 = WCS(naxis=2) w2.wcs.ctype = ['RA---SIN', 'DEC--SIN'] w2.wcs.crpix = [256.0, 256.0] w2.wcs.cdelt = [-0.05, 0.05] w2.wcs.crval = [235.0, +23.7] t1 = WCSWorld2PixelTransform(w1) t2 = WCSWorld2PixelTransform(w2) assert t1 - t2 == t1 + t2.inverted() assert t1 - t2 != t2.inverted() + t1 assert t1 - t1 == IdentityTransform()