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)
Example #2
0
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()