def __spacetime_diagram_o_prime_frame(self): # from (x,t) to (x',t') def tr(x_prime, t_prime): x_prime, t_prime = np.asarray(x_prime), np.asarray(t_prime) return self.lorentz_transformations.transform( x_prime, t_prime, self.velocity) # form (x',t') to (x,t) def inv_tr(x, t): x, t = np.asarray(x), np.asarray(t) return self.lorentz_transformations.transform(x, t, -self.velocity) grid_helper = GridHelperCurveLinear((tr, inv_tr)) ax = SubplotHost(self.fig, 1, 2, 2, grid_helper=grid_helper) self.fig.add_subplot(ax) ax.set_xlabel("x'", loc="center") ax.set_ylabel("t'", loc="center") # O x axis ax.axis["x1"] = x1 = ax.new_floating_axis(0, 0) x1.label.set_text("x") # O t axis ax.axis["t1"] = t1 = ax.new_floating_axis(1, 0) t1.label.set_text("t") self.__add_x_and_y_axis(ax) ax.format_coord = self.__format_coord_o_prime_frame self.__remove_ticks(ax, x1, t1) self.world_lines_plotter.transform_and_plot(plt, ax, self.velocity)
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 createQEAxes(DataSet=None,axis=0,figure = None, projectionVector1 = None, projectionVector2 = None): """Function to create Q E plot Kwargs: - DataSet (DataSet): If provided and no projections vectors creates QE axis for main direction (default None) - axis (int): Whether to create axis 0 or 1 (projection vector 0 or orthogonal to this, default 0) - figure (figure): If provided, this is used to create the axis within (default None) - projectionVector1 (vec): Projection vector along which data is plotted. If not provided sample vector is used (default None) - projectionVector2 (vec): Projection vector orthogonal to data. If not provided sample vector is used (default None) """ if projectionVector1 is None or projectionVector2 is None: v1 = DataSet.sample[0].projectionVector1 v2 = DataSet.sample[0].projectionVector2 angle = DataSet.sample[0].projectionAngle orientationMatrix = DataSet.sample[0].orientationMatrix else: v1 = np.array(projectionVector1) v2 = np.array(projectionVector2) if not np.all([x.shape==(3,) for x in [v1,v2]]) or not np.all([len(x.shape)==1 for x in [v1,v2]]): raise AttributeError('Provided vector(s) is not 3D: projectionVector1.shape={} or projectionVector2.shape={}'.format(v1.shape,v2.shape)) angle = np.arccos(np.dot(v1,v2)/(np.linalg.norm(v1)*np.linalg.norm(v2))) orientationMatrix = np.ones(3) sample = copy.deepcopy(DataSet.sample) v1,v2 = sample[0].projectionVector1,sample[0].projectionVector2 angle = np.sign(np.dot(np.cross(v1,v2),sample[0].planeNormal))*sample[0].projectionAngle v2Length = np.linalg.norm(v2)/np.linalg.norm(v1) projectionMatrix = np.linalg.inv(np.array([[1,0],[np.cos(angle)*v2Length,np.sin(angle)*v2Length]]).T) projectionVectorQX = np.dot(np.dot(projectionMatrix,[1,0]),np.array([v1,v2])) projectionVectorQY = np.dot(np.dot(projectionMatrix,[0,1]),np.array([v1,v2])) projectionVectorQX = _tools.LengthOrder(projectionVectorQX) projectionVectorQY = _tools.LengthOrder(projectionVectorQY) projectionVectorQXLength = np.linalg.norm(np.dot(orientationMatrix,projectionVectorQY)) projectionVectorQYLength = np.linalg.norm(np.dot(orientationMatrix,projectionVectorQX)) projectionVectorQXFormated = ', '.join(['{:.3f}'.format(x) for x in projectionVectorQX]) projectionVectorQYFormated = ', '.join(['{:.3f}'.format(x) for x in projectionVectorQY]) if axis == 0: projectionVectorLength = projectionVectorQYLength projectionVectorLengthORthogonal = projectionVectorQXLength projectionVectorFormated = projectionVectorQXFormated projectionVector = projectionVectorQX projectionVectorOrthogonal = projectionVectorQY elif axis == 1: projectionVectorLength = projectionVectorQXLength projectionVectorFormated = projectionVectorQYFormated projectionVectorLengthORthogonal = projectionVectorQYLength projectionVector = projectionVectorQY projectionVectorOrthogonal = projectionVectorQX else: raise AttributeError('Provided axis of {} is not allowed. Should be either 0 or 1.'.format(axis)) if figure is None: figure = plt.figure(figsize=(7, 4)) else: figure.clf() def inv_tr(l,x,y): return x*l,y def tr(l,x,y): return x/l,y if pythonVersion == 3: grid_locator1 = MultipleLocator(base=1.0) # Standard X ticks is multiple locator grid_helper = GridHelperCurveLinear((lambda x,y:inv_tr(projectionVectorLength,x,y), lambda x,y:tr(projectionVectorLength,x,y)),grid_locator1=grid_locator1) else: grid_helper = GridHelperCurveLinear((lambda x,y:inv_tr(projectionVectorLength,x,y), lambda x,y:tr(projectionVectorLength,x,y))) ax = SubplotHost(figure, 1, 1, 1, grid_helper=grid_helper) ax.sample = sample[0] figure.add_subplot(ax) #ax.set_aspect(1.) ax.grid(True, zorder=0) def calculateRLU(l,v1,x,y,v,step): return np.asarray(x)/l*v1+v*step, np.asarray(y) def format_coord(x,y): # pragma: no cover # x is H,K,L and y is energy xformated = ', '.join(['{} = {}'.format(Y[0],Y[1]) for Y in zip(['h','k','l'],['{:.4f}'.format(X) for X in x])]) return '{}, E={:.4f}'.format(xformated,y) ax.set_xlabel('{} [RLU]'.format(projectionVectorFormated)) ax.set_ylabel('E [meV]') ax._length = projectionVectorLengthORthogonal ax._projectionVector = projectionVector ax._projectionVectorOrthogonal = projectionVectorOrthogonal ax._step = 0.0 ax.calculateRLU = lambda x,y: calculateRLU(projectionVectorLength,ax._projectionVector,x,y,ax._projectionVectorOrthogonal,ax._step) ax.format_coord = lambda x,y: format_coord(*ax.calculateRLU(x,y)) if pythonVersion == 3: ax.forceGridUpdate = lambda:forceGridUpdate(ax) ax.xticks = 7 def xAxisChanged(axis, forceUpdate=False): locator = axis._grid_helper.grid_finder.grid_locator1 xlim = axis.get_xlim() xlimDiff = np.diff(xlim) if isinstance(locator,MultipleLocator): if hasattr(axis,'xBase'): base = axis.xBase else: base = calculateBase(locator,xlimDiff,axis.xticks) locator.set_params(base=base) elif isinstance(locator,MaxNLocator): if hasattr(axis,'xTicks'): ticks = getattr(axis,'xTicks') else: ticks = 7 locator.set_params(nbins = ticks) else: return axis.forceGridUpdate() ax.callbacks.connect('xlim_changed', xAxisChanged) ax.callbacks.connect('draw_event',lambda ax: xAxisChanged(ax,forceUpdate=True)) ax.xAxisChanged = lambda: xAxisChanged(ax,forceUpdate=True) @updateXAxisDecorator(ax=ax) def set_xticks_base(xBase=None,ax=ax): """Setter of the base x ticks to be used for plotting Kwargs: - xBase (float): Base of the tick marks (default automatic) """ if not isinstance(ax._grid_helper.grid_finder.grid_locator1,MultipleLocator): l1 = MultipleLocator(base=xBase) ax._grid_helper.update_grid_finder(grid_locator1=l1) if xBase is None: if hasattr(ax,'xBase'): delattr(ax,'xBase') else: ax.xBase = xBase @updateXAxisDecorator(ax=ax) def set_xticks_number(xNumber = None,ax=ax): """Setter of the number of x ticks to be used for plotting Kwargs: - xNumber (int): Number of x tick marks (default 7) """ if xNumber is None: xNumber = 7 if not isinstance(ax._grid_helper.grid_finder.grid_locator1,MaxNLocator): l1 = MaxNLocator(nbins=xNumber) ax._grid_helper.update_grid_finder(grid_locator1=l1) ax.xTicks = xNumber ax.set_xticks_base = set_xticks_base ax.set_xticks_number = set_xticks_number return ax
def createRLUAxes(self,figure=None,ids=[1, 1, 1],basex=None,basey=None): """Create a reciprocal lattice plot for a given DataSet object. Args: - Dataset (DataSet): DataSet object for which the RLU plot is to be made. Kwargs: - figure: Matplotlib figure in which the axis is to be put (default None) - ids (array): List of integer numbers provided to the SubplotHost ids attribute (default [1,1,1]) - basex (float): Ticks are positioned at multiples of this value along x (default None) - basey (float): Ticks are positioned at multiples of this value along y (default None) Returns: - ax (Matplotlib axes): Axes containing the RLU plot. .. note:: When rlu axis is created, the orientation of Qx and Qy is assumed to be rotated as well. This is to be done in the self.View3D method call! .. note:: When using python 2 the changing of tick marks is not supported due to limitations in matplotlib. However, if python 3 is used, the number of ticks and their location can be change after the initialization using the set_xticks_number, set_yticks_number chaning the wanted number of tick marks, or the set_xticks_base or set_yticks_base to change the base number, see RLU tutorial under Tools. As default a sufficient base number is found and will update when zooming. """ sample = copy.deepcopy(self.sample) for samp in sample: samp.convert = np.einsum('ij,j...->i...',samp.RotMat,samp.convert) #sample.convert = np.einsum('ij,j...->i...',sample.RotMat,sample.convert) samp.convertinv = np.linalg.inv(samp.convert) # Convert from Qx, Qy to projX, projY samp.orientationMatrix = np.dot(samp.RotMat3D,samp.orientationMatrix) samp.orientationMatrixINV = np.linalg.inv(samp.orientationMatrix) samp.theta = 0.0 if figure is None: fig = plt.figure(figsize=(7, 4)) else: fig = figure def calculateTicks(ticks,angle,round=True): val = ticks/np.tan(angle/2.0) if round: return np.array(np.round(val),dtype=int) else: return val if pythonVersion==3: # Only for python 3 if not basex is None or not basey is None: # Either basex or basey is provided (or both) if basex is None: basex = calculateTicks(basey,sample[0].projectionAngle,round=False) elif basey is None: basey = basex/calculateTicks(1.0,sample[0].projectionAngle,round=False) grid_locator1 = MultipleLocator(base=basex) grid_locator2 = MultipleLocator(base=basey) else: basex = 0.5 basey = 0.5 grid_locator1 = MultipleLocator(base=basex) grid_locator2 = MultipleLocator(base=basey) grid_helper = GridHelperCurveLinear((sample[0].inv_tr, sample[0].tr),grid_locator1=grid_locator1,grid_locator2=grid_locator2) else: # Python 2 grid_helper = GridHelperCurveLinear((sample[0].inv_tr, sample[0].tr)) ax = SubplotHost(fig, *ids, grid_helper=grid_helper) ax.sample = sample[0] if pythonVersion==3: # Only for python 3 ax.basex = basex ax.basey = basey def set_axis(ax,v1,v2,*args): if not args is (): points = np.concatenate([[v1,v2],[x for x in args]],axis=0) else: points = np.array([v1,v2]) if points.shape[1] == 3: points = ax.sample.calculateHKLtoProjection(points[:,0],points[:,1],points[:,2]).T boundaries = np.array([ax.sample.inv_tr(x[0],x[1]) for x in points]) ax.set_xlim(boundaries[:,0].min(),boundaries[:,0].max()) ax.set_ylim(boundaries[:,1].min(),boundaries[:,1].max()) if pythonVersion == 3: # Only possible in python 3 ax.forceGridUpdate() fig.add_subplot(ax) ax.set_aspect(1.) ax.grid(True, zorder=0) if not np.isclose(ax.sample.projectionAngle,np.pi/2.0,atol=0.001): ax.axis["top"].major_ticklabels.set_visible(True) ax.axis["right"].major_ticklabels.set_visible(True) ax.format_coord = ax.sample.format_coord ax.set_axis = lambda v1,v2,*args: set_axis(ax,v1,v2,*args) def beautifyLabel(vec): Vec = [x.astype(int) if np.isclose(x.astype(float)-x.astype(int),0.0) else x.astype(float) for x in vec] return '{} [RLU]'.format(', '.join([str(x) for x in Vec])) ax.set_xlabel(beautifyLabel(ax.sample.projectionVector1)) ax.set_ylabel(beautifyLabel(ax.sample.projectionVector2)) if pythonVersion==3: # Only for python 3 ax.calculateTicks = lambda value:calculateTicks(value,ax.sample.projectionAngle) ax.forceGridUpdate = lambda:forceGridUpdate(ax) ax._oldXlimDiff = np.diff(ax.get_xlim()) ax._oldYlimDiff = np.diff(ax.get_ylim()) ax.get_aspect_ratio = lambda: get_aspect(ax) ax.callbacks.connect('xlim_changed', axisChanged) ax.callbacks.connect('ylim_changed', axisChanged) ax.callbacks.connect('draw_event',lambda ax: axisChanged(ax,forceUpdate=True)) ax.axisChanged = lambda direction='both': axisChanged(ax,forceUpdate=True,direction=direction) @updateAxisDecorator(ax=ax,direction='x') def set_xticks_base(xBase,ax=ax): """Setter of the base x ticks to be used for plotting Args: - xBase (float): Base of the tick marks """ if not isinstance(ax._grid_helper.grid_finder.grid_locator1,MultipleLocator): l1 = MultipleLocator(base=xBase) ax._grid_helper.update_grid_finder(grid_locator1=l1) ax.xbase = xBase @updateAxisDecorator(ax=ax,direction='y') def set_yticks_base(yBase,ax=ax): """Setter of the base y ticks to be used for plotting Args: - yBase (float): Base of the tick marks """ if not isinstance(ax._grid_helper.grid_finder.grid_locator2,MultipleLocator): l2 = MultipleLocator(base=yBase) ax._grid_helper.update_grid_finder(grid_locator2=l2) ax.ybase = yBase @updateAxisDecorator(ax=ax,direction='x') def set_xticks_number(xNumber,ax=ax): """Setter of the number of x ticks to be used for plotting Args: - xNumber (int): Number of x tick marks """ if not isinstance(ax._grid_helper.grid_finder.grid_locator1,MaxNLocator): l1 = MaxNLocator(nbins=xNumber) ax._grid_helper.update_grid_finder(grid_locator1=l1) ax.xticks = xNumber @updateAxisDecorator(ax=ax,direction='y') def set_yticks_number(yNumber,ax=ax): """Setter of the number of y ticks to be used for plotting Args: - yNumber (int): Number of y tick marks """ if not isinstance(ax._grid_helper.grid_finder.grid_locator2,MaxNLocator): l2 = MaxNLocator(nbins=yNumber) ax._grid_helper.update_grid_finder(grid_locator2=l2) ax.yticks = yNumber ax.set_xticks_base = set_xticks_base ax.set_yticks_base = set_yticks_base ax.set_xticks_number = set_xticks_number ax.set_yticks_number = set_yticks_number return ax
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 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 curvelinear_test2(fig, gs=None, xcenter=0.0, ycenter=17.3, xwidth=1.5, ywidth=1.5, 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(1.34) # 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 # ax1.set_xlim(-1.5, 1.4) # ax1.set_ylim(15.8, 18.8) if xlabel is not None: ax1.set_xlabel(xlabel) if ylabel is not None: ax1.set_ylabel(ylabel) # ax1.set_ylabel('Declination') # ax1.set_xlabel('Right Ascension') ax1.grid(True, linestyle='-') #ax1.grid(linestyle='--', which='x') # either keyword applies to both #ax1.grid(linestyle=':', which='y') # sets of gridlines return ax1,tr