def setup_axes(fig, rect, rmax): tr_rotate = Affine2D().translate(0, 0) tr_scale = Affine2D().scale(np.pi / 180, 1) tr = tr_rotate + tr_scale + PolarTransform() grid_locator1 = angle_helper.LocatorDMS(12) grid_locator2 = angle_helper.LocatorDMS(3) tick_formatter1 = angle_helper.FormatterDMS() tick_formatter2 = angle_helper.FormatterDMS() ra0, ra1 = 0, 180 cz0, cz1 = 0, rmax grid_helper = floating_axes.GridHelperCurveLinear( tr, extremes=(ra0, ra1, cz0, cz1), grid_locator1=grid_locator1, grid_locator2=grid_locator2, tick_formatter1=tick_formatter1, tick_formatter2=tick_formatter2) ax1 = floating_axes.FloatingSubplot(fig, rect, grid_helper=grid_helper) fig.add_subplot(ax1) ax1.axis["left"].set_axis_direction("bottom") ax1.axis["right"].set_axis_direction("top") ax1.axis["bottom"].set_visible(False) ax1.axis["top"].set_axis_direction("bottom") ax1.axis["top"].toggle(ticklabels=True, label=True) ax1.axis["top"].major_ticklabels.set_axis_direction("top") ax1.axis["top"].label.set_axis_direction("top") ax1.axis["top"].label.set_text("Tilt Angle") aux_ax = ax1.get_aux_axes(tr) aux_ax.patch = ax1.patch ax1.patch.zorder = 0.9 return ax1, aux_ax
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 setup_axes(fig, rect): """Polar projection, but in a rectangular box.""" # see demo_curvelinear_grid.py for details tr = Affine2D().scale(np.pi / 180., 1.) + PolarAxes.PolarTransform() 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) grid_locator2 = grid_finder.MaxNLocator(5) tick_formatter1 = angle_helper.FormatterDMS() grid_helper = GridHelperCurveLinear(tr, extreme_finder=extreme_finder, grid_locator1=grid_locator1, grid_locator2=grid_locator2, tick_formatter1=tick_formatter1) ax1 = fig.add_subplot(rect, axes_class=axisartist.Axes, grid_helper=grid_helper) ax1.axis[:].set_visible(False) ax1.set_aspect(1.) ax1.set_xlim(-5, 12) ax1.set_ylim(-5, 10) return ax1
def curvelinear_test2(fig, rect=111): """ Polar projection, but in a rectangular box. """ # see demo_curvelinear_grid.py for details tr = Affine2D().translate(0, 90) + Affine2D().scale(np.pi / 180., 1.) + \ PolarAxes.PolarTransform() extreme_finder = angle_helper.ExtremeFinderCycle( 10, 60, lon_cycle=360, lat_cycle=None, lon_minmax=None, lat_minmax=(-90, np.inf), ) # Changes theta gridline count grid_locator1 = angle_helper.LocatorHMS(12) grid_locator2 = angle_helper.LocatorDMS(6) tick_formatter1 = angle_helper.FormatterHMS() tick_formatter2 = angle_helper.FormatterDMS() grid_helper = GridHelperCurveLinear(tr, extreme_finder=extreme_finder, grid_locator1=grid_locator1, grid_locator2=grid_locator2, tick_formatter1=tick_formatter1, tick_formatter2=tick_formatter2) ax1 = SubplotHost(fig, rect, grid_helper=grid_helper) # make ticklabels of right and top axis visible. ax1.axis["right"].major_ticklabels.set_visible(True) ax1.axis["top"].major_ticklabels.set_visible(True) ax1.axis["bottom"].major_ticklabels.set_visible(True) # let right and bottom axis show ticklabels for 1st coordinate (angle) ax1.axis["right"].get_helper().nth_coord_ticks = 0 ax1.axis["bottom"].get_helper().nth_coord_ticks = 0 # fig.add_subplot(ax1) grid_helper = ax1.get_grid_helper() # You may or may not need these - they set the view window explicitly # rather than using the default as determined by matplotlib with extreme # finder. ax1.set_aspect(1.) ax1.set_xlim(-4, 25) # moves the origin left-right in ax1 ax1.set_ylim(-2.5, 30) # moves the origin up-down ax1.set_ylabel('$DEC\,(^{\circ})$') ax1.set_xlabel('$RA\,(h)$') ax1.grid(True) # ax1.grid(linestyle='--', which='x') # either keyword applies to both # ax1.grid(linestyle=':', which='y') # sets of gridlines return ax1, tr
def curvelinear_test2(fig): """ polar projection, but in a rectangular box. """ global ax1 import numpy as np import mpl_toolkits.axisartist.angle_helper as angle_helper from matplotlib.projections import PolarAxes from matplotlib.transforms import Affine2D from mpl_toolkits.axisartist import SubplotHost from mpl_toolkits.axisartist import GridHelperCurveLinear # see demo_curvelinear_grid.py for details tr = Affine2D().scale(np.pi/180., 1.) + PolarAxes.PolarTransform() 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) fig.add_subplot(ax1) # Now creates floating axis #grid_helper = ax1.get_grid_helper() # floating axis whose first coordinate (theta) is fixed at 60 ax1.axis["lat"] = axis = ax1.new_floating_axis(0, 60) axis.label.set_text(r"$\theta = 60^{\circ}$") axis.label.set_visible(True) # floating axis whose second coordinate (r) is fixed at 6 ax1.axis["lon"] = axis = ax1.new_floating_axis(1, 6) axis.label.set_text(r"$r = 6$") ax1.set_aspect(1.) ax1.set_xlim(-5, 12) ax1.set_ylim(-5, 10) ax1.grid(True)
def test_curvelinear3(): fig = plt.figure(figsize=(5, 5)) tr = (mtransforms.Affine2D().scale(np.pi / 180, 1) + mprojections.PolarAxes.PolarTransform()) grid_locator1 = angle_helper.LocatorDMS(15) tick_formatter1 = angle_helper.FormatterDMS() grid_locator2 = FixedLocator([2, 4, 6, 8, 10]) grid_helper = GridHelperCurveLinear( tr, extremes=(0, 360, 10, 3), grid_locator1=grid_locator1, grid_locator2=grid_locator2, tick_formatter1=tick_formatter1, tick_formatter2=None, ) ax1 = FloatingSubplot(fig, 111, grid_helper=grid_helper) fig.add_subplot(ax1) r_scale = 10 tr2 = mtransforms.Affine2D().scale(1, 1 / r_scale) + tr grid_locator2 = FixedLocator([30, 60, 90]) grid_helper2 = GridHelperCurveLinear(tr2, extremes=(0, 360, 10 * r_scale, 3 * r_scale), grid_locator2=grid_locator2) ax1.axis["right"] = axis = grid_helper2.new_fixed_axis("right", axes=ax1) ax1.axis["left"].label.set_text("Test 1") ax1.axis["right"].label.set_text("Test 2") for an in ["left", "right"]: ax1.axis[an].set_visible(False) axis = grid_helper.new_floating_axis(1, 7, axes=ax1, axis_direction="bottom") ax1.axis["z"] = axis axis.toggle(all=True, label=True) axis.label.set_text("z = ?") axis.label.set_visible(True) axis.line.set_color("0.5") ax2 = ax1.get_aux_axes(tr) xx, yy = [67, 90, 75, 30], [2, 5, 8, 4] ax2.scatter(xx, yy) (l, ) = ax2.plot(xx, yy, "k-") l.set_clip_path(ax1.patch)
def create_axes(self, rect=111): """ Create a special AxisArtist to overlay grid coordinates. Much of this taken from the examples here: http://matplotlib.org/mpl_toolkits/axes_grid/users/axisartist.html """ # from curved coordinate to rectlinear coordinate. def tr(x, y): x, y = np.asarray(x), np.asarray(y) return self(x, y) # from rectlinear coordinate to curved coordinate. def inv_tr(x, y): x, y = np.asarray(x), np.asarray(y) return self(x, y, inverse=True) # Cycle the coordinates extreme_finder = angle_helper.ExtremeFinderCycle(20, 20) # Find a grid values appropriate for the coordinate. # The argument is a approximate number of grid lines. grid_locator1 = angle_helper.LocatorD(8, include_last=False) grid_locator2 = angle_helper.LocatorD(6, include_last=False) # Format the values of the grid tick_formatter1 = FormatterFgcm() tick_formatter2 = angle_helper.FormatterDMS() grid_helper = GridHelperCurveLinear( (tr, inv_tr), extreme_finder=extreme_finder, grid_locator1=grid_locator1, grid_locator2=grid_locator2, tick_formatter1=tick_formatter1, tick_formatter2=tick_formatter2, ) fig = plt.gcf() ax = axisartist.Subplot(fig, rect, grid_helper=grid_helper) fig.add_subplot(ax) ax.axis['left'].major_ticklabels.set_visible(True) ax.axis['right'].major_ticklabels.set_visible(True) ax.axis['bottom'].major_ticklabels.set_visible(True) ax.axis['top'].major_ticklabels.set_visible(True) ax.set_xlabel("Right Ascension") ax.set_ylabel("Declination") return fig, ax
def curvelinear_test2(fig): """ Polar projection, but in a rectangular box. """ # 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( nx=20, ny=20, # Number of sampling points in each direction. lon_cycle=360, lat_cycle=None, lon_minmax=None, lat_minmax=(0, np.inf), ) # Find grid values appropriate for the coordinate (degree, minute, second). grid_locator1 = angle_helper.LocatorDMS(12) # Use an appropriate formatter. Note that the acceptable Locator and # Formatter classes are a bit different than that of Matplotlib, which # cannot directly be used here (this may be possible in the future). 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, 2, 2, grid_helper=grid_helper) # make ticklabels of right and top axis visible. 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.set_aspect(1) ax1.set_xlim(-5, 12) ax1.set_ylim(-5, 10) ax1.grid(True, zorder=0) # A parasite axes with given transform ax2 = ParasiteAxesAuxTrans(ax1, tr, "equal") # note that 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, 51), np.linspace(10, 10, 51), linewidth=2)
def curvelinear_test(fig): """Polar projection, but in a rectangular box. """ # 创建一个极坐标变换。PolarAxes.PolarTransform使用弧度,但本例 # 要设置的坐标系中角度的单位为度 tr = Affine2D().scale(np.pi / 180., 1.) + PolarAxes.PolarTransform() # 极坐标投影涉及到周期,在坐标上也有限制,需要一种特殊的方法来找到 # 坐标的最小值和最大值 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) # 使用适当的Formatter。请注意,可接受的Locator和Formatter类 # 与Matplotlib中的相应类稍有不同,后者目前还不能直接在这里使用 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) fig.add_subplot(ax1) # 创建浮动坐标轴 # 浮动坐标轴的第一个坐标(theta)指定为60度 ax1.axis["lat"] = axis = ax1.new_floating_axis(0, 60) axis.label.set_text(r"$\theta = 60^{\circ}$") axis.label.set_visible(True) # 浮动坐标轴的第二个坐标(r)指定为6 ax1.axis["lon"] = axis = ax1.new_floating_axis(1, 6) axis.label.set_text(r"$r = 6$") ax1.set_aspect(1.) ax1.set_xlim(-5, 12) ax1.set_ylim(-5, 10) ax1.grid(True)
def test_curvelinear4(): # Remove this line when this test image is regenerated. plt.rcParams['text.kerning_factor'] = 6 fig = plt.figure(figsize=(5, 5)) tr = (mtransforms.Affine2D().scale(np.pi / 180, 1) + mprojections.PolarAxes.PolarTransform()) grid_locator1 = angle_helper.LocatorDMS(5) tick_formatter1 = angle_helper.FormatterDMS() grid_locator2 = FixedLocator([2, 4, 6, 8, 10]) grid_helper = GridHelperCurveLinear(tr, extremes=(120, 30, 10, 0), grid_locator1=grid_locator1, grid_locator2=grid_locator2, tick_formatter1=tick_formatter1, tick_formatter2=None) ax1 = FloatingSubplot(fig, 111, grid_helper=grid_helper) fig.add_subplot(ax1) ax1.axis["left"].label.set_text("Test 1") ax1.axis["right"].label.set_text("Test 2") for an in ["top"]: ax1.axis[an].set_visible(False) axis = grid_helper.new_floating_axis(1, 70, axes=ax1, axis_direction="bottom") ax1.axis["z"] = axis axis.toggle(all=True, label=True) axis.label.set_axis_direction("top") axis.label.set_text("z = ?") axis.label.set_visible(True) axis.line.set_color("0.5") ax2 = ax1.get_aux_axes(tr) xx, yy = [67, 90, 75, 30], [2, 5, 8, 4] ax2.scatter(xx, yy) l, = ax2.plot(xx, yy, "k-") l.set_clip_path(ax1.patch)
def curvelinear_test2(fig): """Polar projection, but in a rectangular box.""" # see demo_curvelinear_grid.py for details tr = Affine2D().scale(np.pi / 180., 1.) + PolarAxes.PolarTransform() 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 = fig.add_subplot(axes_class=HostAxes, grid_helper=grid_helper) # Now creates floating axis # floating axis whose first coordinate (theta) is fixed at 60 ax1.axis["lat"] = axis = ax1.new_floating_axis(0, 60) axis.label.set_text(r"$\theta = 60^{\circ}$") axis.label.set_visible(True) # floating axis whose second coordinate (r) is fixed at 6 ax1.axis["lon"] = axis = ax1.new_floating_axis(1, 6) axis.label.set_text(r"$r = 6$") ax1.set_aspect(1.) ax1.set_xlim(-5, 12) ax1.set_ylim(-5, 10) ax1.grid(True)
def setup_axes(fig, rect): """ polar projection, but in a rectangular box. """ # 细节可以参考前面“曲线网格”的例子 tr = Affine2D().scale(np.pi/180., 1.) + PolarAxes.PolarTransform() 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) grid_locator2 = grid_finder.MaxNLocator(5) tick_formatter1 = angle_helper.FormatterDMS() grid_helper = GridHelperCurveLinear(tr, extreme_finder=extreme_finder, grid_locator1=grid_locator1, grid_locator2=grid_locator2, tick_formatter1=tick_formatter1 ) ax1 = axisartist.Subplot(fig, rect, grid_helper=grid_helper) ax1.axis[:].toggle(ticklabels=False) fig.add_subplot(ax1) ax1.set_aspect(1.) ax1.set_xlim(-5, 12) ax1.set_ylim(-5, 10) return ax1
def make_polar_axis(figure): """ Generate a polar axis. Examples -------- >>> from pylab import * >>> f = figure() >>> ax1,ax2 = make_polar_axis(f) >>> f.add_subplot(ax1) """ # 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). # 20, 20 : number of sampling points along x, y direction extreme_finder = angle_helper.ExtremeFinderCycle( 40, 40, lon_cycle=360, lat_cycle=None, lon_minmax=None, lat_minmax=(0, np.inf), ) grid_locator1 = angle_helper.LocatorDMS(12) # Find a grid values appropriate for the coordinate (degree, # minute, second). tick_formatter1 = angle_helper.FormatterDMS() # And also uses an appropriate formatter. Note that,the # acceptable Locator and Formatter class is a bit different than # that of mpl's, and you cannot directly use mpl's Locator and # Formatter here (but may be possible in the future). grid_helper = GridHelperCurveLinear( tr, extreme_finder=extreme_finder, grid_locator1=grid_locator1, tick_formatter1=tick_formatter1, #tick_formatter2=matplotlib.ticker.FuncFormatter(lambda x: x * kpc_per_pix) ) ax1 = SubplotHost(figure, 1, 1, 1, grid_helper=grid_helper, axisbg='#333333') # make ticklabels of right and top axis visible. 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 ax2 = ParasiteAxesAuxTrans(ax1, tr, "equal") ax1.parasites.append(ax2) return ax1, ax2
def make_mw_plot(fig=None, mw_img_name = "Milky_Way_2005.jpg", solar_rad=8.5, fignum=5): """ Generate a "Milky Way" plot with Robert Hurt's Milky Way illustration as the background. .. TODO: Figure out how to fix the axis labels. They don't work now! Parameters ---------- fig : matplotlib.figure instance If you want to start with a figure instance, can specify it mw_img_name: str The name of the image on disk solar_rad : float The assumed Galactocentric orbital radius of the sun fignum : int If Figure not specified, use this figure number """ # load image mw = np.array(PIL.Image.open(mw_img_name))[:,::-1] # set some constants npix = mw.shape[0] # must be symmetric # Galactic Center in middle of image gc_loc = [x/2 for x in mw.shape] # Sun is at 0.691 (maybe really 0.7?) length of image sun_loc = mw.shape[0]/2,int(mw.shape[1]*0.691) # determine scaling kpc_per_pix = solar_rad / (sun_loc[1]-gc_loc[1]) boxsize = npix*kpc_per_pix # most of the code below is taken from: # http://matplotlib.sourceforge.net/examples/axes_grid/demo_curvelinear_grid.html # and http://matplotlib.sourceforge.net/examples/axes_grid/demo_floating_axis.html if fig is None: fig = plt.figure(fignum) plt.clf() # PolarAxes.PolarTransform takes radian. However, we want our coordinate # system in degree # this defines the polar coordinate system @ Galactic center 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). # grid helper stuff, I think (grid is off by default) # This may not apply to the image *at all*, but would if you # used the grid # 40, 40 : number of sampling points along x, y direction extreme_finder = angle_helper.ExtremeFinderCycle(40, 40, lon_cycle = 360, lat_cycle = None, lon_minmax = None, lat_minmax = (0, np.inf), ) grid_locator1 = angle_helper.LocatorDMS(12) # Find a grid values appropriate for the coordinate (degree, # minute, second). tick_formatter1 = angle_helper.FormatterDMS() # And also uses an appropriate formatter. Note that,the # acceptable Locator and Formatter class is a bit different than # that of mpl's, and you cannot directly use mpl's Locator and # Formatter here (but may be possible in the future). grid_helper = GridHelperCurveLinear(tr, extreme_finder=extreme_finder, grid_locator1=grid_locator1, tick_formatter1=tick_formatter1, #tick_formatter2=matplotlib.ticker.FuncFormatter(lambda x: x * kpc_per_pix) ) ax = SubplotHost(fig, 1, 1, 1, grid_helper=grid_helper, axisbg='#333333') fig.add_subplot(ax) # ax.transData is still a (rectlinear) pixel coordinate. Only the # grids are done in galactocentric coordinate. # show the image ax.imshow(mw,extent=[-boxsize/2,boxsize/2,-boxsize/2,boxsize/2]) ax_pixgrid = ax.twin() # simple twin will give you a twin axes, # but with normal grids. # to draw heliocentric grids, it is best to update the grid_helper # with new transform. # need to rotate by -90 deg to get into the standard convention tr_helio = Affine2D().scale(np.pi/180., 1.).translate(-np.pi/2.,0) + \ PolarAxes.PolarTransform() + \ Affine2D().translate(0,solar_rad) # Note that the transform is from the heliocentric coordinate to # the pixel coordinate of ax (i.e., ax.transData). ax.get_grid_helper().update_grid_finder(aux_trans=tr_helio) # Now we defina parasite axes with galactocentric & heliocentric # coordinates. # A parasite axes with given transform gc_polar = ParasiteAxesAuxTrans(ax, tr, "equal") ax.parasites.append(gc_polar) # note that ax2.transData == tr + galactocentric_axis.transData # Anthing you draw in ax2 will match the ticks and grids of galactocentric_axis. hc_polar = ParasiteAxesAuxTrans(ax, tr_helio, "equal") ax.parasites.append(hc_polar) return ax, ax_pixgrid, gc_polar, hc_polar
def test_axis_direction(): 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). # 20, 20 : number of sampling points along x, y direction 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) for axis in ax1.axis.values(): axis.set_visible(False) fig.add_subplot(ax1) ax1.axis["lat1"] = axis = grid_helper.new_floating_axis( 0, 130, axes=ax1, axis_direction="left") axis.label.set_text("Test") axis.label.set_visible(True) axis.get_helper()._extremes = 0.001, 10 ax1.axis["lat2"] = axis = grid_helper.new_floating_axis( 0, 50, axes=ax1, axis_direction="right") axis.label.set_text("Test") axis.label.set_visible(True) axis.get_helper()._extremes = 0.001, 10 ax1.axis["lon"] = axis = grid_helper.new_floating_axis( 1, 10, axes=ax1, axis_direction="bottom") axis.label.set_text("Test 2") axis.get_helper()._extremes = 50, 130 axis.major_ticklabels.set_axis_direction("top") axis.label.set_axis_direction("top") grid_helper.grid_finder.grid_locator1.den = 5 grid_helper.grid_finder.grid_locator2._nbins = 5 ax1.set_aspect(1.) ax1.set_xlim(-8, 8) ax1.set_ylim(-4, 12) ax1.grid(True)
def plotGsrResidue(theta, phi, residue, optTheta, optPhi, mvabTheta=None, mvabPhi=None, mvubTheta=None, mvubPhi=None): fig = figure() fig.clf() # some matplotlib setup stuff which I don't fully understand but it works tr = Affine2D().scale(pi / 180., 1.) + PolarAxes.PolarTransform() extreme_finder = angle_helper.ExtremeFinderCycle( 20, 20, lon_cycle=360, lat_cycle=None, lon_minmax=None, lat_minmax=(0, 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) fig.add_subplot(ax1) ax1.axis["right"].major_ticklabels.set_visible(True) ax1.axis["top"].major_ticklabels.set_visible(True) ax1.axis["right"].get_helper().nth_coord_ticks = 0 ax1.axis["bottom"].get_helper().nth_coord_ticks = 1 # draw the filled contoured map in polar coordinates ax1.contour(transpose(mat(theta)) * mat(cos(phi * pi / 180)), transpose(mat(theta)) * mat(sin(phi * pi / 180)), 1 / transpose(reshape(residue, (phi.size, -1))), 100, lw=0.1) cc = ax1.contourf( transpose(mat(theta)) * mat(cos(phi * pi / 180)), transpose(mat(theta)) * mat(sin(phi * pi / 180)), 1 / transpose(reshape(residue, (phi.size, -1))), 100) # remove gaps between the contour lines for c in cc.collections: c.set_antialiased(False) # show the MVAB direction if mvabTheta is not None and mvabPhi is not None: ax1.plot(mvabTheta * cos(mvabPhi * pi / 180), mvabTheta * sin(mvabPhi * pi / 180), 'sk', markersize=8) # show the MVUB direction if mvubTheta is not None and mvubPhi is not None: ax1.plot(mvubTheta * cos(mvubPhi * pi / 180), mvubTheta * sin(mvubPhi * pi / 180), 'dk', markersize=8) # show the optimal direction ax1.plot(optTheta * cos(optPhi * pi / 180), optTheta * sin(optPhi * pi / 180), '.k', markersize=15) # aspect and initial axes limits ax1.set_aspect(1.) ax1.set_xlim(-90, 90) ax1.set_ylim(-90, 90) # add grid ax1.grid(True) # add colobar cb = colorbar(cc, pad=0.07) cb.locator = MaxNLocator(14) cb.update_ticks() cb.set_label(r"$1/\tilde{\mathcal{R}}$") # save if toSave: savefig(resultsDir + '/eps/gsr_ResidualMap.eps', format='eps') savefig(resultsDir + '/png/gsr_ResidualMap.png', format='png')
def setup_axes(fig, rect, theta, radius, quad): # quad controls the quadrant of the plot and controls the orientation # of the plot where quad=1 is upper left, 2 is upper right, 3 is # lower left, 4 is lower right if quad == 1: tr_rotate = Affine2D().translate(np.pi / 2.0, 0) elif quad == 2: tr_rotate = Affine2D().translate(0, 0) elif quad == 3: tr_rotate = Affine2D().translate(np.pi, 0) else: tr_rotate = Affine2D().translate(3.0 * np.pi / 2.0, 0) tr_scale = Affine2D().scale(np.pi / 180., 1.) # PolarAxes.PolarTransform takes radian. However, we want our coordinate # system in degree tr = tr_scale + tr_rotate + PolarAxes.PolarTransform() # Find grid values appropriate for the coordinate (degree). # The argument is an approximate number of grids. grid_locator1 = angle_helper.LocatorD(2) # And also use an appropriate formatter: tick_formatter1 = angle_helper.FormatterDMS() # set up number of ticks for the r-axis grid_locator2 = MaxNLocator(5) grid_locator1 = MaxNLocator(6) # the extremes are passed to the function thetaMin = 0 thetaMax = 90 grid_helper = floating_axes.GridHelperCurveLinear( tr, extremes=(thetaMin, thetaMax, radius[0], radius[1]), grid_locator1=grid_locator1, grid_locator2=grid_locator2, tick_formatter1=tick_formatter1, tick_formatter2=None, ) ax1 = floating_axes.FloatingSubplot(fig, rect, grid_helper=grid_helper) fig.add_subplot(ax1) print ax1.get_xlim() print ax1.get_ylim() # adjust axis # the axis artist lets you call axis with # "bottom", "top", "left", "right" ax1.axis["left"].set_axis_direction("bottom") ax1.axis["right"].set_axis_direction("top") ax1.axis["bottom"].set_visible(False) ax1.axis["top"].set_axis_direction("bottom") ax1.axis["top"].toggle(ticklabels=True, label=True) ax1.axis["top"].major_ticklabels.set_axis_direction("top") ax1.axis["top"].label.set_axis_direction("top") ax1.axis["top"].label.set_text(ur"$\Phi$") # Set the axis labels based on the quadrant if quad == 1: # Set visibilities ax1.axis["right"].set_visible(True) ax1.axis["left"].set_visible(True) ax1.axis["right"].toggle(ticklabels=True, label=True) ax1.axis["left"].toggle(ticklabels=False, label=False) # Tick Labels #ax1.axis["right"].major_ticks.set_axis_direction('right') ax1.axis["right"].major_ticklabels.set_axis_direction('bottom') #ax1.axis["right"].major_ticklabels.set_pad(-20) #ax1.axis["right"].set_axis_direction('top') #ax1.axis["right"].set_ticklabel_direction('+') # Axis labels ax1.axis["right"].label.set_rotation(0) ax1.axis["right"].label.set_text("$D$ (kpc)") ax1.axis["right"].label.set_pad(20) elif quad == 2: ax1.axis["left"].set_visible(True) ax1.axis["left"].toggle(ticklabels=True, label=True) ax1.axis["left"].major_ticklabels.set_axis_direction("bottom") ax1.axis["left"].set_axis_direction("bottom") ax1.axis["left"].label.set_text("$D$ (kpc)") elif quad == 3: # Set visibilities ax1.axis["right"].set_visible(True) ax1.axis["left"].set_visible(True) ax1.axis["right"].toggle(ticklabels=False, label=False) ax1.axis["left"].toggle(ticklabels=True, label=True) # Tick Labels #ax1.axis["right"].major_ticks.set_axis_direction('right') ax1.axis["left"].major_ticklabels.set_axis_direction('top') #ax1.axis["right"].major_ticklabels.set_pad(-20) #ax1.axis["right"].set_axis_direction('top') #ax1.axis["right"].set_ticklabel_direction('+') # Axis labels ax1.axis["left"].label.set_rotation(180) ax1.axis["left"].label.set_text("$D$ (kpc)") ax1.axis["left"].label.set_pad(20) else: # Set visibilities ax1.axis["right"].set_visible(True) ax1.axis["left"].set_visible(True) ax1.axis["right"].toggle(ticklabels=True, label=True) ax1.axis["left"].toggle(ticklabels=False, label=False) # Tick Labels #ax1.axis["right"].major_ticks.set_axis_direction('right') ax1.axis["right"].major_ticklabels.set_axis_direction('top') #ax1.axis["right"].major_ticklabels.set_pad(-20) #ax1.axis["right"].set_axis_direction('top') #ax1.axis["right"].set_ticklabel_direction('+') # Axis labels ax1.axis["right"].label.set_rotation(180) ax1.axis["right"].label.set_text("$D$ (kpc)") ax1.axis["right"].label.set_pad(0) ax1.grid(True) # create a parasite axes aux_ax = ax1.get_aux_axes(tr) aux_ax.patch = ax1.patch # for aux_ax to have a clip path as in ax ax1.patch.zorder = 0.9 # but this has a side effect that the patch is # drawn twice, and possibly over some other # artists. So, we decrease the zorder a bit to # prevent this. return ax1, aux_ax
# strad = [ 0 ] # nstat = len( mamp ) # while num < nstat: # # print num, nstat, mphs[num] # if num == 0: # dtrad[num] = math.radians( mphs[num] ) # strad[num] = math.radians( sphs[num] ) # else: # dtrad.append( math.radians( mphs[num] )) # strad.append( math.radians( sphs[num] )) # num = num + 1 #angle_ticks = [(0, r"$0$"), (.25*pi, r"$\frac{1}{4}\pi$"), (.5*pi, r"$\frac{1}{2}\pi$")] grid_locator1 = angle_helper.LocatorDMS(12) tick_formatter1 = angle_helper.FormatterDMS() grid_locator2 = MaxNLocator(2) dtrad = (np.array(mphs)) strad = (np.array(sphs)) total = np.hstack([dtrad, strad]) checkrange_s = 0 def mod_dist(a, b): return np.min([np.mod(a - b, 360), np.mod(b - a, 360)]) for a in total: for b in total:
def polar_stuff(fig, telescope): # PolarAxes.PolarTransform takes radian. However, we want our coordinate # system in degree tr = Affine2D().scale(np.pi / 180., 1.).translate( +np.pi / 2., 0) + 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). # 20, 20 : number of sampling points along x, y direction n = 1 extreme_finder = angle_helper.ExtremeFinderCycle( n, n, lon_cycle=360, lat_cycle=None, lon_minmax=None, lat_minmax=(-90, 90), ) grid_locator1 = angle_helper.LocatorDMS(12) # Find a grid values appropriate for the coordinate (degree, # minute, second). tick_formatter1 = angle_helper.FormatterDMS() # And also uses an appropriate formatter. Note that,the # acceptable Locator and Formatter class is a bit different than # that of mpl's, and you cannot directly use mpl's Locator and # Formatter here (but may be possible in the future). 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) # make ticklabels of right and top axis visible. 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) # A parasite axes with given transform ax2 = ParasiteAxesAuxTrans(ax1, tr, "equal") # note that ax2.transData == tr + ax1.transData # Anything you draw in ax2 will match the ticks and grids of ax1. ax1.parasites.append(ax2) # intp = cbook.simple_linear_interpolation #ax2.plot(intp(np.array([0, 30]), 50), # intp(np.array([10., 10.]), 50), # linewidth=2.0) x = np.rad2deg(telescope.az.value) * np.cos(telescope.alt.value) y = np.rad2deg(telescope.alt.value) circle = plt.Circle( (np.rad2deg(telescope.az.value - np.pi) * np.sin(telescope.alt.value), np.rad2deg(-telescope.alt.value * np.cos( (telescope.az.value - np.pi)))), radius=7.7 / 2, color="red", alpha=0.2, ) circle = plt.Circle( (x, y), radius=7.7 / 2, color="red", alpha=0.2, ) ax1.add_artist(circle) # point = ax1.scatter(x, y, c="b", s=20, zorder=10, transform=ax2.transData) ax2.annotate(1, (x, y), fontsize=15, xytext=(4, 4), textcoords='offset pixels') ax1.set_xlim(-180, 180) ax1.set_ylim(0, 90) ax1.set_aspect(1.) ax1.grid(True, zorder=0) ax1.set_xlabel("Azimuth in degrees", fontsize=20) ax1.set_ylabel("Zenith in degrees", fontsize=20) plt.show() return fig
def create_axes(self,rect=111): """ Create a special AxisArtist to overlay grid coordinates. Much of this taken from the examples here: http://matplotlib.org/mpl_toolkits/axes_grid/users/axisartist.html """ # from curved coordinate to rectlinear coordinate. def tr(x, y): x, y = np.asarray(x), np.asarray(y) return self(x,y) # from rectlinear coordinate to curved coordinate. def inv_tr(x,y): x, y = np.asarray(x), np.asarray(y) return self(x,y,inverse=True) # Cycle the coordinates extreme_finder = angle_helper.ExtremeFinderCycle(20, 20) # Find a grid values appropriate for the coordinate. # The argument is a approximate number of grid lines. grid_locator1 = angle_helper.LocatorD(9,include_last=False) #grid_locator1 = angle_helper.LocatorD(8,include_last=False) grid_locator2 = angle_helper.LocatorD(6,include_last=False) # Format the values of the grid tick_formatter1 = self.create_tick_formatter() tick_formatter2 = angle_helper.FormatterDMS() grid_helper = GridHelperCurveLinear((tr, inv_tr), extreme_finder=extreme_finder, grid_locator1=grid_locator1, grid_locator2=grid_locator2, tick_formatter1=tick_formatter1, tick_formatter2=tick_formatter2, ) fig = plt.gcf() if rect is None: # This doesn't quite work. Need to remove the existing axis... rect = plt.gca().get_position() plt.gca().axis('off') ax = axisartist.Axes(fig,rect,grid_helper=grid_helper) fig.add_axes(ax) else: ax = axisartist.Subplot(fig,rect,grid_helper=grid_helper) fig.add_subplot(ax) ## Coordinate formatter def format_coord(x, y): return 'lon=%1.4f, lat=%1.4f'%inv_tr(x,y) ax.format_coord = format_coord ax.axis['left'].major_ticklabels.set_visible(True) ax.axis['right'].major_ticklabels.set_visible(False) ax.axis['bottom'].major_ticklabels.set_visible(True) ax.axis['top'].major_ticklabels.set_visible(True) ax.set_xlabel("Right Ascension") ax.set_ylabel("Declination") #self.set_axes_limits() self.axisartist = ax return fig,ax
def create_axes(self, rect=111): """ Create a special AxisArtist to overlay grid coordinates. Much of this taken from the examples here: http://matplotlib.org/mpl_toolkits/axes_grid/users/axisartist.html """ # from curved coordinate to rectlinear coordinate. def tr(x, y): return self(x, y) # from rectlinear coordinate to curved coordinate. def inv_tr(x, y): return self(x, y, inverse=True) # Cycle the coordinates extreme_finder = angle_helper.ExtremeFinderCycle(20, 20) # Find a grid values appropriate for the coordinate. # The argument is a approximate number of grid lines. grid_locator1 = angle_helper.LocatorD(9, include_last=False) # grid_locator1 = angle_helper.LocatorD(8, include_last=False) grid_locator2 = angle_helper.LocatorD(6, include_last=False) # Format the values of the grid tick_formatter1 = self.create_tick_formatter() tick_formatter2 = angle_helper.FormatterDMS() grid_helper = GridHelperCurveLinear( (tr, inv_tr), extreme_finder=extreme_finder, grid_locator1=grid_locator1, grid_locator2=grid_locator2, tick_formatter1=tick_formatter1, tick_formatter2=tick_formatter2, ) fig = plt.gcf() rect = self.ax.get_position() ax = axisartist.Axes(fig, rect, grid_helper=grid_helper, frameon=False) fig.add_axes(ax) # Coordinate formatter def format_coord(x, y): return 'lon=%1.4f, lat=%1.4f' % inv_tr(x, y) ax.format_coord = format_coord ax.axis['left'].major_ticklabels.set_visible(True) ax.axis['right'].major_ticklabels.set_visible(False) ax.axis['bottom'].major_ticklabels.set_visible(True) ax.axis['top'].major_ticklabels.set_visible(True) ax.axis['bottom'].label.set(text="Right Ascension", size=18) ax.axis['left'].label.set(text="Declination", size=18) self.aa = ax # Set the current axis back to the SkyAxes fig.sca(self.ax) return fig, ax
def create_cg(st, fig=None, subplot=111): """ Helper function to create curvelinear grid The function makes use of the Matplotlib AXISARTIST namespace `mpl_toolkits.axisartist \ <https://matplotlib.org/mpl_toolkits/axes_grid/users/axisartist.html>`_. Here are some limitations to normal Matplotlib Axes. While using the Matplotlib `AxesGrid Toolkit \ <https://matplotlib.org/mpl_toolkits/axes_grid/index.html>`_ most of the limitations can be overcome. See `Matplotlib AxesGrid Toolkit User’s Guide \ <https://matplotlib.org/mpl_toolkits/axes_grid/users/index.html>`_. Parameters ---------- st : string scan type, 'PPI' or 'RHI' fig : matplotlib Figure object If given, the PPI will be plotted into this figure object. Axes are created as needed. If None a new figure object will be created or current figure will be used, depending on "subplot". subplot : :class:`matplotlib:matplotlib.gridspec.GridSpec`, \ matplotlib grid definition nrows/ncols/plotnumber, see examples section defaults to '111', only one subplot Returns ------- cgax : matplotlib toolkit axisartist Axes object curvelinear Axes (r-theta-grid) caax : matplotlib Axes object (twin to cgax) Cartesian Axes (x-y-grid) for plotting cartesian data paax : matplotlib Axes object (parasite to cgax) The parasite axes object for plotting polar data """ if st == 'RHI': # create transformation tr = Affine2D().scale(np.pi / 180, 1) + PolarAxes.PolarTransform() # build up curvelinear grid extreme_finder = ah.ExtremeFinderCycle(20, 20, lon_cycle=100, lat_cycle=None, lon_minmax=(0, np.inf), lat_minmax=(0, np.inf), ) # locator and formatter for angular annotation grid_locator1 = ah.LocatorDMS(10.) tick_formatter1 = ah.FormatterDMS() # grid_helper for curvelinear grid grid_helper = GridHelperCurveLinear(tr, extreme_finder=extreme_finder, grid_locator1=grid_locator1, grid_locator2=None, tick_formatter1=tick_formatter1, tick_formatter2=None, ) # try to set nice locations for range gridlines grid_helper.grid_finder.grid_locator2._nbins = 30.0 grid_helper.grid_finder.grid_locator2._steps = [0, 1, 1.5, 2, 2.5, 5, 10] if st == 'PPI': # Set theta start to north tr_rotate = Affine2D().translate(-90, 0) # set theta running clockwise tr_scale = Affine2D().scale(-np.pi / 180, 1) # create transformation tr = tr_rotate + tr_scale + PolarAxes.PolarTransform() # build up curvelinear grid extreme_finder = ah.ExtremeFinderCycle(20, 20, lon_cycle=360, lat_cycle=None, lon_minmax=(360, 0), lat_minmax=(0, np.inf), ) # locator and formatter for angle annotation locs = [i for i in np.arange(0., 359., 10.)] grid_locator1 = FixedLocator(locs) tick_formatter1 = DictFormatter(dict([(i, r"${0:.0f}^\circ$".format(i)) for i in locs])) # grid_helper for curvelinear grid grid_helper = GridHelperCurveLinear(tr, extreme_finder=extreme_finder, grid_locator1=grid_locator1, grid_locator2=None, tick_formatter1=tick_formatter1, tick_formatter2=None, ) # try to set nice locations for range gridlines grid_helper.grid_finder.grid_locator2._nbins = 15.0 grid_helper.grid_finder.grid_locator2._steps = [0, 1, 1.5, 2, 2.5, 5, 10] # if there is no figure object given if fig is None: # create new figure if there is only one subplot if subplot is 111: fig = pl.figure() # otherwise get current figure or create new figure else: fig = pl.gcf() # generate Axis cgax = SubplotHost(fig, subplot, grid_helper=grid_helper) fig.add_axes(cgax) # PPIs always plottetd with equal aspect if st == 'PPI': cgax.set_aspect('equal', adjustable='box') # get twin axis for cartesian grid caax = cgax.twin() # move axis annotation from right to left and top to bottom for # cartesian axis caax.toggle_axisline() # make right and top axis visible and show ticklabels (curvelinear axis) cgax.axis["top", "right"].set_visible(True) cgax.axis["top", "right"].major_ticklabels.set_visible(True) # make ticklabels of left and bottom axis invisible (curvelinear axis) cgax.axis["left", "bottom"].major_ticklabels.set_visible(False) # and also set tickmarklength to zero for better presentation # (curvelinear axis) cgax.axis["top", "right", "left", "bottom"].major_ticks.set_ticksize(0) # show theta (angles) on top and right axis cgax.axis["top"].get_helper().nth_coord_ticks = 0 cgax.axis["right"].get_helper().nth_coord_ticks = 0 # generate and add parasite axes with given transform paax = ParasiteAxesAuxTrans(cgax, tr, "equal") # note that paax.transData == tr + cgax.transData # Anything you draw in paax will match the ticks and grids of cgax. cgax.parasites.append(paax) return cgax, caax, paax
def cone( ra, z, scale=0.5, orientation='horizontal', raaxis='min', ralim=None, zlim=None, hms=False, # cosmology=None, lookbtime=False, plot=None, fig=None, subnum=None, xlabel=r"$\alpha$", ylabel=r"$\mathsf{redshift}$", **kwargs): """ Make a wedge plot of RA/Dec vs redshift z, where RA/DEC are in degrees Parameters ---------- Input data angle : (n, ) array RA in degrees redshift : (n, ) array scale: 0.5 orientation: 'horizontal': increasing z along +ve xaxis 'vertical': increasing z along +ve yaxis angle in degrees: increasing z along the tilted axis raxis: 'min' | 'mid' | float default is 'min' RA value along which the cone plot is orientated horizontal or vertical ralim, zlim: list [ramin, rmax], list [zmin, zmax] default is taken from the lower/upper bound of the input data scatter: any kwargs compatible with plt.scatter hms: show RA labels in units of hours (if True) or degrees (if False) lookbtime: True/False plot: None 'scatter' | 'hexbin' etc fig: supply figure instance default None subnum: subplot number e.g. 111, 221 etc default None xlabel: r"$\alpha$" ylabel: r"$\mathsf{redshift}$" cosmology: dict Uses cosmolopy package to compute look-back time default cosmology is {'omega_M_0': 0.3, 'omega_lambda_0': 0.7, 'h': 0.72} kwargs ------ scatter = {'s': 4, 'marker': ','} Notes ----- --Decorations that can be done outside the code: Draw grids: ax.grid(True, alpha=0.2) Set title: ax.set_title('Wedge plot') --Look-back time as twin axis to redshift not yet implemented --In future plan is to able to put colorbar in the plot too. Using cmap option. """ # ------ Extents of ra and z if ralim: ramin, ramax = ralim else: ramin, ramax = ra.min(), ra.max() if zlim: zmin, zmax = zlim else: zmin, zmax = z.min(), z.max() # ----- Scale and Orientation of the wedge if orientation == 'horizontal': dirn = 0. elif orientation == 'vertical': dirn = 90. else: dirn = orientation if raaxis == 'min': raaxis = ramin elif raaxis == 'mid': raaxis = 0.5 * (ramin + ramax) # Tilt of a cone relative to minimum RA tr_rotate = Affine2D().translate(dirn / scale - raaxis, 0.0) # Scaling the opening angle tr_scale = Affine2D().scale(scale * np.pi / 180., 1.0) tr = tr_rotate + tr_scale + PolarAxes.PolarTransform() # ---- Grids if hms is True: grid_locator1 = angle_helper.LocatorHMS(4.0) tick_formatter1 = angle_helper.FormatterHMS() else: grid_locator1 = angle_helper.LocatorDMS(4.0) tick_formatter1 = angle_helper.FormatterDMS() grid_locator2 = MaxNLocator(10) grid_helper = GridHelperCurveLinear(tr, extremes=(ramin, ramax, zmin, zmax), grid_locator1=grid_locator1, grid_locator2=grid_locator2, tick_formatter1=tick_formatter1, tick_formatter2=None) # Figure properties if not fig: fig = plt.figure(figsize=(8, 7)) subnum = 111 ax = FloatingSubplot(fig, subnum, grid_helper=grid_helper) fig.add_subplot(ax) # adjust axis # Left, right, top represent z, lookbacktime, RA respectively. # right axes is for look-back time yet to be coded ax.axis["left"].set_axis_direction("bottom") ax.axis["right"].set_axis_direction("top") ax.axis["bottom"].set_visible(False) ax.axis["top"].set_axis_direction("bottom") ax.axis["top"].toggle(ticklabels=True, label=True) ax.axis["top"].major_ticklabels.set_axis_direction("top") ax.axis["top"].label.set_axis_direction("top") ax.axis["left"].label.set_text(ylabel) ax.axis["top"].label.set_text(xlabel) # create a parasite axes that transData in RA, z aux = ax.get_aux_axes(tr) aux.patch = ax.patch # for aux_ax to have a clip path as in ax ax.patch.zorder = 0.9 # but this has a side effect that the patch is # drawn twice, and possibly over some other # artists. So, we decrease the zorder a bit to # prevent this. if plot == 'scatter': aux.scatter(ra, z, **kwargs) # plt.tight_layout() # plt.show() return ax, aux, fig
def curvelinear_test2(fig, gs=None, xcenter=0.0, ycenter=17.3, xwidth=1.5, ywidth=1.5, rot_angle=0.0, xlabel=xlabel, ylabel=ylabel, xgrid_density=8, ygrid_density=5): """ polar projection, but in a rectangular box. """ tr = Affine2D().translate(0,90) tr += Affine2D().scale(np.pi/180., 1.) tr += PolarAxes.PolarTransform() tr += Affine2D().rotate(rot_angle) # This rotates the grid extreme_finder = angle_helper.ExtremeFinderCycle(10, 60, lon_cycle = 360, lat_cycle = None, lon_minmax = None, lat_minmax = (-90, np.inf), ) grid_locator1 = angle_helper.LocatorHMS(xgrid_density) #changes theta gridline count tick_formatter1 = angle_helper.FormatterHMS() grid_locator2 = angle_helper.LocatorDMS(ygrid_density) #changes theta gridline count tick_formatter2 = angle_helper.FormatterDMS() grid_helper = GridHelperCurveLinear(tr, extreme_finder=extreme_finder, grid_locator1=grid_locator1, grid_locator2=grid_locator2, tick_formatter1=tick_formatter1, tick_formatter2=tick_formatter2 ) # ax1 = SubplotHost(fig, rect, grid_helper=grid_helper) if gs is None: ax1 = SubplotHost(fig, 111, grid_helper=grid_helper) else: ax1 = SubplotHost(fig, gs, grid_helper=grid_helper) # make ticklabels of right and top axis visible. ax1.axis["right"].major_ticklabels.set_visible(False) ax1.axis["top"].major_ticklabels.set_visible(False) ax1.axis["bottom"].major_ticklabels.set_visible(True) #Turn off? # let right and bottom axis show ticklabels for 1st coordinate (angle) ax1.axis["right"].get_helper().nth_coord_ticks=0 ax1.axis["bottom"].get_helper().nth_coord_ticks=0 fig.add_subplot(ax1) grid_helper = ax1.get_grid_helper() # These move the grid ax1.set_xlim(xcenter-xwidth, xcenter+xwidth) # moves the origin left-right in ax1 ax1.set_ylim(ycenter-ywidth, ycenter+ywidth) # moves the origin up-down if xlabel is not None: ax1.set_xlabel(xlabel) if ylabel is not None: ax1.set_ylabel(ylabel) ax1.grid(True, linestyle='-') return ax1,tr
def fractional_polar_axes(f, thlim=(0, 180), rlim=(0, 1), step=(30, 0.01), thlabel=r'$\alpha$', rlabel='z', ticklabels=True): import matplotlib.pyplot as plt from matplotlib.transforms import Affine2D from matplotlib.projections import PolarAxes from mpl_toolkits.axisartist import angle_helper from mpl_toolkits.axisartist.grid_finder import MaxNLocator from mpl_toolkits.axisartist.floating_axes import GridHelperCurveLinear, FloatingSubplot from mpl_toolkits.axisartist.grid_finder import (FixedLocator, MaxNLocator, DictFormatter) """Return polar axes that adhere to desired theta (in deg) and r limits. steps for theta and r are really just hints for the locators. Using negative values for rlim causes problems for GridHelperCurveLinear for some reason""" th0, th1 = thlim # deg r0, r1 = rlim thstep, rstep = step # scale degrees to radians: tr_scale = Affine2D().scale(np.pi/180., 1.) tr = tr_scale + PolarAxes.PolarTransform() theta_grid_locator = angle_helper.LocatorDMS((th1-th0) // thstep) r_grid_locator = MaxNLocator((r1-r0) // rstep) theta_tick_formatter = angle_helper.FormatterDMS() theta_tick_formatter = None theta_ticks = [(0, r"$90^{\circ}$"), (30, r"$120^{\circ}$"), (60, r"$150^{\circ}$"), (90, r"$180^{\circ}$"), (120, r"$210^{\circ}$"), (150, r"$270^{\circ}$"), (180, r"$0^{\circ}$")] theta_tick_formatter = DictFormatter(dict(theta_ticks)) grid_helper = GridHelperCurveLinear(tr, extremes=(th0, th1, r0, r1), grid_locator1=theta_grid_locator, grid_locator2=r_grid_locator, tick_formatter1=theta_tick_formatter, tick_formatter2=None) a = FloatingSubplot(f, 111, grid_helper=grid_helper) f.add_subplot(a) # adjust x axis (theta): a.axis["bottom"].set_visible(False) a.axis["top"].set_axis_direction("bottom") # tick direction a.axis["top"].toggle(ticklabels=ticklabels, label=bool(thlabel)) a.axis["top"].major_ticklabels.set_axis_direction("top") a.axis["top"].label.set_axis_direction("top") # adjust y axis (r): a.axis["left"].set_axis_direction("bottom") # tick direction a.axis["right"].set_axis_direction("top") # tick direction a.axis["left"].toggle(ticklabels=ticklabels, label=bool(rlabel)) # add labels: a.axis["top"].label.set_text(thlabel) a.axis["left"].label.set_text(rlabel) # create a parasite axes whose transData is theta, r: auxa = a.get_aux_axes(tr) # make aux_ax to have a clip path as in a?: auxa.patch = a.patch # this has a side effect that the patch is drawn twice, and possibly over some other # artists. So, we decrease the zorder a bit to prevent this: a.patch.zorder = -2 # add sector lines for both dimensions: thticks = grid_helper.grid_info['lon_info'][0] rticks = grid_helper.grid_info['lat_info'][0] for th in thticks[1:-1]: # all but the first and last auxa.plot([th, th], [r0, r1], '--', c='grey', zorder=-1) for ri, r in enumerate(rticks): # plot first r line as axes border in solid black only if it isn't at r=0 if ri == 0 and r != 0: ls, lw, color = 'solid', 2, 'black' else: ls, lw, color = 'dashed', 1, 'grey' # From http://stackoverflow.com/a/19828753/2020363 auxa.add_artist(plt.Circle([0, 0], radius=r, ls=ls, lw=lw, color=color, fill=False, transform=auxa.transData._b, zorder=-1)) return auxa
def curvelinear_test2(fig): """ polar projection, but in a rectangular box. """ # 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). # 20, 20 : number of sampling points along x, y direction 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) # Find a grid values appropriate for the coordinate (degree, # minute, second). tick_formatter1 = angle_helper.FormatterDMS() # And also uses an appropriate formatter. Note that,the # acceptable Locator and Formatter class is a bit different than # that of mpl's, and you cannot directly use mpl's Locator and # Formatter here (but may be possible in the future). grid_helper = GridHelperCurveLinear(tr, extreme_finder=extreme_finder, grid_locator1=grid_locator1, tick_formatter1=tick_formatter1) ax1 = SubplotHost(fig, 1, 2, 2, grid_helper=grid_helper) # make ticklabels of right and top axis visible. 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) # A parasite axes with given transform ax2 = ParasiteAxesAuxTrans(ax1, tr, "equal") # note that ax2.transData == tr + ax1.transData # Anthing you draw in ax2 will match the ticks and grids of ax1. ax1.parasites.append(ax2) intp = cbook.simple_linear_interpolation ax2.plot(intp(np.array([0, 30]), 50), intp(np.array([10., 10.]), 50), linewidth=2.0) ax1.set_aspect(1.) ax1.set_xlim(-5, 12) ax1.set_ylim(-5, 10) ax1.grid(True, zorder=0)
def fractional_polar_axes(f, thlim=(0, 180), rlim=(0, 1), step=(30, 0.25), thlabel='theta', rlabel='r', ticklabels=True, rlabels = None, subplot=111): '''Return polar axes that adhere to desired theta (in deg) and r limits. steps for theta and r are really just hints for the locators.''' th0, th1 = thlim # deg r0, r1 = rlim thstep, rstep = step # scale degrees to radians: tr_scale = Affine2D().scale(np.pi/180., 1.) pa = PolarAxes tr = tr_scale + pa.PolarTransform() theta_grid_locator = angle_helper.LocatorDMS((th1-th0)//thstep) r_grid_locator = MaxNLocator((r1-r0)//rstep) theta_tick_formatter = angle_helper.FormatterDMS() if rlabels: rlabels = DictFormatter(rlabels) grid_helper = GridHelperCurveLinear(tr, extremes=(th0, th1, r0, r1), grid_locator1=theta_grid_locator, grid_locator2=r_grid_locator, tick_formatter1=theta_tick_formatter, tick_formatter2=rlabels) a = FloatingSubplot(f, subplot, grid_helper=grid_helper) f.add_subplot(a) # adjust x axis (theta): a.axis["bottom"].set_visible(False) a.axis["top"].set_axis_direction("bottom") # tick direction a.axis["top"].toggle(ticklabels=ticklabels, label=bool(thlabel)) a.axis["top"].major_ticklabels.set_axis_direction("top") a.axis["top"].label.set_axis_direction("top") a.axis["top"].major_ticklabels.set_pad(10) # adjust y axis (r): a.axis["left"].set_axis_direction("bottom") # tick direction a.axis["right"].set_axis_direction("top") # tick direction a.axis["left"].toggle(ticklabels=True, label=bool(rlabel)) # add labels: a.axis["top"].label.set_text(thlabel) a.axis["left"].label.set_text(rlabel) # create a parasite axes whose transData is theta, r: auxa = a.get_aux_axes(tr) # make aux_ax to have a clip path as in a?: auxa.patch = a.patch # this has a side effect that the patch is drawn twice, and possibly over some other # artists. So, we decrease the zorder a bit to prevent this: a.patch.zorder = -2 # add sector lines for both dimensions: thticks = grid_helper.grid_info['lon_info'][0] rticks = grid_helper.grid_info['lat_info'][0] for th in thticks[1:-1]: # all but the first and last auxa.plot([th, th], [r0, r1], ':', c='grey', zorder=-1, lw=0.5) for ri, r in enumerate(rticks): # plot first r line as axes border in solid black only if it isn't at r=0 if ri == 0 and r != 0: ls, lw, color = 'solid', 1, 'black' else: ls, lw, color = 'dashed', 0.5, 'grey' # From http://stackoverflow.com/a/19828753/2020363 auxa.add_artist(plt.Circle([0, 0], radius=r, ls=ls, lw=lw, color=color, fill=False, transform=auxa.transData._b, zorder=-1)) return auxa
def create_cg(fig=None, subplot=111, rot=-450, scale=-1, angular_spacing=10, radial_spacing=10, latmin=0, lon_cycle=360): """ Helper function to create curvelinear grid The function makes use of the Matplotlib AXISARTIST namespace `mpl_toolkits.axisartist \ <https://matplotlib.org/mpl_toolkits/axes_grid/users/axisartist.html>`_. Here are some limitations to normal Matplotlib Axes. While using the Matplotlib `AxesGrid Toolkit \ <https://matplotlib.org/mpl_toolkits/axes_grid/index.html>`_ most of the limitations can be overcome. See `Matplotlib AxesGrid Toolkit User’s Guide \ <https://matplotlib.org/mpl_toolkits/axes_grid/users/index.html>`_. Parameters ---------- fig : matplotlib Figure object If given, the PPI/RHI will be plotted into this figure object. Axes are created as needed. If None a new figure object will be created or current figure will be used, depending on "subplot". subplot : :class:`matplotlib:matplotlib.gridspec.GridSpec`, \ matplotlib grid definition nrows/ncols/plotnumber, see examples section defaults to '111', only one subplot rot : float Rotation of the source data in degrees, defaults to -450 for PPI, use 0 for RHI scale : float Scale of source data, defaults to -1. for PPI, use 1 for RHI angular_spacing : float Spacing of the angular grid, defaults to 10. radial_spacing : float Spacing of the radial grid, defaults to 10. latmin : float Startvalue for radial grid, defaults to 0. lon_cycle : float Angular cycle, defaults to 360. Returns ------- cgax : matplotlib toolkit axisartist Axes object curvelinear Axes (r-theta-grid) caax : matplotlib Axes object (twin to cgax) Cartesian Axes (x-y-grid) for plotting cartesian data paax : matplotlib Axes object (parasite to cgax) The parasite axes object for plotting polar data """ # create transformation # rotate tr_rotate = Affine2D().translate(rot, 0) # scale tr_scale = Affine2D().scale(scale * np.pi / 180, 1) # polar tr_polar = PolarAxes.PolarTransform() tr = tr_rotate + tr_scale + tr_polar # build up curvelinear grid extreme_finder = ah.ExtremeFinderCycle( 360, 360, lon_cycle=lon_cycle, lat_cycle=None, lon_minmax=None, lat_minmax=(latmin, np.inf), ) # locator and formatter for angular annotation grid_locator1 = ah.LocatorDMS(lon_cycle // angular_spacing) tick_formatter1 = ah.FormatterDMS() # grid_helper for curvelinear grid grid_helper = GridHelperCurveLinear( tr, extreme_finder=extreme_finder, grid_locator1=grid_locator1, grid_locator2=None, tick_formatter1=tick_formatter1, tick_formatter2=None, ) # try to set nice locations for radial gridlines grid_locator2 = grid_helper.grid_finder.grid_locator2 grid_locator2._nbins = (radial_spacing * 2 + 1) // np.sqrt(2) # if there is no figure object given if fig is None: # create new figure if there is only one subplot if subplot == 111: fig = pl.figure() # otherwise get current figure or create new figure else: fig = pl.gcf() # generate Axis cgax = SubplotHost(fig, subplot, grid_helper=grid_helper) fig.add_axes(cgax) # get twin axis for cartesian grid caax = cgax.twin() # move axis annotation from right to left and top to bottom for # cartesian axis caax.toggle_axisline() # make right and top axis visible and show ticklabels (curvelinear axis) cgax.axis["top", "right"].set_visible(True) cgax.axis["top", "right"].major_ticklabels.set_visible(True) # make ticklabels of left and bottom axis invisible (curvelinear axis) cgax.axis["left", "bottom"].major_ticklabels.set_visible(False) # and also set tickmarklength to zero for better presentation # (curvelinear axis) cgax.axis["top", "right", "left", "bottom"].major_ticks.set_ticksize(0) # show theta (angles) on top and right axis cgax.axis["top"].get_helper().nth_coord_ticks = 0 cgax.axis["right"].get_helper().nth_coord_ticks = 0 # generate and add parasite axes with given transform paax = ParasiteAxesAuxTrans(cgax, tr, "equal") # note that paax.transData == tr + cgax.transData # Anything you draw in paax will match the ticks and grids of cgax. cgax.parasites.append(paax) return cgax, caax, paax
def __init__(self, fig=None, max_normed_std=2.5, std_ratios=[1], \ bias_vmin=None, bias_vmax=None, \ normalized=True, cmap=plt.cm.jet, s=80, title_expected=r'expected'): """ Set up Taylor diagram axes. """ self.title_polar = r'Correlation' self.title_xy = r'Normalized Standard Deviation' self.max_normed_std = max_normed_std self.s_min = 0 self.std_ratios = std_ratios self.bias_vmin = bias_vmin self.bias_vmax = bias_vmax self.normalized = normalized self.cmap = cmap self.s = s # marker size self.title_expected = title_expected # Define polar coordinate tr = PolarAxes.PolarTransform() 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) # figure self.fig = fig if self.fig is None: self.fig = plt.figure() # setup axes ax = SubplotHost(self.fig, 111, grid_helper=grid_helper) self.ax = self.fig.add_subplot(ax) # set x and y axis self._setup_axes() # attach the polar axes and plot the correlation lines self.polar_ax = self.ax.get_aux_axes(tr) self.polar_ax.plot([np.pi / 2.135, np.pi / 2.135], [self.s_min, self.max_normed_std * 2], color='grey') self.polar_ax.plot([np.pi / 2.484, np.pi / 2.484], [self.s_min, self.max_normed_std * 2], color='grey') self.polar_ax.plot([np.pi / 3, np.pi / 3], [self.s_min, self.max_normed_std * 2], color='grey') self.polar_ax.plot([np.pi / 3.95, np.pi / 3.95], [self.s_min, self.max_normed_std * 2], color='grey') self.polar_ax.plot([np.pi / 6.95, np.pi / 6.95], [self.s_min, self.max_normed_std * 2], color='grey') # Add norm stddev ratio contours self._plot_req_cont(self.std_ratios) self.points = []