def draw_boxxyerrorbar(axis, plot, alpha=0.25, draw_labels = False): """ Gnuplot-like errorbars """ axis.update_limits(plot, padding = 0.05) from matplotlib.collections import PatchCollection r = boxxyerrorbar(plot.xmin, plot.xmax, plot.ymin, plot.ymax) pc = PatchCollection(r, facecolor=plot.color, edgecolor='None', alpha=alpha) if not plot.color: # maybe the plot did not contain a color, let's give it some color! if isinstance(pc, (tuple, list)): color = pc[0].get_facecolor() else: color = pc.get_facecolor() # Update the plot color plot.set_plot_parameters(color = color) if draw_labels: axis.draw_labels(plot) axis.add_collection(pc)
def tod3D(tod, dets=None, time_resolution=2., prange=[None, None], sky_coords=False, pointingpar=None, anim_time=10., display='show', filename=None, **kwargs): """3D visualization of a TOD: animation of the 2D focal plane through the TOD Arguments: ---------- - tod: TOD object to visualize Optional: --------- - dets: list of detectors to plot (default will use tod.det_uid) - time_resolution: Tod will be downsample to reach a time resolution as close as possible to the input using a power of 2 resampling (every 2**n samples). Default is 2s - prange: scale - sky_coords: if True, project the focal plane on the sky and show the TOD animation in RA, DEC (must provide pointingpar) - pointingpar: focal plane model, eg. {'source': 'fp_file', 'filename': '.../RelativeOffsets/template_ar2_150529s.txt'} - anim_time: total time of the animated TOD in seconds - display: 'show' or 'save' - filename: only if display=='save', by default: todname.gif - other args to define the animation (interval, repeat, repeat_delay...) """ if dets is None: dets = tod.det_uid # Re-sampling tres = (tod.ctime[-1] - tod.ctime[0]) / tod.nsamps r = time_resolution / tres Nresamp = 2**np.ceil(np.log2(r)) tod_ds = tod.copy(resample=Nresamp) print("Downsampled tod has %i samples, with time resolution of %.2fs" % (tod_ds.nsamps, (tod_ds.ctime[-1] - tod_ds.ctime[0]) / tod_ds.nsamps)) # Get focal plane infos if sky_coords: x, y = get_sky_coords(tod_ds, pointingpar) x = x[dets] y = y[dets] x *= 180. / np.pi y *= 180. / np.pi if x.max() - x.min() > 180.: x[x < 0] += 360. if y.max() - y.min() > 180.: y[y < 0] += 360. else: x = tod.info.array_data['sky_x'][dets] y = tod.info.array_data['sky_y'][dets] polfamily = tod.info.array_data['pol_family'][dets] # Get limits fot the plot if sky_coords: x_lim = (x.min(), x.max()) y_lim = (y.min(), y.max()) else: x_lim, y_lim = get_array_plot_lims(tod.info.array, tod.info.season) pmin, pmax = prange if pmin == None: pmin = tod.data[dets].min() if pmax == None: pmax = tod.data[dets].max() plt.ioff() # Create animation fig = plt.figure(figsize=(7, 8)) ax1 = fig.add_axes([0.1, 0.2, 0.8, 0.7]) if sky_coords: ax1.tick_params(bottom='off', top='on', right='off', left='on', labelbottom='off', labelleft='on', labeltop='on', which='both') else: ax1.tick_params(bottom='off', top='off', right='off', left='off', labelbottom='off', labelleft='off', which='both') ax2 = fig.add_axes([0.1, 0.1, 0.8, 0.1]) ax2.plot(tod_ds.ctime - tod_ds.ctime[0], tod_ds.data[dets].T, 'b', alpha=0.1) ax1.set_xlim(x_lim) ax1.set_ylim(y_lim) ax2.set_xlim((0, tod_ds.ctime[-1] - tod_ds.ctime[0])) ax2.set_ylim((pmin, pmax)) ax2.set_yticks((pmin, 0, pmax)) if sky_coords: ax1.set_xlabel('RA (degrees)') ax1.set_ylabel('DEC (degrees)') ax2.set_xlabel('Time [s]') ax2.set_ylabel('pW') plt.figtext(0.5, 0.95, '%s' % tod_ds.info.basename, ha='center', va='center', fontsize='xx-large') if not sky_coords: plot_wafer_names(ax1, tod_ds.info.array) line = ax2.axvline(0, color='r') color = get_color(tod_ds.data[dets, 0], pmax=pmax, pmin=pmin) colors = [ get_color(tod_ds.data[dets, i], pmax=pmax, pmin=pmin) for i in range(tod_ds.nsamps) ] if sky_coords: # pos = x[:,0], y[:,0] patchlists = [ PatchCollection( get_patches((x[:, i], y[:, i]), colors[i], polfamily)) for i in range(tod_ds.nsamps) ] ax1.add_collection(patchlists[0]) else: pos = x, y patchlist = PatchCollection(get_patches(pos, colors[0], polfamily)) print(patchlist.get_facecolor()) # p = patchlist[0] # ax1.add_patch(p) ax1.add_collection(patchlist) def animate(i): if sky_coords: patchlist = patchlists[i] color = colors[i] patchlist.set_facecolors(color) patchlist.set_edgecolors(color) ax1.collections.pop() ax1.add_collection(patchlist) else: patchlist = ax1.collections[0] color = colors[i] patchlist.set_facecolors(color) patchlist.set_edgecolors(color) line.set_xdata(tod_ds.ctime[i] - tod_ds.ctime[0]) return line interval = float(anim_time) / tod_ds.nsamps * 1000 ani = animation.FuncAnimation(fig, animate, np.arange(tod_ds.nsamps), interval=interval, **kwargs) if display == 'show': plt.ion() plt.show() plt.draw() elif display == 'save': if filename is None: filename = '%s.gif' % tod_ds.info.basename Writer = animation.writers['imagemagick_file'] writer = Writer(fps=1 / interval * 1000) ani.save(filename, writer=writer) plt.close()