def plot(LSM, fileName=None, labelBy=None): """ Shows a simple plot of the sky model. The circles in the plot are scaled with flux. If the sky model is grouped into patches, sources are colored by patch and the patch positions are indicated with stars. Parameters ---------- LSM : SkyModel object Input sky model fileName : str, optional If given, the plot is saved to a file instead of displayed labelBy : str, optional One of 'source' or 'patch': label points using source names ('source') or patch names ('patch') Examples: --------- Plot and display to the screen:: >>> LSM = lsmtool.load('sky.model') >>> plot(LSM) Plot and save to a PDF file:: >>> plot(LSM, 'sky_plot.pdf') """ try: import os if 'DISPLAY' not in os.environ: import matplotlib if matplotlib.get_backend() is not 'Agg': matplotlib.use("Agg") import matplotlib.pyplot as plt from matplotlib.ticker import FuncFormatter except Exception as e: raise ImportError('PyPlot could not be imported. Plotting is not ' 'available: {0}'.format(e.message)) try: try: from astropy.visualization.wcsaxes import WCSAxes hasWCSaxes = True except: from wcsaxes import WCSAxes hasWCSaxes = True except: hasWCSaxes = False import numpy as np from ..operations_lib import radec2xy, makeWCS global midRA, midDec, ymin, xmin if len(LSM) == 0: log.error('Sky model is empty.') return fig = plt.figure(1, figsize=(7.66, 7)) plt.clf() x, y, midRA, midDec = LSM._getXY() if hasWCSaxes: wcs = makeWCS(midRA, midDec) ax = WCSAxes(fig, [0.16, 0.1, 0.8, 0.8], wcs=wcs) fig.add_axes(ax) else: ax = plt.gca() if LSM.hasPatches: nsrc = len(LSM.getPatchNames()) else: nsrc = len(LSM) sm = plt.cm.ScalarMappable(cmap=plt.cm.Set3, norm=plt.Normalize(vmin=0, vmax=nsrc)) sm._A = [] # Set symbol sizes by flux, making sure no symbol is smaller than 50 or # larger than 1000 s = [] fluxes = LSM.getColValues('I') if len(fluxes[fluxes > 0.0]) == 0: minflux = 0.0 else: minflux = np.min(fluxes[fluxes > 0.0]) for flux in LSM.getColValues('I'): if flux > 0.0: s.append(min(1000.0, (1.0 + 2.0 * np.log10(flux / minflux)) * 50.0)) else: s.append(50.0) # Color sources by patch if grouped c = [0] * len(LSM) cp = [] if LSM.hasPatches: for p, patchName in enumerate(LSM.getPatchNames()): indices = LSM.getRowIndex(patchName) cp.append(sm.to_rgba(p)) for ind in indices: c[ind] = sm.to_rgba(p) else: c = [sm.to_rgba(0)] * nsrc # Plot sources if hasWCSaxes: RA = LSM.getColValues('Ra') Dec = LSM.getColValues('Dec') ax.set_xlim(np.min(x) - 20, np.max(x) + 20) ax.set_ylim(np.min(y) - 20, np.max(y) + 20) plt.scatter(x, y, s=s, c=c) if LSM.hasPatches: RAp, Decp = LSM.getPatchPositions(asArray=True) goodInd = np.where((RAp != 0.0) & (Decp != 0.0)) if len(goodInd[0]) < len(RAp): log.info('Some patch positions are unset. Run setPatchPositions() ' 'before plotting to see patch positions and patch names.') xp, yp = radec2xy(RAp[goodInd], Decp[goodInd], midRA, midDec) plt.scatter(xp, yp, s=100, c=cp, marker='*') # Set axis labels, etc. if hasWCSaxes: RAAxis = ax.coords['ra'] RAAxis.set_axislabel('RA', minpad=0.75) RAAxis.set_major_formatter('hh:mm:ss') DecAxis = ax.coords['dec'] DecAxis.set_axislabel('Dec', minpad=0.75) DecAxis.set_major_formatter('dd:mm:ss') ax.coords.grid(color='black', alpha=0.5, linestyle='solid') else: plt.xlabel("RA (arb. units)") plt.ylabel("Dec (arb. units)") if labelBy is not None: if labelBy.lower() == 'source': labels = LSM.getColValues('name') xls = x yls = y elif labelBy.lower() == 'patch': if LSM.hasPatches: labels = LSM.getPatchNames() xls = xp yls = yp else: labels = LSM.getColValues('name') xls = x yls = y else: raise ValueError( "The lableBy parameter must be one of 'source' or " "'patch'.") for label, xl, yl in zip(labels, xls, yls): plt.annotate(label, xy=(xl, yl), xytext=(-2, 2), textcoords='offset points', ha='right', va='bottom') # Define coodinate formater to show RA and Dec under mouse pointer RAformatter = FuncFormatter(RAtickformatter) ax.format_coord = formatCoord if fileName is not None: plt.savefig(fileName) else: plt.show() plt.close(fig)
def plot_state(directions_list, trim_names=True): """ Plots the facets of a run """ global midRA, midDec, fig, at, selected_direction, choose_from_list selected_direction = None choose_from_list = False # Set up coordinate system and figure points, midRA, midDec = factor.directions.getxy(directions_list) fig = plt.figure(1, figsize=(10,9)) if hasWCSaxes: wcs = factor.directions.makeWCS(midRA, midDec) ax = WCSAxes(fig, [0.16, 0.1, 0.8, 0.8], wcs=wcs) fig.add_axes(ax) else: ax = plt.gca() field_x = min(points[0]) field_y = max(points[1]) adjust_xy = True while adjust_xy: adjust_xy = False for xy in points: dist = np.sqrt( (xy[0] - field_x)**2 + (xy[1] - field_y)**2 ) if dist < 10.0: field_x -= 1 field_y += 1 adjust_xy = True break field_ra, field_dec = factor.directions.xy2radec([field_x], [field_y], refRA=midRA, refDec=midDec) field = Direction('field', field_ra[0], field_dec[0], factor_working_dir=directions_list[0].working_dir) directions_list.append(field) ax.set_title('Overview of Factor run in\n{}'.format(directions_list[0].working_dir)) # Plot facets markers = [] for direction in directions_list: if direction.name != 'field': vertices = read_vertices(direction.vertices_file) RAverts = vertices[0] Decverts = vertices[1] xverts, yverts = factor.directions.radec2xy(RAverts, Decverts, refRA=midRA, refDec=midDec) xyverts = [np.array([xp, yp]) for xp, yp in zip(xverts, yverts)] mpl_poly = Polygon(np.array(xyverts), edgecolor='#a9a9a9', facecolor='#F2F2F2', clip_box=ax.bbox, picker=3.0, linewidth=2) else: xverts = [field_x] yverts = [field_y] mpl_poly = Circle((field_x, field_y), radius=5.0, edgecolor='#a9a9a9', facecolor='#F2F2F2', clip_box=ax.bbox, picker=3.0, linewidth=2) mpl_poly.facet_name = direction.name mpl_poly.completed_ops = get_completed_ops(direction) mpl_poly.started_ops = get_started_ops(direction) mpl_poly.current_op = get_current_op(direction) set_patch_color(mpl_poly, direction) ax.add_patch(mpl_poly) # Add facet names if direction.name != 'field': poly_tuple = tuple([(xp, yp) for xp, yp in zip(xverts, yverts)]) xmid = SPolygon(poly_tuple).centroid.x ymid = SPolygon(poly_tuple).centroid.y else: xmid = field_x ymid = field_y if trim_names: name = direction.name.split('_')[-1] else: name = direction.name marker = ax.text(xmid, ymid, name, color='k', clip_on=True, clip_box=ax.bbox, ha='center', va='bottom') marker.set_zorder(1001) markers.append(marker) # Add info box at = AnchoredText("Selected direction: None", prop=dict(size=12), frameon=True, loc=3) at.patch.set_boxstyle("round,pad=0.,rounding_size=0.2") at.set_zorder(1002) ax.add_artist(at) ax.relim() ax.autoscale() ax.set_aspect('equal') if hasWCSaxes: RAAxis = ax.coords['ra'] RAAxis.set_axislabel('RA', minpad=0.75) RAAxis.set_major_formatter('hh:mm:ss') DecAxis = ax.coords['dec'] DecAxis.set_axislabel('Dec', minpad=0.75) DecAxis.set_major_formatter('dd:mm:ss') ax.coords.grid(color='black', alpha=0.5, linestyle='solid') else: plt.xlabel("RA (arb. units)") plt.ylabel("Dec (arb. units)") # Define coodinate formater to show RA and Dec under mouse pointer ax.format_coord = formatCoord # Show legend not_processed_patch = plt.Rectangle((0, 0), 1, 1, edgecolor='#a9a9a9', facecolor='#F2F2F2', linewidth=2) processing_patch = plt.Rectangle((0, 0), 1, 1, edgecolor='#a9a9a9', facecolor='#F2F5A9', linewidth=2) selfcal_ok_patch = plt.Rectangle((0, 0), 1, 1, edgecolor='#a9a9a9', facecolor='#A9F5A9', linewidth=2) selfcal_not_ok_patch = plt.Rectangle((0, 0), 1, 1, edgecolor='#a9a9a9', facecolor='#A4A4A4', linewidth=2) processing_error = plt.Rectangle((0, 0), 1, 1, edgecolor='#a9a9a9', facecolor='#F5A9A9', linewidth=2) patch_list=[not_processed_patch, processing_patch, processing_error, selfcal_not_ok_patch, selfcal_ok_patch] label_list=['Unprocessed', 'Processing', 'Pipeline Error', 'Selfcal Failed', 'Selfcal OK'] for i in range(options['reimages']): label_list.append('Image '+str(i+1)) color=(0.66/(i+2)**0.5, 0.96/(i+2)**0.5, 0.66/(i+2)**0.5, 1.0) reimage_patch=plt.Rectangle((0, 0), 1, 1, edgecolor='#a9a9a9', facecolor=color, linewidth=2) patch_list.append(reimage_patch) l = ax.legend(patch_list, label_list, loc="upper right") l.set_zorder(1002) # Add check for mouse clicks and key presses fig.canvas.mpl_connect('pick_event', on_pick) fig.canvas.mpl_connect('key_press_event', on_press) # Add timer to update the plot every 60 seconds timer = fig.canvas.new_timer(interval=60000) timer.add_callback(update_plot) timer.start() # Show plot plt.show() plt.close(fig) # Clean up any temp casacore images if not hasaplpy: if os.path.exists('/tmp/tempimage'): try: shutil.rmtree('/tmp/tempimage') except OSError: pass
def plot_state(directions_list, trim_names=True): """ Plots the facets of a run """ global midRA, midDec, fig, at, selected_direction, choose_from_list selected_direction = None choose_from_list = False # Set up coordinate system and figure points, midRA, midDec = factor.directions.getxy(directions_list) fig = plt.figure(1, figsize=(10, 9)) if hasWCSaxes: wcs = factor.directions.makeWCS(midRA, midDec) ax = WCSAxes(fig, [0.16, 0.1, 0.8, 0.8], wcs=wcs) fig.add_axes(ax) else: ax = plt.gca() field_x = min(points[0]) field_y = max(points[1]) adjust_xy = True while adjust_xy: adjust_xy = False for xy in points: dist = np.sqrt((xy[0] - field_x)**2 + (xy[1] - field_y)**2) if dist < 10.0: field_x -= 1 field_y += 1 adjust_xy = True break field_ra, field_dec = factor.directions.xy2radec([field_x], [field_y], refRA=midRA, refDec=midDec) field = Direction('field', field_ra[0], field_dec[0], factor_working_dir=directions_list[0].working_dir) directions_list.append(field) ax.set_title('Overview of Factor run in\n{}'.format( directions_list[0].working_dir)) # Plot facets markers = [] for direction in directions_list: if direction.name != 'field': vertices = read_vertices(direction.vertices_file) RAverts = vertices[0] Decverts = vertices[1] xverts, yverts = factor.directions.radec2xy(RAverts, Decverts, refRA=midRA, refDec=midDec) xyverts = [np.array([xp, yp]) for xp, yp in zip(xverts, yverts)] mpl_poly = Polygon(np.array(xyverts), edgecolor='#a9a9a9', facecolor='#F2F2F2', clip_box=ax.bbox, picker=3.0, linewidth=2) else: xverts = [field_x] yverts = [field_y] mpl_poly = Circle((field_x, field_y), radius=5.0, edgecolor='#a9a9a9', facecolor='#F2F2F2', clip_box=ax.bbox, picker=3.0, linewidth=2) mpl_poly.facet_name = direction.name mpl_poly.completed_ops = get_completed_ops(direction) mpl_poly.started_ops = get_started_ops(direction) mpl_poly.current_op = get_current_op(direction) set_patch_color(mpl_poly, direction) ax.add_patch(mpl_poly) # Add facet names if direction.name != 'field': poly_tuple = tuple([(xp, yp) for xp, yp in zip(xverts, yverts)]) xmid = SPolygon(poly_tuple).centroid.x ymid = SPolygon(poly_tuple).centroid.y else: xmid = field_x ymid = field_y if trim_names: name = direction.name.split('_')[-1] else: name = direction.name marker = ax.text(xmid, ymid, name, color='k', clip_on=True, clip_box=ax.bbox, ha='center', va='bottom') marker.set_zorder(1001) markers.append(marker) # Add info box at = AnchoredText("Selected direction: None", prop=dict(size=12), frameon=True, loc=3) at.patch.set_boxstyle("round,pad=0.,rounding_size=0.2") at.set_zorder(1002) ax.add_artist(at) ax.relim() ax.autoscale() ax.set_aspect('equal') if hasWCSaxes: RAAxis = ax.coords['ra'] RAAxis.set_axislabel('RA', minpad=0.75) RAAxis.set_major_formatter('hh:mm:ss') DecAxis = ax.coords['dec'] DecAxis.set_axislabel('Dec', minpad=0.75) DecAxis.set_major_formatter('dd:mm:ss') ax.coords.grid(color='black', alpha=0.5, linestyle='solid') else: plt.xlabel("RA (arb. units)") plt.ylabel("Dec (arb. units)") # Define coodinate formater to show RA and Dec under mouse pointer ax.format_coord = formatCoord # Show legend not_processed_patch = plt.Rectangle((0, 0), 1, 1, edgecolor='#a9a9a9', facecolor='#F2F2F2', linewidth=2) processing_patch = plt.Rectangle((0, 0), 1, 1, edgecolor='#a9a9a9', facecolor='#F2F5A9', linewidth=2) selfcal_ok_patch = plt.Rectangle((0, 0), 1, 1, edgecolor='#a9a9a9', facecolor='#A9F5A9', linewidth=2) selfcal_not_ok_patch = plt.Rectangle((0, 0), 1, 1, edgecolor='#a9a9a9', facecolor='#A4A4A4', linewidth=2) processing_error = plt.Rectangle((0, 0), 1, 1, edgecolor='#a9a9a9', facecolor='#F5A9A9', linewidth=2) patch_list = [ not_processed_patch, processing_patch, processing_error, selfcal_not_ok_patch, selfcal_ok_patch ] label_list = [ 'Unprocessed', 'Processing', 'Pipeline Error', 'Selfcal Failed', 'Selfcal OK' ] for i in range(options['reimages']): label_list.append('Image ' + str(i + 1)) color = (0.66 / (i + 2)**0.5, 0.96 / (i + 2)**0.5, 0.66 / (i + 2)**0.5, 1.0) reimage_patch = plt.Rectangle((0, 0), 1, 1, edgecolor='#a9a9a9', facecolor=color, linewidth=2) patch_list.append(reimage_patch) l = ax.legend(patch_list, label_list, loc="upper right") l.set_zorder(1002) # Add check for mouse clicks and key presses fig.canvas.mpl_connect('pick_event', on_pick) fig.canvas.mpl_connect('key_press_event', on_press) # Add timer to update the plot every 60 seconds timer = fig.canvas.new_timer(interval=60000) timer.add_callback(update_plot) timer.start() # Show plot plt.show() plt.close(fig) # Clean up any temp casacore images if not hasaplpy: if os.path.exists('/tmp/tempimage'): try: shutil.rmtree('/tmp/tempimage') except OSError: pass
def plot(LSM, fileName=None, labelBy=None): """ Shows a simple plot of the sky model. The circles in the plot are scaled with flux. If the sky model is grouped into patches, sources are colored by patch and the patch positions are indicated with stars. Parameters ---------- LSM : SkyModel object Input sky model fileName : str, optional If given, the plot is saved to a file instead of displayed labelBy : str, optional One of 'source' or 'patch': label points using source names ('source') or patch names ('patch') Examples: --------- Plot and display to the screen:: >>> LSM = lsmtool.load('sky.model') >>> plot(LSM) Plot and save to a PDF file:: >>> plot(LSM, 'sky_plot.pdf') """ try: import os if 'DISPLAY' not in os.environ: import matplotlib if matplotlib.get_backend() is not 'Agg': matplotlib.use("Agg") import matplotlib.pyplot as plt from matplotlib.ticker import FuncFormatter except Exception as e: raise ImportError('PyPlot could not be imported. Plotting is not ' 'available: {0}'.format(e.message)) try: try: from astropy.visualization.wcsaxes import WCSAxes hasWCSaxes = True except: from wcsaxes import WCSAxes hasWCSaxes = True except: hasWCSaxes = False import numpy as np from ..operations_lib import radec2xy, makeWCS global midRA, midDec, ymin, xmin if len(LSM) == 0: log.error('Sky model is empty.') return fig = plt.figure(1,figsize=(7.66,7)) plt.clf() x, y, midRA, midDec = LSM._getXY() if hasWCSaxes: wcs = makeWCS(midRA, midDec) ax = WCSAxes(fig, [0.16, 0.1, 0.8, 0.8], wcs=wcs) fig.add_axes(ax) else: ax = plt.gca() if LSM.hasPatches: nsrc = len(LSM.getPatchNames()) else: nsrc = len(LSM) sm = plt.cm.ScalarMappable(cmap=plt.cm.Set3, norm=plt.Normalize(vmin=0, vmax=nsrc)) sm._A = [] # Set symbol sizes by flux, making sure no symbol is smaller than 50 or # larger than 1000 s = [] fluxes = LSM.getColValues('I') if len(fluxes[fluxes > 0.0]) == 0: minflux = 0.0 else: minflux = np.min(fluxes[fluxes > 0.0]) for flux in LSM.getColValues('I'): if flux > 0.0: s.append(min(1000.0, (1.0+2.0*np.log10(flux/minflux))*50.0)) else: s.append(50.0) # Color sources by patch if grouped c = [0]*len(LSM) cp = [] if LSM.hasPatches: for p, patchName in enumerate(LSM.getPatchNames()): indices = LSM.getRowIndex(patchName) cp.append(sm.to_rgba(p)) for ind in indices: c[ind] = sm.to_rgba(p) else: c = [sm.to_rgba(0)] * nsrc # Plot sources if hasWCSaxes: RA = LSM.getColValues('Ra') Dec = LSM.getColValues('Dec') ax.set_xlim(np.min(x)-20, np.max(x)+20) ax.set_ylim(np.min(y)-20, np.max(y)+20) plt.scatter(x, y, s=s, c=c) if LSM.hasPatches: RAp, Decp = LSM.getPatchPositions(asArray=True) goodInd = np.where( (RAp != 0.0) & (Decp != 0.0) ) if len(goodInd[0]) < len(RAp): log.info('Some patch positions are unset. Run setPatchPositions() ' 'before plotting to see patch positions and patch names.') xp, yp = radec2xy(RAp[goodInd], Decp[goodInd], midRA, midDec) plt.scatter(xp, yp, s=100, c=cp, marker='*') # Set axis labels, etc. if hasWCSaxes: RAAxis = ax.coords['ra'] RAAxis.set_axislabel('RA', minpad=0.75) RAAxis.set_major_formatter('hh:mm:ss') DecAxis = ax.coords['dec'] DecAxis.set_axislabel('Dec', minpad=0.75) DecAxis.set_major_formatter('dd:mm:ss') ax.coords.grid(color='black', alpha=0.5, linestyle='solid') else: plt.xlabel("RA (arb. units)") plt.ylabel("Dec (arb. units)") if labelBy is not None: if labelBy.lower() == 'source': labels = LSM.getColValues('name') xls = x yls = y elif labelBy.lower() == 'patch': if LSM.hasPatches: labels = LSM.getPatchNames() xls = xp yls = yp else: labels = LSM.getColValues('name') xls = x yls = y else: raise ValueError("The lableBy parameter must be one of 'source' or " "'patch'.") for label, xl, yl in zip(labels, xls, yls): plt.annotate(label, xy = (xl, yl), xytext = (-2, 2), textcoords= 'offset points', ha='right', va='bottom') # Define coodinate formater to show RA and Dec under mouse pointer RAformatter = FuncFormatter(RAtickformatter) ax.format_coord = formatCoord if fileName is not None: plt.savefig(fileName) else: plt.show() plt.close(fig)