# xmax, xmin = xmax0, xmin0 print "splitting in y: child box", ((xmin, ymin), (xmax, ymax)) print "splitting in y: remaining box", ((xmin0, ymin0), (xmax0, ymax0)) else: print "splitting in x: starting box", ((xmin0, ymin0), (xmax0, ymax0)) # xmin, xmax = xmin0, xmin0 + deltay * arearatio - 1.*deltax * fbuffer / 80 xmin, xmax = xmax0 - deltax * arearatio + deltax * fbuffer / 40, xmax0 xmax0, xmin0 = xmax0 - deltax * arearatio - deltax * fbuffer / 40, xmin0 print "splitting in x: child box", ((xmin, ymin), (xmax, ymax)) print "splitting in x: remaining box", ((xmin0, ymin0), (xmax0, ymax0)) # recurse childbox = mtransforms.Bbox(((xmin, ymin), (xmax, ymax))) nodesets_rectangles((child, grandchildren), childbox) plot_box(bbox=childbox, attrs=attrs, label=label) def treesets_rectangles(tree): ((xmin, xmax), (ymin, ymax)) = [(0, 1), (0, 1)] superset = None ax = plt.gca() ax.set_aspect(1.0) ax.set_xlim(-0.1, 1.1) ax.set_ylim(-0.1, 1.1) ax.set_xticks([]) ax.set_yticks([]) plt.axis("off") # start with plotting root node
def make_axes(parents, location=None, orientation=None, fraction=0.15, shrink=1.0, aspect=20, **kw): ''' Resize and reposition parent axes, and return a child axes suitable for a colorbar:: cax, kw = make_axes(parent, **kw) Keyword arguments may include the following (with defaults): location : [`None`|'left'|'right'|'top'|'bottom'] The position, relative to **parents**, where the colorbar axes should be created. If None, the value will either come from the given ``orientation``, else it will default to 'right'. orientation : [`None`|'vertical'|'horizontal'] The orientation of the colorbar. Typically, this keyword shouldn't be used, as it can be derived from the ``location`` keyword. %s Returns (cax, kw), the child axes and the reduced kw dictionary to be passed when creating the colorbar instance. ''' locations = ["left", "right", "top", "bottom"] if orientation is not None and location is not None: msg = ('position and orientation are mutually exclusive. ' 'Consider setting the position to any of ' '{0}'.format(', '.join(locations))) raise TypeError(msg) # provide a default location if location is None and orientation is None: location = 'right' # allow the user to not specify the location by specifying the # orientation instead if location is None: location = 'right' if orientation == 'vertical' else 'bottom' if location not in locations: raise ValueError('Invalid colorbar location. Must be one ' 'of %s' % ', '.join(locations)) default_location_settings = {'left': {'anchor': (1.0, 0.5), 'panchor': (0.0, 0.5), 'pad': 0.10, 'orientation': 'vertical'}, 'right': {'anchor': (0.0, 0.5), 'panchor': (1.0, 0.5), 'pad': 0.05, 'orientation': 'vertical'}, 'top': {'anchor': (0.5, 0.0), 'panchor': (0.5, 1.0), 'pad': 0.05, 'orientation': 'horizontal'}, 'bottom': {'anchor': (0.5, 1.0), 'panchor': (0.5, 0.0), 'pad': 0.15, # backwards compat 'orientation': 'horizontal'}, } loc_settings = default_location_settings[location] # put appropriate values into the kw dict for passing back to # the Colorbar class kw['orientation'] = loc_settings['orientation'] kw['ticklocation'] = location anchor = kw.pop('anchor', loc_settings['anchor']) parent_anchor = kw.pop('panchor', loc_settings['panchor']) pad = kw.pop('pad', loc_settings['pad']) # turn parents into a list if it is not already if not isinstance(parents, (list, tuple)): parents = [parents] fig = parents[0].get_figure() if not all(fig is ax.get_figure() for ax in parents): raise ValueError('Unable to create a colorbar axes as not all ' 'parents share the same figure.') # take a bounding box around all of the given axes parents_bbox = mtrans.Bbox.union([ax.get_position(original=True).frozen() for ax in parents]) pb = parents_bbox if location in ('left', 'right'): if location == 'left': pbcb, _, pb1 = pb.splitx(fraction, fraction + pad) else: pb1, _, pbcb = pb.splitx(1 - fraction - pad, 1 - fraction) pbcb = pbcb.shrunk(1.0, shrink).anchored(anchor, pbcb) else: if location == 'bottom': pbcb, _, pb1 = pb.splity(fraction, fraction + pad) else: pb1, _, pbcb = pb.splity(1 - fraction - pad, 1 - fraction) pbcb = pbcb.shrunk(shrink, 1.0).anchored(anchor, pbcb) # define the aspect ratio in terms of y's per x rather than x's per y aspect = 1.0 / aspect # define a transform which takes us from old axes coordinates to # new axes coordinates shrinking_trans = mtrans.BboxTransform(parents_bbox, pb1) # transform each of the axes in parents using the new transform for ax in parents: new_posn = shrinking_trans.transform(ax.get_position()) new_posn = mtrans.Bbox(new_posn) ax.set_position(new_posn) if parent_anchor is not False: ax.set_anchor(parent_anchor) cax = fig.add_axes(pbcb) cax.set_aspect(aspect, anchor=anchor, adjustable='box') return cax, kw
0.95, u'Ausbreitungsrichtung\nbasierend auf vergangenen KFÜ-Daten', ha='center', va='center', fontsize=12, fontweight='bold') text.set_transform(fig.transFigure) "--------------------------- LEGENDE --------------------------------------" # ax4 ist fuer die Box um die Legendenbestandteile ax4 = fig.add_axes([0.0, 0.0, 1, 1], frameon=False) ax4.axes.get_yaxis().set_visible(False) ax4.axes.get_xaxis().set_visible(False) bb = mtransforms.Bbox([[0.01, 0.01], [0.99, 0.2]]) p_fancy = FancyBboxPatch((bb.xmin, bb.ymin), abs(bb.width), abs(bb.height), boxstyle="square, pad=0", fc='white', ec='black') p_fancy.set_transform(fig.transFigure) ax4.add_patch(p_fancy) # ax5 ist fuer die Legende des Freisetzungspunkts plus Text ax5 = fig.add_axes([0.01, 0.01, 0.8, 0.8], frameon=False) ax5.axes.get_yaxis().set_visible(False) ax5.axes.get_xaxis().set_visible(False)
@image_comparison(['test_bboxtight.png'], remove_text=True, style='mpl20', savefig_kwarg={'bbox_inches': 'tight'}) def test_bboxtight(): fig, ax = plt.subplots(constrained_layout=True) ax.set_aspect(1.) @image_comparison( ['test_bbox.png'], remove_text=True, style='mpl20', savefig_kwarg={'bbox_inches': mtransforms.Bbox([[0.5, 0], [2.5, 2]])}) def test_bbox(): fig, ax = plt.subplots(constrained_layout=True) ax.set_aspect(1.) def test_align_labels(): """ Tests for a bug in which constrained layout and align_ylabels on three unevenly sized subplots, one of whose y tick labels include negative numbers, drives the non-negative subplots' y labels off the edge of the plot """ fig, (ax3, ax1, ax2) = plt.subplots(3, 1,
def test_nan_overlap(): a = mtrans.Bbox([[0, 0], [1, 1]]) b = mtrans.Bbox([[0, 0], [1, np.nan]]) assert not a.overlaps(b)
def plot_barbs(self, p, u, v, c=None, xloc=1.0, x_clip_radius=0.1, y_clip_radius=0.08, **kwargs): r"""Plot wind barbs. Adds wind barbs to the skew-T plot. This is a wrapper around the `barbs` command that adds to appropriate transform to place the barbs in a vertical line, located as a function of pressure. Parameters ---------- p : array_like pressure values u : array_like U (East-West) component of wind v : array_like V (North-South) component of wind c: An optional array used to map colors to the barbs xloc : float, optional Position for the barbs, in normalized axes coordinates, where 0.0 denotes far left and 1.0 denotes far right. Defaults to far right. x_clip_radius : float, optional Space, in normalized axes coordinates, to leave before clipping wind barbs in the x-direction. Defaults to 0.1. y_clip_radius : float, optional Space, in normalized axes coordinates, to leave above/below plot before clipping wind barbs in the y-direction. Defaults to 0.08. plot_units: `pint.unit` Units to plot in (performing conversion if necessary). Defaults to given units. kwargs Other keyword arguments to pass to :func:`~matplotlib.pyplot.barbs` Returns ------- matplotlib.quiver.Barbs instance created See Also -------- :func:`matplotlib.pyplot.barbs` """ # If plot_units specified, convert the data to those units plotting_units = kwargs.pop('plot_units', None) if plotting_units: if hasattr(u, 'units') and hasattr(v, 'units'): u = u.to(plotting_units) v = v.to(plotting_units) else: raise ValueError( 'To convert to plotting units, units must be attached to ' 'u and v wind components.') # Assemble array of x-locations in axes space x = np.empty_like(p) x.fill(xloc) # Do barbs plot at this location if c is not None: b = self.ax.barbs( x, p, u, v, c, transform=self.ax.get_yaxis_transform(which='tick2'), clip_on=True, zorder=2, **kwargs) else: b = self.ax.barbs( x, p, u, v, transform=self.ax.get_yaxis_transform(which='tick2'), clip_on=True, zorder=2, **kwargs) # Override the default clip box, which is the axes rectangle, so we can have # barbs that extend outside. ax_bbox = transforms.Bbox([[xloc - x_clip_radius, -y_clip_radius], [xloc + x_clip_radius, 1.0 + y_clip_radius]]) b.set_clip_box(transforms.TransformedBbox(ax_bbox, self.ax.transAxes)) return b
def voronoi_finite_polygons_2d_box(vor, box): """ Reconstruct infinite voronoi regions in a 2D diagram to finite box. Parameters ---------- vor : Voronoi Input diagram box : (2,2) float array corners of bounding box numpy.array([[x1,y1],[x2,y2]]) Returns ------- poly : array of M (N,2) arrays polygon coordinates for M revised Voronoi regions. """ import matplotlib.transforms as mplTrans import matplotlib.path as mplPath if vor.points.shape[1] != 2: raise ValueError("Requires 2D input") if box.shape != (2, 2): raise ValueError("Bounding box should be 2x2 array ((x1,y1),(x2,y2))") radius = np.max(box) # define the bounding box transform from the box extent - to be used to intersect with the regions bbox = mplTrans.Bbox(box) new_regions = [] new_vertices = vor.vertices.tolist() center = vor.points.mean(axis=0) if radius is None: radius = vor.points.ptp().max() # Construct a map containing all ridges for a given point all_ridges = {} for (p1, p2), (v1, v2) in zip(vor.ridge_points, vor.ridge_vertices): all_ridges.setdefault(p1, []).append((p2, v1, v2)) all_ridges.setdefault(p2, []).append((p1, v1, v2)) # Reconstruct infinite regions for p1, region in enumerate(vor.point_region): vertices = vor.regions[region] if all(v >= 0 for v in vertices): # finite region new_regions.append(vertices) continue if all(v >= 0 for v in vertices): # finite region new_regions.append(vertices) continue # reconstruct a non-finite region ridges = all_ridges[p1] new_region = [v for v in vertices if v >= 0] for p2, v1, v2 in ridges: if v2 < 0: v1, v2 = v2, v1 if v1 >= 0: # finite ridge: already in the region continue # Compute the missing endpoint of an infinite ridge t = vor.points[p2] - vor.points[p1] # tangent t /= np.linalg.norm(t) n = np.array([-t[1], t[0]]) # normal midpoint = vor.points[[p1, p2]].mean(axis=0) direction = np.sign(np.dot(midpoint - center, n)) * n far_point = vor.vertices[v2] + direction * radius new_region.append(len(new_vertices)) new_vertices.append(far_point.tolist()) # sort region counterclockwise vs = np.asarray([new_vertices[v] for v in new_region]) c = vs.mean(axis=0) angles = np.arctan2(vs[:, 1] - c[1], vs[:, 0] - c[0]) new_region = np.array(new_region)[np.argsort(angles)] # finish new_regions.append(new_region.tolist()) regions, imvertices = new_regions, np.asarray(new_vertices) #return new_regions, np.asarray(new_vertices) ## now force them to be in the bounding box poly = np.asarray([imvertices[v] for v in regions]) newpoly = [] for p in poly: polyPath = mplPath.Path(p) newpolyPath = polyPath.clip_to_bbox(bbox) pp = newpolyPath.vertices.transpose() newpoly.append(pp.transpose()) return np.asarray(newpoly)
import matplotlib.pyplot as plt import matplotlib.transforms as mtransforms from matplotlib.patches import FancyBboxPatch # Bbox object around which the fancy box will be drawn. bb = mtransforms.Bbox([[0.3, 0.4], [0.7, 0.6]]) def draw_bbox(ax, bb): # boxstyle=square with pad=0, i.e. bbox itself. p_bbox = FancyBboxPatch( (bb.xmin, bb.ymin), abs(bb.width), abs(bb.height), boxstyle="square,pad=0.", ec="k", fc="none", zorder=10., ) ax.add_patch(p_bbox) def test1(ax): # a fancy box with round corners. pad=0.1 p_fancy = FancyBboxPatch((bb.xmin, bb.ymin), abs(bb.width), abs(bb.height), boxstyle="round,pad=0.1", fc=(1., .8, 1.), ec=(1., 0.5, 1.))
pp = axs[0].get_position() np.testing.assert_allclose(pp, [[0.2, 0.2], [0.44, 0.5]]) @image_comparison(['test_bboxtight.png'], remove_text=True, style='mpl20', savefig_kwarg={'bbox_inches': 'tight'}) def test_bboxtight(): fig, ax = plt.subplots(constrained_layout=True) ax.set_aspect(1.) @image_comparison(['test_bbox.png'], remove_text=True, style='mpl20', savefig_kwarg={'bbox_inches': mtransforms.Bbox([[0.5, 0], [2.5, 2]])}) def test_bbox(): fig, ax = plt.subplots(constrained_layout=True) ax.set_aspect(1.) def test_align_labels(): """ Tests for a bug in which constrained layout and align_ylabels on three unevenly sized subplots, one of whose y tick labels include negative numbers, drives the non-negative subplots' y labels off the edge of the plot """ fig, (ax3, ax1, ax2) = plt.subplots(3, 1, constrained_layout=True, figsize=(6.4, 8), gridspec_kw={"height_ratios": (1, 1,