def double_choropleth(gdf, label_fn=lambda _: "", Rt_col="Rt", Rt_proj_col="Rt_proj", titles=["Current $R_t$", "Projected $R_t$ (1 Week)"], arrangement=(1, 2), label_kwargs={}, mappable=sm): """ plot two choropleths side-by-side based on multiple metrics """ gdf["pt"] = gdf["geometry"].centroid fig, (ax1, ax2) = plt.subplots(*arrangement) for (ax, title, col) in zip((ax1, ax2), titles, (Rt_col, Rt_proj_col)): ax.grid(False) ax.set_xticks([]) ax.set_yticks([]) ax.set_title(title, loc="left", fontdict=theme.label) gdf.plot(color=[mappable.to_rgba(_) for _ in gdf[col]], ax=ax, edgecolors="black", linewidth=0.5, missing_kwds={ "color": theme.accent, "edgecolor": "white" }) if label_fn is not None: for (_, row) in gdf.iterrows(): label = label_fn(row) Rt_c, Rt_p = round(row[Rt_col], 2), round(row[Rt_proj_col], 2) a1 = ax1.annotate(s=f"{label}{Rt_c}", xy=list(row["pt"].coords)[0], ha="center", fontfamily=theme.note["family"], color="white", **label_kwargs) a2 = ax2.annotate(s=f"{label}{Rt_p}", xy=list(row["pt"].coords)[0], ha="center", fontfamily=theme.note["family"], color="white", **label_kwargs) a1.set_path_effects( [Stroke(linewidth=2, foreground="black"), Normal()]) a2.set_path_effects( [Stroke(linewidth=2, foreground="black"), Normal()]) cbar_ax = fig.add_axes([0.95, 0.25, 0.01, 0.5]) cb = fig.colorbar(mappable=mappable, orientation="vertical", cax=cbar_ax) cbar_ax.set_title("$R_t$", fontdict=theme.note) return PlotDevice(fig)
def __init__(self, size=1, extent=0.025, label="", loc=2, ax=None, pad=0.6, borderpad=0.5, ppad=0, sep=4, prop=None, frameon=False, colour='black', **kwargs): # size: length of bar in data units. # extent: height of bar ends in axes units. if loc == 'upper right': loc = 1 elif loc == 'upper left': loc = 2 elif loc == 'lower left': loc = 3 elif loc == 'lower right': loc = 4 if colour in ['w', 'white']: fc = 'w' # Foreground colour. ec = 'k' # Edge colour. else: fc = 'k' ec = 'w' trans = ax.get_xaxis_transform() size_bar = matplotlib.offsetbox.AuxTransformBox(trans) rectangle = Rectangle((0, 0), width=size, height=extent, fc=fc, ec=ec) size_bar.add_artist(rectangle) text = matplotlib.offsetbox.TextArea(label, minimumdescent=False, textprops={'color': fc}) path_effects = [ Stroke(linewidth=2, foreground=ec, alpha=0.75), Normal() ] text._text.set_path_effects(path_effects) self.vpac = matplotlib.offsetbox.VPacker( \ children=[size_bar, text], align="center", pad=ppad, sep=sep) matplotlib.offsetbox.AnchoredOffsetbox.__init__( \ self, loc, pad=pad, borderpad=borderpad, child=self.vpac, prop=prop, frameon=frameon)
def filtered_text(ax): # mostly copied from contour_demo.py # prepare image delta = 0.025 x = np.arange(-3.0, 3.0, delta) y = np.arange(-2.0, 2.0, delta) X, Y = np.meshgrid(x, y) Z1 = mlab.bivariate_normal(X, Y, 1.0, 1.0, 0.0, 0.0) Z2 = mlab.bivariate_normal(X, Y, 1.5, 0.5, 1, 1) # difference of Gaussians Z = 10.0 * (Z2 - Z1) # draw im = ax.imshow(Z, interpolation='bilinear', origin='lower', cmap=cm.gray, extent=(-3, 3, -2, 2)) levels = np.arange(-1.2, 1.6, 0.2) CS = ax.contour(Z, levels, origin='lower', linewidths=2, extent=(-3, 3, -2, 2)) ax.set_aspect("auto") # contour label cl = ax.clabel( CS, levels[1::2], # label every second level inline=1, fmt='%1.1f', fontsize=11) # change clable color to black from matplotlib.patheffects import Normal for t in cl: t.set_color("k") t.set_path_effects( [Normal()]) # to force TextPath (i.e., same font in all backends) # Add white glows to improve visibility of labels. white_glows = FilteredArtistList(cl, GrowFilter(3)) ax.add_artist(white_glows) white_glows.set_zorder(cl[0].get_zorder() - 0.1) ax.xaxis.set_visible(False) ax.yaxis.set_visible(False)
def filtered_text(ax): # mostly copied from contour_demo.py # prepare image delta = 0.025 x = np.arange(-3.0, 3.0, delta) y = np.arange(-2.0, 2.0, delta) X, Y = np.meshgrid(x, y) Z1 = np.exp(-X**2 - Y**2) Z2 = np.exp(-(X - 1)**2 - (Y - 1)**2) Z = (Z1 - Z2) * 2 # draw ax.imshow(Z, interpolation='bilinear', origin='lower', cmap=cm.gray, extent=(-3, 3, -2, 2), aspect='auto') levels = np.arange(-1.2, 1.6, 0.2) CS = ax.contour(Z, levels, origin='lower', linewidths=2, extent=(-3, 3, -2, 2)) # contour label cl = ax.clabel( CS, levels[1::2], # label every second level inline=True, fmt='%1.1f', fontsize=11) # change clabel color to black from matplotlib.patheffects import Normal for t in cl: t.set_color("k") # to force TextPath (i.e., same font in all backends) t.set_path_effects([Normal()]) # Add white glows to improve visibility of labels. white_glows = FilteredArtistList(cl, GrowFilter(3)) ax.add_artist(white_glows) white_glows.set_zorder(cl[0].get_zorder() - 0.1) ax.xaxis.set_visible(False) ax.yaxis.set_visible(False)
def __init__(self, *args, **kwargs): super().__init__(*args, **kwargs) # if "main" axes if not kwargs.get("sharex"): text = AnchoredText("PRELIMINARY", loc="center", frameon=False, borderpad=0, prop=dict(alpha=0.15, fontsize=50, rotation=30, color="black")) text.set_path_effects( [Stroke(linewidth=3, foreground="white"), Normal()]) text.set_zorder(1000) self.add_artist(text)
def test_patheffect1(): ax1 = plt.subplot(111) ax1.imshow([[1, 2], [2, 3]]) txt = ax1.annotate("test", (1., 1.), (0., 0), arrowprops=dict(arrowstyle="->", connectionstyle="angle3", lw=2), size=20, ha="center", path_effects=[withStroke(linewidth=3, foreground="w")]) txt.arrow_patch.set_path_effects([Stroke(linewidth=5, foreground="w"), Normal()]) ax1.grid(True, linestyle="-") pe = [withStroke(linewidth=3, foreground="w")] for l in ax1.get_xgridlines() + ax1.get_ygridlines(): l.set_path_effects(pe)
def choropleth(gdf, label_fn=lambda _: "", col="Rt", title="$R_t$", label_kwargs={}, mappable=sm, fig=None, ax=None): """ display choropleth of locations by metric """ gdf["pt"] = gdf["geometry"].centroid if not fig: fig, ax = plt.subplots() ax.grid(False) ax.set_xticks([]) ax.set_yticks([]) if title: ax.set_title(title, loc="left", fontdict=theme.label) gdf.plot(color=[mappable.to_rgba(_) for _ in gdf[col]], ax=ax, edgecolors="black", linewidth=0.5, missing_kwds={ "color": theme.accent, "edgecolor": "white" }) if label_fn is not None: for (_, row) in gdf.iterrows(): label = label_fn(row) value = round(row[col], 2) ax.annotate( s = f"{label}{value}", xy = list(row["pt"].coords)[0], ha = "center", fontfamily = theme.note["family"], color = "black", **label_kwargs, fontweight = "semibold", size = 12)\ .set_path_effects([Stroke(linewidth = 2, foreground = "white"), Normal()]) cbar_ax = fig.add_axes([0.90, 0.25, 0.01, 0.5]) cb = fig.colorbar(mappable=mappable, orientation="vertical", cax=cbar_ax) cbar_ax.set_title("$R_t$", fontdict=theme.note) return PlotDevice(fig)
import matplotlib.dates as mdt import matplotlib.font_manager as mfm import matplotlib.patches as mpatch import matplotlib.path as mpath import matplotlib.pyplot as plt import matplotlib.transforms as mtrans import numpy as np from matplotlib.patheffects import Normal, Stroke from .cell import Cell, CellRow from .gpf import pure_cmap from .weathercode import WeatherCode from .wxsymbols import wx_symbol_font STROKE = [Stroke(linewidth=0.8, foreground='w'), Normal()] ARROW_VER = [(0, -0.1), (0.66, -0.8), (0, 1), (-0.66, -0.8), (0, -0.1)] ARROW_CODE = [ mpath.Path.MOVETO, mpath.Path.LINETO, mpath.Path.LINETO, mpath.Path.LINETO, mpath.Path.CLOSEPOLY ] ARROW = mpath.Path(ARROW_VER, ARROW_CODE) temp_cmap = pure_cmap('temp') fontpath = os.path.join(os.path.dirname(__file__), 'source.ttf') source_font = mfm.FontProperties(fname=fontpath, size=6) matplotlib.rc('font', family='HelveticaNeue', size=6)
ax = fig.add_subplot(4, 2, 6, xticks=[], yticks=[]) ax.imshow(I, cmap=cmap, origin="lower") ax.text( x, y, "Read me", color="white", transform=ax.transData, bbox={ "facecolor": "black", "edgecolor": "None", "pad": 1, "alpha": 0.75 }, ) ax = fig.add_subplot(4, 2, 7, xticks=[], yticks=[]) ax.imshow(I, cmap=cmap, origin="lower") text = ax.text(x, y, "Read me", color="black", transform=ax.transData) text.set_path_effects([Stroke(linewidth=1.5, foreground="white"), Normal()]) ax = fig.add_subplot(4, 2, 8, xticks=[], yticks=[]) ax.imshow(I, cmap=cmap, origin="lower") text = ax.text(x, y, "Read me", color="white", transform=ax.transData) text.set_path_effects([Stroke(linewidth=1.5, foreground="black"), Normal()]) plt.tight_layout() plt.savefig("../../figures/typography/typography-legibility.pdf", dpi=600) plt.show()
def draw_outline(matplt_plot_obj, lw): matplt_plot_obj.set_path_effects( [Stroke(linewidth=lw, foreground='black'), Normal()])