def slope_marker(self, x, y, slope=None, width=.2, xoffset=0, yoffset=.2, color='0.5'): 'slope marker' ax = self.gca() islog = {'log': True, 'linear': False} xislog = islog[ax.get_xscale()] yislog = islog[ax.get_yscale()] xisnum = numeric.isnumber(x) yisnum = numeric.isnumber(y) if slope is None: assert not xisnum and not xisnum, 'need two points to compute a slope' x__, x_ = numpy.log10(x[-2:]) if xislog else x[-2:] y__, y_ = numpy.log10(y[-2:]) if yislog else y[-2:] slope = (y_ - y__) / (x_ - x__) if slope > 0: width = -width if not xisnum: x = x[-1] if not yisnum: y = y[-1] xmin, xmax = ax.get_xlim() if xislog: W = numpy.log10(xmax / xmin) * width x0 = x * 10**-W xc = x * 10**(-.5*W) else: W = (xmax - xmin) * width x0 = x - W xc = x - .5 * W H = W * float(slope) if yislog: y0 = y * 10**-H yc = y * 10**(-.5*H) else: y0 = y - H yc = y - .5 * H from matplotlib import transforms dpi = self.gcf().dpi_scale_trans shifttrans = ax.transData + transforms.ScaledTranslation(xoffset, numpy.sign(H) * yoffset, dpi) triangle = self.Polygon([(x0,y0), (x,y), (xc,y)], closed=False, ec=color, fc='none', transform=shifttrans) ax.add_patch(triangle) self.text(xc, yc, str(round(float(slope),3)), color=color, horizontalalignment = 'right' if W > 0 else 'left', verticalalignment = 'top' if H < 0 else 'bottom', transform = shifttrans + transforms.ScaledTranslation( numpy.sign(W) * -.05, numpy.sign(H) * .05, dpi))
def __init__(self, axes, *args, **kwargs): self._text1_translate = mtransforms.ScaledTranslation( 0, 0, axes.figure.dpi_scale_trans) self._text2_translate = mtransforms.ScaledTranslation( 0, 0, axes.figure.dpi_scale_trans) super().__init__(axes, *args, **kwargs) self.label1.set(rotation_mode='anchor', transform=self.label1.get_transform() + self._text1_translate) self.label2.set(rotation_mode='anchor', transform=self.label2.get_transform() + self._text2_translate)
def plot_relative_feature_importance(importance): max_importance = np.max(importance) relative_importance = sorted( zip(100 * importance / max_importance, features)) yticks = np.arange(len(relative_importance)) yticklabels = [ri[1] for ri in relative_importance][::-1] bars_sizes = [ri[0] for ri in relative_importance][::-1] fig, ax = plt.subplots(figsize=(4.3, 6.5), dpi=150) bars = ax.barh(yticks, bars_sizes, height=0.8, color='red') plt.setp(ax, yticks=yticks, yticklabels=yticklabels) ax.set_xlim([0, 100]) ax.set_ylim([-0.5, 57]) for e in ax.get_yticklabels() + ax.get_xticklabels(): e.set_fontsize(6) e.set_color(GRAY1) ax.tick_params(left=False) ax.spines['right'].set_visible(False) ax.spines['top'].set_visible(False) offset = transforms.ScaledTranslation(0, -0.07, fig.dpi_scale_trans) for e in ax.get_xticklabels() + ax.xaxis.get_ticklines() + \ [ax.spines['bottom']]: e.set_transform(e.get_transform() + offset) ax.spines['bottom'].set_bounds(0, 100) _ = ax.set_xlabel('Relative Importance', color=GRAY4, fontsize=7)
def errorbar(self, offset=False, **kwargs): """ Make a matplotlib errorbar plot, with all Hists in the stack overlaid. Passing 'offset=True' will slightly offset each dataset so overlapping errorbars are still visible. Any additional keyword arguments will be passed to :func:`matplotlib.pyplot.errorbar`. """ plots = [] for i, hist in enumerate(self.hists): if self.title is not None: hist.title = self.title if self.xlabel is not None: hist.xlabel = self.xlabel if self.ylabel is not None: hist.ylabel = self.ylabel all_kwargs = copy.copy(kwargs) all_kwargs.update(self.kwargs[i]) transform = plt.gca().transData if offset: index_offset = (len(self.hists) - 1) / 2. pixel_offset = 1. / 72 * (i - index_offset) transform = transforms.ScaledTranslation( pixel_offset, 0, plt.gcf().dpi_scale_trans) transform = plt.gca().transData + transform errorbar = hist.errorbar(transform=transform, **all_kwargs) plots.append(errorbar) return plots
def plot_support_roller(self, ax, direc='X', size=9 / 72): """ローラー支点の描画 :param ax: :param direc:ローラーの方向 'X' or 'Y' :param size: 作図サイズ(ポイント) """ size = size codes = [Path.MOVETO] + [Path.LINETO] * 2 + [Path.CLOSEPOLY] if direc == 'X': vertices = [(0, 0), (size / 2, -size * 1.73 / 2), (-size / 2, -size * 1.73 / 2), (0, 0)] else: vertices = [(0, 0), (size * 1.73 / 2, size / 2), (size * 1.73 / 2, -size / 2), (0, 0)] codes += [Path.MOVETO] + [Path.LINETO] * 1 + [Path.CLOSEPOLY] if direc == 'X': vertices += [(size / 2, -size * 1.73 / 2 - size / 4), (-size / 2, -size * 1.73 / 2 - size / 4), (0, 0)] else: vertices += [(size * 1.73 / 2 + size / 4, size / 2), (size * 1.73 / 2 + size / 4, -size / 2), (0, 0)] # vertices = np.array(vertices, float) path = Path(vertices, codes) trans = (ax.get_figure().dpi_scale_trans + transforms.ScaledTranslation(self._x, self._y, ax.transData)) pathpatch = PathPatch(path, facecolor='None', edgecolor='k', transform=trans) ax.add_patch(pathpatch)
def draw_wedge(ax, drawing_origin, radius, prob1, prob2, prob3, prob4, col_alpha): box_height = 1 box_width = 1 origin = np.array([0,0]) trans = (fig.dpi_scale_trans + transforms.ScaledTranslation(drawing_origin[0],drawing_origin[1], ax.transData)) ang1 = prob1*360 ang2 = prob2*360 ang3 = prob3*360 ang4 = prob4*360 if (prob1 != 0): wedge1 = mpatches.Wedge(origin, radius, 0, ang1, facecolor="k", edgecolor="k", transform=trans, alpha=1) ax.add_patch(wedge1) if (prob2 != 0): wedge2 = mpatches.Wedge(origin, radius,ang1,ang1+ang2, facecolor="r", edgecolor="k", transform=trans, alpha=col_alpha) ax.add_patch(wedge2) if (prob3 != 0): wedge3 = mpatches.Wedge(origin, radius,ang1+ang2,ang1+ang2+ang3, facecolor="b", edgecolor="k", transform=trans, alpha=col_alpha) ax.add_patch(wedge3) if (prob4 != 0): wedge4 = mpatches.Wedge(origin, radius,ang1+ang2+ang3,ang1+ang2+ang3+ang4, facecolor="y", edgecolor="k", transform=trans, alpha=col_alpha) ax.add_patch(wedge4) return 0
def plot_support_fixed(self, ax, size=9 / 72): """ 固定支点の描画 :param ax: :param size: 作図サイズ(ポイント) """ size = size w = 1.2 * size h = 0.7 * size trans = (ax.get_figure().dpi_scale_trans + transforms.ScaledTranslation(self._x, self._y, ax.transData)) # support_patch = mpatches.Rectangle((-w * 0.5, -h * 1.0), w, h, linewidth=0.9, zorder=2, hatch='//////', fc='w', # ec='k', alpha=1, transform=trans) support_patch = mpatches.Rectangle((-w * 0.5, -h * 1.0), w, h, linewidth=0., zorder=2, hatch='//////', fc='w', ec='k', alpha=1, transform=trans) ax.add_patch(support_patch) codes = [Path.MOVETO] + [Path.LINETO] + [Path.CLOSEPOLY] vertices = [(-w * 0.5, 0), (w * 0.5, 0), (0, 0)] path = Path(vertices, codes) pathpatch = PathPatch(path, facecolor='None', edgecolor='k', transform=trans, linewidth=1.) ax.add_patch(pathpatch)
def secondary_legend(ax=None, *args, rel_loc='left', **kwargs): if not ax: ax = plt.gca() old_legend = ax.get_legend() leg = ax.legend(*args, **kwargs) if old_legend: ax.add_artist(old_legend) ax.figure.canvas.draw() bb0 = old_legend.get_window_extent() bb1 = leg.get_window_extent().transformed(ax.transAxes.inverted()) if rel_loc in ['left', 'right']: bb1.y1 += 0.015 dx = (bb0.x1 - bb0.x0) / 72 dy = 0 if rel_loc == 'left': dx = -dx if rel_loc in ['over', 'under']: bb1.x1 += 0.015 dy = (bb0.y1 - bb0.y0) / 72 dx = 0 if rel_loc == 'under': dy = -dy offset = transforms.ScaledTranslation(dx, dy, ax.figure.dpi_scale_trans) shadow_transform = ax.transAxes + offset leg.set_bbox_to_anchor(bb1, transform=shadow_transform) return leg
def transform_tick_labels(*, ax, xt=0., yt=0., rotation=0., axis, ha=None, va=None): offset = transforms.ScaledTranslation( xt=xt, yt=yt, scale_trans=ax.get_figure().dpi_scale_trans) if rotation != 0: ax.tick_params(axis=axis, rotation=rotation) def __set_alignment(lbl): if va is not None: lbl.set_va(va) if ha is not None: lbl.set_ha(ha) if 'x' in axis or 'both' in axis: for label in ax.xaxis.get_majorticklabels(): label.set_transform(label.get_transform() + offset) __set_alignment(lbl=label) if 'y' in axis or 'both' in axis: for label in ax.yaxis.get_majorticklabels(): label.set_transform(label.get_transform() + offset) __set_alignment(lbl=label)
def boxplotMean(featL, x_lab="variable", y_lab="value", ax=None): """boxplot and mean""" import matplotlib.transforms as transforms if ax == None: fig, ax = plt.subplots() featG = featL.groupby([x_lab]).agg(np.std).reset_index() err = featG[y_lab].mean() sns.pointplot(x=x_lab, y=y_lab, data=featL, linestyles='', scale=1, color='k', errwidth=err, capsize=0.2, markers='x', ax=ax) offset = transforms.ScaledTranslation(5 / 72., 0, ax.figure.dpi_scale_trans) trans = ax.collections[0].get_transform() ax.collections[0].set_transform(trans + offset) # sns.swarmplot(x=x_lab,y=y_lab,data=featL,edgecolor="black",linewidth=.9,ax=ax) sns.boxplot(x=x_lab, y=y_lab, data=featL, saturation=1, ax=ax) sns.pointplot(x=x_lab, y=y_lab, data=featL, linestyles='--', scale=0.4, color='k', errwidth=0, capsize=0, ax=ax) return ax
def add_plot(graph, names, values, errors): fig = graph.fig ax = graph.ax offset_points = graph.offset_points color = graph.next_color offset = transforms.ScaledTranslation(offset_points/72.0, 0, fig.dpi_scale_trans) offset_transform = ax.transData + offset (plot, bar1, bar2) = ax.errorbar(xrange(0,len(values)), values, yerr=errors, marker="D", markersize=2.5, linestyle=" ", color=color, transform=offset_transform, markeredgecolor=color, elinewidth=0.8) graph.plots.append(plot) graph.change_color() for i in xrange(0, len(values)): high_point = values[i] + errors[i] if high_point > graph.high_yaxis: graph.high_yaxis = high_point graph.high_yaxis = graph.high_yaxis * 1.05 ax.axis([-1, graph.benchmarks_num, 0, graph.high_yaxis]) width = 0.15 ind = range(0, len(values)) plt.xticks(map(lambda n: n + width/2.0, ind), names, fontsize=8, rotation=300) plt.yticks(fontsize=8) graph.offset_points += 4
def initOffset(shift): DEFAULT_FONTSIZE = plt.rcParams['font.size'] nonlocal trans, offset, toff, texoff, axoff, axis_to_data, data_to_axis trans = transforms.blended_transform_factory(ax.transData, ax.transAxes) offset = transforms.ScaledTranslation( 0, shift + (DEFAULT_FONTSIZE + 2) / 72., fig.dpi_scale_trans) toff = transforms.ScaledTranslation(0, shift + 0 / 72., fig.dpi_scale_trans) texoff = ax.transAxes + toff axoff = ax.transAxes + offset axis_to_data = ax.transAxes + ax.transData.inverted() data_to_axis = axis_to_data.inverted() return shift + (2 * (DEFAULT_FONTSIZE + 2 + 2)) / 72
def get_spine_transform(self): """Return the spine transform.""" self._ensure_position_is_set() position = self._position if isinstance(position, str): if position == 'center': position = ('axes', 0.5) elif position == 'zero': position = ('data', 0) assert len(position) == 2, 'position should be 2-tuple' position_type, amount = position _api.check_in_list(['axes', 'outward', 'data'], position_type=position_type) if self.spine_type in ['left', 'right']: base_transform = self.axes.get_yaxis_transform(which='grid') elif self.spine_type in ['top', 'bottom']: base_transform = self.axes.get_xaxis_transform(which='grid') else: raise ValueError(f'unknown spine spine_type: {self.spine_type!r}') if position_type == 'outward': if amount == 0: # short circuit commonest case return base_transform else: offset_vec = {'left': (-1, 0), 'right': (1, 0), 'bottom': (0, -1), 'top': (0, 1), }[self.spine_type] # calculate x and y offset in dots offset_dots = amount * np.array(offset_vec) / 72 return (base_transform + mtransforms.ScaledTranslation( *offset_dots, self.figure.dpi_scale_trans)) elif position_type == 'axes': if self.spine_type in ['left', 'right']: # keep y unchanged, fix x at amount return (mtransforms.Affine2D.from_values(0, 0, 0, 1, amount, 0) + base_transform) elif self.spine_type in ['bottom', 'top']: # keep x unchanged, fix y at amount return (mtransforms.Affine2D.from_values(1, 0, 0, 0, 0, amount) + base_transform) elif position_type == 'data': if self.spine_type in ('right', 'top'): # The right and top spines have a default position of 1 in # axes coordinates. When specifying the position in data # coordinates, we need to calculate the position relative to 0. amount -= 1 if self.spine_type in ('left', 'right'): return mtransforms.blended_transform_factory( mtransforms.Affine2D().translate(amount, 0) + self.axes.transData, self.axes.transData) elif self.spine_type in ('bottom', 'top'): return mtransforms.blended_transform_factory( self.axes.transData, mtransforms.Affine2D().translate(0, amount) + self.axes.transData)
def _calc_offset_transform(self): """calculate the offset transform performed by the spine""" self._ensure_position_is_set() position = self._position if cbook.is_string_like(position): if position=='center': position = ('axes',0.5) elif position=='zero': position = ('data',0) assert len(position)==2, "position should be 2-tuple" position_type, amount = position assert position_type in ('axes','outward','data') if position_type=='outward': if amount == 0: # short circuit commonest case self._spine_transform = ('identity',mtransforms.IdentityTransform()) elif self.spine_type in ['left','right','top','bottom']: offset_vec = {'left':(-1,0), 'right':(1,0), 'bottom':(0,-1), 'top':(0,1), }[self.spine_type] # calculate x and y offset in dots offset_x = amount*offset_vec[0]/ 72.0 offset_y = amount*offset_vec[1]/ 72.0 self._spine_transform = ('post', mtransforms.ScaledTranslation(offset_x,offset_y, self.figure.dpi_scale_trans)) else: warnings.warn('unknown spine type "%s": no spine ' 'offset performed'%self.spine_type) self._spine_transform = ('identity',mtransforms.IdentityTransform()) elif position_type=='axes': if self.spine_type in ('left','right'): self._spine_transform = ('pre', mtransforms.Affine2D.from_values( # keep y unchanged, fix x at amount 0,0,0,1,amount,0)) elif self.spine_type in ('bottom','top'): self._spine_transform = ('pre', mtransforms.Affine2D.from_values( # keep x unchanged, fix y at amount 1,0,0,0,0,amount)) else: warnings.warn('unknown spine type "%s": no spine ' 'offset performed'%self.spine_type) self._spine_transform = ('identity',mtransforms.IdentityTransform()) elif position_type=='data': if self.spine_type in ('left','right'): self._spine_transform = ('data', mtransforms.Affine2D().translate(amount,0)) elif self.spine_type in ('bottom','top'): self._spine_transform = ('data', mtransforms.Affine2D().translate(0,amount)) else: warnings.warn('unknown spine type "%s": no spine ' 'offset performed'%self.spine_type) self._spine_transform = ('identity',mtransforms.IdentityTransform())
def slope_triangle(self, x, y, fillcolor='0.9', edgecolor='k', xoffset=0, yoffset=0.1, slopefmt='{0:.1f}'): '''Draw slope triangle for supplied y(x) - x, y: coordinates - xoffset, yoffset: distance graph & triangle (points) - fillcolor, edgecolor: triangle style - slopefmt: format string for slope number''' i, j = (-2, -1) if x[-1] < x[-2] else (-1, -2) # x[i] > x[j] if not all(numpy.isfinite(x[-2:])) or not all(numpy.isfinite(y[-2:])): log.warning('Not plotting slope triangle for +/-inf or nan values') return from matplotlib import transforms shifttrans = self.gca().transData \ + transforms.ScaledTranslation(xoffset, -yoffset, self.gcf().dpi_scale_trans) xscale, yscale = self.gca().get_xscale(), self.gca().get_yscale() # delta() checks if either axis is log or lin scaled delta = lambda a, b, scale: numpy.log10(float( a) / b) if scale == 'log' else float( a - b) if scale == 'linear' else None slope = delta(y[-2], y[-1], yscale) / delta(x[-2], x[-1], xscale) if slope in (numpy.nan, numpy.inf, -numpy.inf): warnings.warn( 'Cannot draw slope triangle with slope: {}, drawing nothing'. format(str(slope))) return slope # handle positive and negative slopes correctly xtup, ytup = ((x[i], x[j], x[i]), (y[j], y[j], y[i])) if slope > 0 else ((x[j], x[j], x[i]), (y[i], y[j], y[i])) a, b = (2 / 3., 1 / 3.) if slope > 0 else (1 / 3., 2 / 3.) xval = a * x[i] + b * x[j] if xscale == 'linear' else x[i]**a * x[j]**b yval = b * y[i] + a * y[j] if yscale == 'linear' else y[i]**b * y[j]**a self.fill(xtup, ytup, color=fillcolor, edgecolor=edgecolor, transform=shifttrans) self.text(xval, yval, slopefmt.format(slope), horizontalalignment='center', verticalalignment='center', transform=shifttrans) return slope
def make_shadow(fig, axes, line, t, s): delta = 2 / 72. # how many points to move the shadow offset = transforms.ScaledTranslation(delta, -delta, fig.dpi_scale_trans) offset_transform = axes.transData + offset # We plot the same data, but now using offset transform # zorder -- to render it below the line axes.plot(t, s, linewidth=5, color='gray', transform=offset_transform, zorder=0.5 * line.get_zorder())
def on_ylims_change(axes=[]): ax.yaxis.set_label_coords(0, ax.get_ylim()[1], transform=ax.transData) dd = 2 / 72. fig = ax.get_figure() l = ax.yaxis.label xpos, ypos = l.get_position() offset = trans.ScaledTranslation(dd, 0, fig.dpi_scale_trans) shadow_transform = l.get_transform() + offset ax.yaxis.set_label_coords(xpos, ypos, transform=shadow_transform)
def make_shadow(fig, axes, line, t, s): ❓ #偏移的值是以点为单位的,点尺寸 1/72英寸,想有偏移2pt,向下偏移2pt delta = 2/72 #how many points to move the shadow offset = transforms.ScaledTranslation(delta, -delta, fig.dpi_scale_trans) #设置偏移方向、距离; offset_transform = axes.transData + offset #创建了一个偏移对象, # we plot the same data, but now using offset transform # zorder -- to render it below the line axes.plot(t, s , linewidth=5, color='gray', transform=offset_transform, zorder=0.5*line.get_zorder())
def make_shadow(fig, axes, line, t, s): delta = 2 / 72. offset = transforms.ScaledTranslation(delta, -delta, fig.dpi_scale_trans) offset_transform = axes.transData + offset axes.plot(t, s, linewidth=5, color='gray', transform=offset_transform, zorder=0.5 * line.get_zorder())
def main(inargs): """Run the program.""" df = pandas.read_csv(inargs.infile) colors = {'historical': 'black', 'GHG-only': 'red', 'AA-only': 'blue'} fig, ax = plt.subplots(figsize=(16, 10)) offset = lambda p: transforms.ScaledTranslation(p / 72., 0, plt.gcf().dpi_scale_trans) trans = plt.gca().transData for experiment in ['historical', 'GHG-only', 'AA-only']: toa_vals = numpy.array( df.loc[(df['variable'] == 'netTOA') & (df['experiment'] == experiment)]['accumulated_heat']) ohu_vals = numpy.array( df.loc[(df['variable'] == 'OHU') & (df['experiment'] == experiment)]['accumulated_heat']) ohc_vals = numpy.array( df.loc[(df['variable'] == 'OHC') & (df['experiment'] == experiment)]['accumulated_heat']) xvals = numpy.arange(toa_vals.shape[0]) plt.scatter(xvals, toa_vals, c=colors[experiment], marker='s', transform=trans + offset(-5)) plt.scatter(xvals, ohu_vals, c=colors[experiment]) plt.scatter(xvals, ohc_vals, c=colors[experiment], marker='D', transform=trans + offset(5)) plt.ticklabel_format(style='sci', axis='y', scilimits=(0, 0), useMathText=True) ax.yaxis.major.formatter._useMathText = True plt.xticks(xvals, list(df.model.unique()), rotation=40, ha='right') ax.axhline(y=0, color='0.5', linestyle='--', linewidth=0.5) add_legends() plt.ylabel('J') plt.savefig(inargs.outfile, bbox_inches='tight') log_text = cmdprov.new_log(git_repo=repo_dir) log_file = re.sub('.png', '.met', inargs.outfile) cmdprov.write_log(log_file, log_text)
def make_shadow(fig, axes, line, t, s): delta = 2 / 72 # number of points to move the shadow away offset = transforms.ScaledTranslation(delta, -delta, fig.dpi_scale_trans) # Deltas : # 1st delta moves shadow left (negative) or right(positive) # 2nd delta moves shadow up (positive) or down (negative) offset_transform = axes.transData + offset # We plot the same data, but now using offset transform # zorder -- to render it below the line axes.plot(t, s, linewidth=5, color='gray', transform=offset_transform, zorder=.5 * line.get_zorder())
def _render_ep_lines(self): """ Render energy profile lines in canvas. """ for line in self.lines: for idx in range(line.shadow_depth): identity_trans = transforms.IdentityTransform() offset = transforms.ScaledTranslation(idx, -idx, identity_trans) shadow_trans = self.axes.transData + offset # Create matplotlib Line2D. alpha = (line.shadow_depth-idx)/2.0/line.shadow_depth shadow_line = Line2D(line.x, line.y, linewidth=line.line_width, color=line.shadow_color, transform=shadow_trans, alpha=alpha) self.shadow_lines.append(shadow_line)
def plot_correlations(names, matrices): size = plt.gcf().get_size_inches() fig, axs = plt.subplots(2, 2, figsize=(size[0], 4.7)) norm = colors.DivergingNorm(vmin=-0.7, vcenter=0, vmax=0.3) for ax, name, matrix in zip(axs.ravel(), names, matrices): mc = np.ma.masked_where(matrix > 0.99, matrix) # RdYlBu im = ax.imshow(mc.T, cmap="RdBu_r", norm=norm) ax.set_yticks([]) ax.set_xticks([]) ax.set_aspect("equal") ax.text( 0.2, 0.07, name, horizontalalignment="center", verticalalignment="center", transform=ax.transAxes, color="gray", ) plt.tight_layout(pad=0, rect=(-0.015, 0, 0.985, 1)) plt.subplots_adjust( wspace=0.04, hspace=0.04, top=1, bottom=0, ) cb = fig.colorbar(im, ax=axs.ravel().tolist(), label="Spearman Correlation Coefficient", use_gridspec=True, pad=0, anchor=(0.2, 0.5)) dx = 0 / 72. dy = 1 / 72. offset = transforms.ScaledTranslation(dx, dy, fig.dpi_scale_trans) for label in cb.ax.get_yticklabels(): label.set_transform(label.get_transform() + offset)
def plot_support_pin(self, ax, size=9 / 72): """ ピン支点の描画 :param ax: :param size: 作図サイズ(ポイント) """ size = size codes = [Path.MOVETO] + [Path.LINETO] * 2 + [Path.CLOSEPOLY] vertices = [(0, 0), (size / 2, -size * 1.73 / 2), (-size / 2, -size * 1.73 / 2), (0, 0)] # vertices = np.array(vertices, float) path = Path(vertices, codes) trans = (ax.get_figure().dpi_scale_trans + transforms.ScaledTranslation(self._x, self._y, ax.transData)) pathpatch = PathPatch(path, facecolor='None', edgecolor='k', transform=trans) ax.add_patch(pathpatch)
def make_shadow(fig, axes, line, t, s): # how many points to move the shadow # create an offset object underneath and just a few points away # from the original object # the point is 1/72 inches # we move the offset object 2pt right and 2pt down delta = 2 / 72. # xtr, ytr: transformation offset # scaletr offset = transforms.ScaledTranslation(delta, -delta, fig.dpi_scale_trans) offset_transform = axes.transData + offset # we plot the same data, but now using offset transform # zorder -- to render it below the line axes.plot(t, s, linewidth=3, color='gray', transform=offset_transform, zorder=0.5 * line.get_zorder())
def draw_dodge(*args, **kwargs): """ Method to displace error bars by a small amount """ func = args[0] dodge = kwargs.pop("dodge", 0) _ax = kwargs.pop("ax", plt.gca()) _trans = _ax.transData + transforms.ScaledTranslation( dodge / 125., 0, _ax.figure.dpi_scale_trans) _artist = func(*args[1:], **kwargs) def iterate(_artist): if hasattr(_artist, '__iter__'): for obj in _artist: iterate(obj) else: _artist.set_transform(_trans) iterate(_artist) return _artist
def enumerate_axes(fig, axes_list, xoffset: float = -30, yoffset: float = 25, labels: list = None, loc: tuple = None, **kwargs): import matplotlib.transforms as transforms import string offset = transforms.ScaledTranslation(xoffset / 72., yoffset / 72, fig.dpi_scale_trans) if labels is None: labels = ['(' + s + ')' for s in string.ascii_uppercase] if loc is None: loc = (0, 1) for ax, label in zip(axes_list, labels): trans = ax.transAxes + offset ax.annotate(label, xy=loc, xycoords=trans, **kwargs)
def create_event_maps(station='*'): all_events = events.Events.read(eventfile) for file_ in glob(em_path + 'events_%s.txt' % station): st_events = events.Events.read(file_) station = (os.path.splitext(os.path.basename(file_))[0]).split('_')[1] if annotate == 'PB01_special' and station != 'PB01': continue m = map.createRFEventMap(show=False, trench=None) all_events.plot_(m, color='b', radius=5, alpha=0.5) st_events.plot_(m, color='r', radius=8, alpha=0.5) if annotate: ax = m._check_ax() if annotate != 'PB01_special': # fancy box from matplotlib import transforms offset = transforms.ScaledTranslation( -20. / 72, 20. / 72, plt.gcf().dpi_scale_trans) trans = ax.transAxes + offset props = dict(boxstyle='round', facecolor='wheat', alpha=0.8) ax.text(1., 0., station, transform=trans, fontsize=14, verticalalignment='bottom', ha='right', bbox=props) plt.gcf().savefig(em_path + 'map_events_%s_anno.pdf' % station) else: y0, x0 = m(-69.5, -21) dx = 0.2e6 dy = 0.5 * dx * 3**0.5 ax.plot((x0, x0 - dx, x0 + dx, x0), (y0 - dy, y0 + dy, y0 + dy, y0 - dy), 'k') ax.annotate(station, (x0 + 1.5 * dx, y0)) plt.gcf().savefig(em_path + 'map_events_%s_special.pdf' % station) else: plt.gcf().savefig(em_path + 'map_events_%s.pdf' % station)
def __init__(self, Points, Angles, fig, axis): self.Points = Points self.Angles = Angles self.ArrowLength = 0.3 # should be inches self.ArrowHeadSize = 0.08 # should be inches self.ArrowHeadAngle = 45. # degrees self.CalcArrowPoints() self.CalcArrows() LineCollection.__init__(self, self.Arrows, offsets=self.Points, transOffset=axis.transData, # transforms the x,y offsets ) # trans = transforms.scale_transform(fig.dpi, fig.dpi) trans = transforms.ScaledTranslation(fig.dpi, fig.dpi) self.set_transform(trans) # the points to pixels transform return None
def slope_trend(self, x, y, lt='k-', xoffset=.1, slopefmt='{0:.1f}'): '''Draw slope triangle for supplied y(x) - x, y: coordinates - slopefmt: format string for slope number''' # TODO check for gca() loglog scale slope = numpy.log(y[-2] / y[-1]) / numpy.log(x[-2] / x[-1]) C = y[-1] / x[-1]**slope self.loglog(x, C * x**slope, 'k-') from matplotlib import transforms shifttrans = self.gca().transData \ + transforms.ScaledTranslation(-xoffset if x[-1] < x[0] else xoffset, 0, self.gcf().dpi_scale_trans) self.text(x[-1], y[-1], slopefmt.format(slope), horizontalalignment='right' if x[-1] < x[0] else 'left', verticalalignment='center', transform=shifttrans) return slope