def lines(self, latlons, color, shadow=False, **kwargs): if not latlons.any(): return else: use_kw = kwargs ispoint = latlons.shape[0] == 1 if ispoint: # a line plot will cause a singular point to vanish, so we force it to # plot points here use_kw = use_kw.copy() use_kw.pop('linestyle', None) size = use_kw.pop('linewidth', 2) use_kw['marker'] = 'o' use_kw['markersize'] = size use_kw['markeredgewidth'] = 0.0 if shadow: shadow_kw = dict(offset=(0.5, -0.5), alpha=0.6) if ispoint: shadow_effect = path_effects.SimplePatchShadow(**shadow_kw) else: shadow_effect = path_effects.SimpleLineShadow(**shadow_kw) use_kw['path_effects'] = [shadow_effect, path_effects.Normal()] self._bgmap.ax.plot(latlons[:, 1], latlons[:, 0], color=color, transform=ccrs.PlateCarree(), **use_kw)
def draw_polygon(self, pos, color='C0', layer=0): p_fancy = mpatches.Polygon(pos, color=color, joinstyle='round', path_effects=[ path_effects.SimplePatchShadow(), path_effects.Normal() ]) self.ax.add_patch(p_fancy)
def draw_rectangle(self, pos, angle=0, color='C0', layer=0): p_fancy = mpatches.Rectangle([pos[0], pos[1]], 1, 1, angle, color=color, zorder=layer, path_effects=[ path_effects.SimplePatchShadow(), path_effects.Normal() ]) self.ax.add_patch(p_fancy)
def points(self, latlons, color='k', marker='o', markersize=2, shadow=False, **kwargs): lons = latlons[:, 1] lats = latlons[:, 0] kw = kwargs.copy() if shadow: # TODO: fix breaking shadow effects shadow_kw = dict(offset=(0.5, -0.5), alpha=0.6) shadow_effect = path_effects.SimplePatchShadow(**shadow_kw) kw['path_effects'] = [shadow_effect, path_effects.Normal()] self._bgmap.ax.scatter(lons, lats, marker=marker, s=markersize, transform=ccrs.PlateCarree(), facecolor=color, **kw)
def __init__(self, ax, facade=None, root=C.DATA_ROOT, on_select=None, on_hover=None, fill_alpha=0.4, expand_by=2, username='******', annotations=None, folder='merged'): """ Parameters: - *ax*: The axis to render onto, - *facade*: A facade object to edit. - *labels_selector*: An (optional) LabelSelector widget to allow the labels of annotations to be changed. """ super().__init__() if folder is None and facade is not None: folder = facade.annotation.folder if annotations is None: annotations = glob(os.path.join(root, 'Annotations', folder, '*.xml')) if facade is None: facade = fsi.Annotation(annotation=annotations[0]) self.ax = ax self.canvas = ax.figure.canvas self._facade = None self.labels_selector = None self.cids = [] self.fill_alpha = fill_alpha self.username = username # Keep a list of all of the annotated images so we can load the 'next' file # automatically self._annotation_list = copy(annotations) self._annotation_index = -1 if facade.annotation_path in annotations: self._annotation_index = annotations.index(facade.annotation_path) # The parameters used to filter objects self.last_filter = None self._label_box = None self.axis_image = None # Callbacks self.on_hover = on_hover self.on_select = on_select ## # Not sure that ths widget should be aware of the root -- should probably be passed # the names and colors as parameters.... self.root = root self.names = np.loadtxt(f"{self.root}/names.txt", dtype='str') self.colors = np.loadtxt(f"{self.root}/colors.txt", delimiter=',', dtype=np.uint8) / 255. self.z_orders = {i: name for (name, i) in enumerate(self.names)} ## # I have a (hopefully) generic polygon selector that allows me to interact with the # polygons self.poly_selector = PolygonSelector(self.ax, onactivate=self._on_poly_activate, onhover=self._on_poly_hover, expandby=expand_by) # Create a text object to render information about the active object # To make the text visible over any background, give it a shadow self.label = self.ax.text(0, 0, 'unknown', visible=False, horizontalalignment='center', verticalalignment='center') self.label.set_path_effects([patheffects.Normal(), patheffects.SimplePatchShadow(offset=(1, -1), shadow_rgbFace=(1, 1, 0))]) # Create polygon editor when the user pressed a certain key (e.g. enter) self.poly_editor = None self._poly_editor_index = -1 # Save the index of the object we last started editing # Set our facade using the property setter to trigger updates self.facade = facade # Keep track of changes made with this tool self.history = [] self.future = [] # Initialize properties to pass stupid code inspection if False and "This is dumb": self.active_index = self.get_active_index() self.active_object = self.get_active_object() self.hover_index = self.get_hover_index() self.hover_object = self.get_hover_object() self.connect_events()
def test_SimplePatchShadow_offset(): pe = path_effects.SimplePatchShadow(offset=(4, 5)) assert_equal(pe._offset, (4, 5))
fig = plt.figure(figsize=(5, 1.5)) text = fig.text(0.5, 0.5, 'Normal Effect', ha='center', va='center', size=36) text.set_path_effects([path_effects.Normal()]) plt.show() fig = plt.figure(figsize=(5, 1.5)) text = fig.text( 0.5, 0.5, 'Shadow Effect', color='b', ha='center', va='center', size=36, weight=500, path_effects=[path_effects.SimplePatchShadow(), path_effects.Normal()]) plt.show() fig = plt.figure(figsize=(5, 1.5)) text = fig.text(0.5, 0.5, 'Stroke Effect', color='orange', ha='center', va='center', size=36) text.set_path_effects( [path_effects.Stroke(linewidth=5, foreground='b'), path_effects.Normal()]) plt.show()
def test_SimplePatchShadow_offset_xy(): with mock.patch('matplotlib.cbook.deprecated') as dep: pe = path_effects.SimplePatchShadow(offset_xy=(4, 5)) assert_equal(pe._offset, (4, 5)) dep.assert_called()
def add_subplot(axis, x, y, xlabel, ylabel, title): global i pear = pearsonr(x, y) reg = linregress(x, y) axis[i].grid(color='#ddd', zorder=0) # Putting grid behind with forced zorder axis[i].scatter(x, y, s=0.4, zorder=2) axis[i].set_xlabel(xlabel) axis[i].set_ylabel(ylabel) axis[i].set_title(title) # Regression axis[i].plot( x, reg.slope * x + reg.intercept, c='brown', label=f'Linear regression: {reg.slope:.3e}*x + {reg.intercept:.2f}') # Legend axis[i].legend(loc="upper right", facecolor='#ddd') # Format for percents if max(y) < 1.5: yformat = mtick.FuncFormatter("{:.0%}".format) axis[i].yaxis.set_major_formatter(yformat) # Fix ylim for APM if max(y) > 100: axis[i].set_ylim([0, 200]) # Data correlation xpos = (axis[i].get_xlim()[1] - axis[i].get_xlim()[0]) * 0.02 + axis[i].get_xlim()[0] effects = [ path_effects.SimplePatchShadow(offset=(0.5, -0.5), alpha=1, shadow_rgbFace='#eee'), path_effects.Normal() ] color = '#333' text = axis[i].text(xpos, axis[i].get_ylim()[1] * 0.85, f'Correlation: {pear[0]:.3f}', fontsize=16, c=color, path_effects=effects) # Data p-value axis[i].text(xpos, axis[i].get_ylim()[1] * 0.78, f'p-value: {pear[1]:.3e}', fontsize=10, c=color, path_effects=effects) # Facecolor axis[i].set_facecolor('#eee') # Update index i += 1