def test_polar_box(): # Remove this line when this test image is regenerated. plt.rcParams['text.kerning_factor'] = 6 fig = plt.figure(figsize=(5, 5)) # PolarAxes.PolarTransform takes radian. However, we want our coordinate # system in degree tr = Affine2D().scale(np.pi / 180., 1.) + PolarAxes.PolarTransform() # polar projection, which involves cycle, and also has limits in # its coordinates, needs a special method to find the extremes # (min, max of the coordinate within the view). extreme_finder = angle_helper.ExtremeFinderCycle(20, 20, lon_cycle=360, lat_cycle=None, lon_minmax=None, lat_minmax=(0, np.inf)) grid_locator1 = angle_helper.LocatorDMS(12) tick_formatter1 = angle_helper.FormatterDMS() grid_helper = GridHelperCurveLinear(tr, extreme_finder=extreme_finder, grid_locator1=grid_locator1, tick_formatter1=tick_formatter1) ax1 = SubplotHost(fig, 1, 1, 1, grid_helper=grid_helper) ax1.axis["right"].major_ticklabels.set_visible(True) ax1.axis["top"].major_ticklabels.set_visible(True) # let right axis shows ticklabels for 1st coordinate (angle) ax1.axis["right"].get_helper().nth_coord_ticks = 0 # let bottom axis shows ticklabels for 2nd coordinate (radius) ax1.axis["bottom"].get_helper().nth_coord_ticks = 1 fig.add_subplot(ax1) ax1.axis["lat"] = axis = grid_helper.new_floating_axis(0, 45, axes=ax1) axis.label.set_text("Test") axis.label.set_visible(True) axis.get_helper().set_extremes(2, 12) ax1.axis["lon"] = axis = grid_helper.new_floating_axis(1, 6, axes=ax1) axis.label.set_text("Test 2") axis.get_helper().set_extremes(-180, 90) # A parasite axes with given transform ax2 = ParasiteAxes(ax1, tr, viewlim_mode="equal") assert ax2.transData == tr + ax1.transData # Anything you draw in ax2 will match the ticks and grids of ax1. ax1.parasites.append(ax2) ax2.plot(np.linspace(0, 30, 50), np.linspace(10, 10, 50)) ax1.set_aspect(1.) ax1.set_xlim(-5, 12) ax1.set_ylim(-5, 10) ax1.grid(True)
def test_custom_transform(): class MyTransform(Transform): input_dims = output_dims = 2 def __init__(self, resolution): """ Resolution is the number of steps to interpolate between each input line segment to approximate its path in transformed space. """ Transform.__init__(self) self._resolution = resolution def transform(self, ll): x, y = ll.T return np.column_stack([x, y - x]) transform_non_affine = transform def transform_path(self, path): ipath = path.interpolated(self._resolution) return Path(self.transform(ipath.vertices), ipath.codes) transform_path_non_affine = transform_path def inverted(self): return MyTransformInv(self._resolution) class MyTransformInv(Transform): input_dims = output_dims = 2 def __init__(self, resolution): Transform.__init__(self) self._resolution = resolution def transform(self, ll): x, y = ll.T return np.column_stack([x, y + x]) def inverted(self): return MyTransform(self._resolution) fig = plt.figure() SubplotHost = host_subplot_class_factory(Axes) tr = MyTransform(1) grid_helper = GridHelperCurveLinear(tr) ax1 = SubplotHost(fig, 1, 1, 1, grid_helper=grid_helper) fig.add_subplot(ax1) ax2 = ParasiteAxes(ax1, tr, viewlim_mode="equal") ax1.parasites.append(ax2) ax2.plot([3, 6], [5.0, 10.]) ax1.set_aspect(1.) ax1.set_xlim(0, 10) ax1.set_ylim(0, 10) ax1.grid(True)
def new_axis(fig, hostax, off=50, loc='bottom', ticks=None, wsadd=0.1, label='', sharex=False, sharey=False): """Make a new axis line using mpl_toolkits.axes_grid's SubplotHost and ParasiteAxes. The new axis line will be an instance of ParasiteAxes attached to `hostax`. You can do twinx()/twiny() type axis (off=0) or completely free-standing axis lines (off > 0). Parameters ---------- fig : mpl Figure hostax : Instance of matplotlib.axes.HostAxesSubplot. This is the subplot of the figure `fig` w.r.t which all new axis lines are placed. See make_axes_grid_fig(). off : offset in points, used with parax.get_grid_helper().new_fixed_axis loc : one of 'left', 'right', 'top', 'bottom', where to place the new axis line ticks : sequence of ticks (numbers) wsadd : Whitespace to add at the location `loc` to make space for the new axis line (only useful if off > 0). The number is a relative unit and is used to change the bounding box: hostax.get_position(). label : str, xlabel (ylabel) for 'top','bottom' ('left', 'right') sharex, sharey : bool, share xaxis (yaxis) with `hostax` Returns ------- (fig, hostax, parax) fig : the Figure hostax : the hostax parax : the new ParasiteAxes instance Notes ----- * The sharex/sharey thing may not work correctly. """ # Create ParasiteAxes, an ax which overlays hostax. if sharex and sharey: parax = ParasiteAxes(hostax, sharex=hostax, sharey=hostax) elif sharex: parax = ParasiteAxes(hostax, sharex=hostax) elif sharey: parax = ParasiteAxes(hostax, sharey=hostax) else: parax = ParasiteAxes(hostax) hostax.parasites.append(parax) # If off != 0, the new axis line will be detached from hostax, i.e. # completely "free standing" below (above, left or right of) the main ax # (hostax), so we don't need anything visilbe from it b/c we create a # new_fixed_axis from this one with an offset anyway. We only need to # activate the label. for _loc in ['left', 'right', 'top', 'bottom']: parax.axis[_loc].set_visible(False) parax.axis[_loc].label.set_visible(True) # Create axis line. Free-standing if off != 0, else overlaying one of hostax's # axis lines. In fact, with off=0, one simulates twinx/y(). new_axisline = parax.get_grid_helper().new_fixed_axis if loc == 'top': offset = (0, off) parax.set_xlabel(label) elif loc == 'bottom': offset = (0, -off) parax.set_xlabel(label) elif loc == 'left': offset = (-off, 0) parax.set_ylabel(label) elif loc == 'right': offset = (off, 0) parax.set_ylabel(label) newax = new_axisline(loc=loc, offset=offset, axes=parax) # name axis lines: bottom2, bottom3, ... n = 2 while loc + str(n) in parax.axis: n += 1 parax.axis[loc + str(n)] = newax # set ticks if ticks is not None: newax.axis.set_ticks(ticks) # Read out whitespace at the location (loc = 'top', 'bottom', 'left', # 'right') and adjust whitespace. # # indices of the values in the array returned by ax.get_position() bbox_idx = dict(left=[0, 0], bottom=[0, 1], right=[1, 0], top=[1, 1]) old_pos = np.array(hostax.get_position())[bbox_idx[loc][0], bbox_idx[loc][1]] if loc in ['top', 'right']: new_ws = old_pos - wsadd else: new_ws = old_pos + wsadd # hack ... cmd = "fig.subplots_adjust(%s=%f)" % (loc, new_ws) eval(cmd) return fig, hostax, parax