Esempio n. 1
0
def CreateLegendPlot(measurements, title_font="modern 12",
                     title="Legend", legend_font="modern 9"):
    """ Plot contour for two axes of an RTDC measurement
    
    Parameters
    ----------
    measurements : list of instances of RTDS_DataSet
        Contains color information and titel.
        - mm.Configuration["Plotting"]["Contour Color"]
        - mm.title
    """
    aplot = ca.Plot()
    # normalize our data in range zero to 100
    aplot.range2d.high=(100,100)
    aplot.range2d.low=(0,0)
    aplot.title = title
    aplot.title_font = title_font
    leftmarg = 7
    toppos = 90
    increment = 10
    for mm in measurements:
        if mm.Configuration["Plotting"]["Scatter Title Colored"]:
            mmlabelcolor = mm.Configuration["Plotting"]["Contour Color"]
        else:
            mmlabelcolor = "black"
        alabel = ca.DataLabel(
                        component=aplot, 
                        label_position="right",
                        data_point=(leftmarg,toppos),
                        padding_bottom=0,
                        marker_size=5,
                        bgcolor="transparent",
                        border_color="transparent",
                        label_text="  "+mm.title,
                        font=legend_font,
                        text_color=mmlabelcolor,
                        marker="circle",
                        marker_color="transparent",
                        marker_line_color=mm.Configuration["Plotting"]["Contour Color"],
                        show_label_coords=False,
                        arrow_visible=False
                              )
        toppos -= increment
        aplot.overlays.append(alabel)
    
    aplot.padding_left = 0
    aplot.y_axis = None
    aplot.x_axis = None
    aplot.x_grid = None
    aplot.y_grid = None

    # pan tool
    pan = cta.PanTool(aplot, drag_button="left")
    aplot.tools.append(pan)

    return aplot
Esempio n. 2
0
 def _create_plot_component(self, measurement, xax, yax):
     # Create some data
     plot = tlabwrap.CreateScatterPlot(measurement,
                                       xax=xax,
                                       yax=yax,
                                       panzoom=False)
     # Create a plot data obect and give it this data
     # Tweak some of the plot properties
     plot.title = "Click to add points, press Enter to add filter"
     plot.padding = 50
     plot.line_width = 1
     # Attach some tools to the plot
     pan = cta.PanTool(plot, drag_button="right", constrain_key="shift")
     plot.tools.append(pan)
     zoom = cta.ZoomTool(component=plot, tool_mode="box", always_on=False)
     plot.overlays.append(zoom)
     plot.overlays.append(LineDrawer(self.callback, (xax, yax), plot))
     return plot
Esempio n. 3
0
    def change_plot(self, indices, x_scale=None, y_scale=None):
        global XY_DATA
        self.plot_indices = indices
        self.container = self.create_container()
        self.high_step = 1  #float(max(self.plot_data[0][:, 0]))
        self.low_step = 0
        self.container.data = capi.ArrayPlotData()
        self.time_data_labels = {}
        if len(indices) == 0:
            return
        self._refresh = 1
        XY_DATA = []
        x_scale, y_scale = self.get_axis_scales(x_scale, y_scale)

        # loop through plot data and plot it
        overlays_plotted = False
        fnams = []
        for d in range(len(self.plot_data)):

            if not self.runs_shown[d]:
                continue

            # The legend entry for each file is one of the following forms:
            #   1) [file basename] VAR
            #   2) [file basename:] VAR variables
            # depending on if variabes were perturbed for this run.
            variables = self.variables[d]
            if len(variables) > 30:
                variables = ", ".join(variables.split(",")[:-1])
            if variables:
                variables = ": {0}".format(variables)

            self.time_data_labels[d] = []
            ti = self.find_time_index()
            mheader = self._mheader()
            xname = mheader[self.x_idx]
            self.y_idx = getidx(mheader, mheader[indices[0]])

            # indices is an integer list containing the columns of the data to
            # be plotted. The indices are wrt to the FIRST file in parsed, not
            # necessarily the same for every file. Here, we loop through the
            # indices, determine the name from the first file's header and
            # find the x and y index in the file of interest
            fnam, header = self.get_info(d)
            if fnam in fnams:
                fnam += "-{0}".format(len(fnams))
            fnams.append(fnam)
            for i, idx in enumerate(indices):
                yname = mheader[idx]

                # get the indices for this file
                xp_idx = getidx(header, xname)
                yp_idx = getidx(header, yname)
                if xp_idx is None or yp_idx is None:
                    continue

                # tjfulle: x and y should always be x and disp, z is the color
                x = self.plot_data[d][:, xp_idx] * x_scale
                y = self.plot_data[d][:, yp_idx] * y_scale
                z = self.plot_data[d][:, yp_idx]
                if self.nfiles() - 1 or self.overlay_plot_data:
                    entry = "({0}) {1}{2}".format(fnam, yname, variables)
                else:
                    entry = "{0} {1}".format(yname, variables)
                self.create_plot(x, y, z, entry)
                XY_DATA.append(
                    Namespace(key=fnam,
                              xname=xname,
                              x=x,
                              yname=yname,
                              y=y,
                              lw=1))

                # create point marker
                xp = self.plot_data[d][ti, xp_idx] * x_scale
                yp = self.plot_data[d][ti, yp_idx] * y_scale
                #self.create_data_label(xp, yp, d, yp_idx)

                if not overlays_plotted:
                    # plot the overlay data
                    overlays_plotted = True
                    ii = i + 1
                    for fnam, head in self.overlay_headers.items():
                        # get the x and y indeces corresponding to what is
                        # being plotted
                        xo_idx = getidx(head, xname)
                        yo_idx = getidx(head, yname)
                        if xo_idx is None or yo_idx is None:
                            continue
                        xo = self.overlay_plot_data[fnam][:, xo_idx] * x_scale
                        zo = self.overlay_plot_data[fnam][:, yo_idx] * y_scale
                        # legend entry
                        entry = "({0}) {1}".format(fnam, head[yo_idx])
                        _i = d + len(self.plot_data) + 3
                        self.create_plot(xo, y, zo, entry)
                        XY_DATA.append(
                            Namespace(key=fnam,
                                      xname=xname,
                                      x=xo,
                                      yname=yname,
                                      y=yo,
                                      lw=3))
                        ii += 1
                        continue

        capi.add_default_grids(self.container)
        capi.add_default_axes(self.container, htitle=mheader[self.x_idx])

        self.container.index_range.tight_bounds = False
        self.container.index_range.refresh()
        self.container.value_range.tight_bounds = False
        self.container.value_range.refresh()

        self.container.tools.append(ctapi.PanTool(self.container))

        zoom = ctapi.ZoomTool(self.container, tool_mode="box", always_on=False)
        self.container.overlays.append(zoom)

        dragzoom = ctapi.DragZoom(self.container, drag_button="right")
        self.container.tools.append(dragzoom)

        self.container.legend.visible = True

        self.container.invalidate_and_redraw()
        return
    def create_plot(self):

        # Create the mapper, etc
        self._image_index = chaco.GridDataSource(scipy.array([]),
                                                 scipy.array([]),
                                                 sort_order=("ascending",
                                                             "ascending"))
        image_index_range = chaco.DataRange2D(self._image_index)
        self._image_index.on_trait_change(self._metadata_changed,
                                          "metadata_changed")

        self._image_value = chaco.ImageData(data=scipy.array([]),
                                            value_depth=1)

        image_value_range = chaco.DataRange1D(self._image_value)

        # Create the contour plots
        #self.polyplot = ContourPolyPlot(index=self._image_index,
        self.polyplot = chaco.CMapImagePlot(
            index=self._image_index,
            value=self._image_value,
            index_mapper=chaco.GridMapper(range=image_index_range),
            color_mapper=self._cmap(image_value_range))

        # Add a left axis to the plot
        left = chaco.PlotAxis(orientation='left',
                              title="y",
                              mapper=self.polyplot.index_mapper._ymapper,
                              component=self.polyplot)
        self.polyplot.overlays.append(left)

        # Add a bottom axis to the plot
        bottom = chaco.PlotAxis(orientation='bottom',
                                title="x",
                                mapper=self.polyplot.index_mapper._xmapper,
                                component=self.polyplot)
        self.polyplot.overlays.append(bottom)

        # Add some tools to the plot
        self.polyplot.tools.append(
            tools.PanTool(self.polyplot,
                          constrain_key="shift",
                          drag_button="middle"))

        self.polyplot.overlays.append(
            tools.ZoomTool(component=self.polyplot,
                           tool_mode="box",
                           always_on=False))

        self.lineInspectorX = clickableLineInspector.ClickableLineInspector(
            component=self.polyplot,
            axis='index_x',
            inspect_mode="indexed",
            write_metadata=True,
            is_listener=False,
            color="white")

        self.lineInspectorY = clickableLineInspector.ClickableLineInspector(
            component=self.polyplot,
            axis='index_y',
            inspect_mode="indexed",
            write_metadata=True,
            color="white",
            is_listener=False)

        self.polyplot.overlays.append(self.lineInspectorX)
        self.polyplot.overlays.append(self.lineInspectorY)

        self.boxSelection2D = boxSelection2D.BoxSelection2D(
            component=self.polyplot)
        self.polyplot.overlays.append(self.boxSelection2D)

        # Add these two plots to one container
        self.centralContainer = chaco.OverlayPlotContainer(padding=0,
                                                           use_backbuffer=True,
                                                           unified_draw=True)
        self.centralContainer.add(self.polyplot)

        # Create a colorbar
        cbar_index_mapper = chaco.LinearMapper(range=image_value_range)
        self.colorbar = chaco.ColorBar(
            index_mapper=cbar_index_mapper,
            plot=self.polyplot,
            padding_top=self.polyplot.padding_top,
            padding_bottom=self.polyplot.padding_bottom,
            padding_right=40,
            resizable='v',
            width=30)

        self.plotData = chaco.ArrayPlotData(
            line_indexHorizontal=scipy.array([]),
            line_valueHorizontal=scipy.array([]),
            scatter_indexHorizontal=scipy.array([]),
            scatter_valueHorizontal=scipy.array([]),
            scatter_colorHorizontal=scipy.array([]),
            fitLine_indexHorizontal=scipy.array([]),
            fitLine_valueHorizontal=scipy.array([]))

        self.crossPlotHorizontal = chaco.Plot(self.plotData, resizable="h")
        self.crossPlotHorizontal.height = 100
        self.crossPlotHorizontal.padding = 20
        self.crossPlotHorizontal.plot(
            ("line_indexHorizontal", "line_valueHorizontal"), line_style="dot")
        self.crossPlotHorizontal.plot(
            ("scatter_indexHorizontal", "scatter_valueHorizontal",
             "scatter_colorHorizontal"),
            type="cmap_scatter",
            name="dot",
            color_mapper=self._cmap(image_value_range),
            marker="circle",
            marker_size=4)

        self.crossPlotHorizontal.index_range = self.polyplot.index_range.x_range

        self.plotData.set_data("line_indexVertical", scipy.array([]))
        self.plotData.set_data("line_valueVertical", scipy.array([]))
        self.plotData.set_data("scatter_indexVertical", scipy.array([]))
        self.plotData.set_data("scatter_valueVertical", scipy.array([]))
        self.plotData.set_data("scatter_colorVertical", scipy.array([]))
        self.plotData.set_data("fitLine_indexVertical", scipy.array([]))
        self.plotData.set_data("fitLine_valueVertical", scipy.array([]))

        self.crossPlotVertical = chaco.Plot(self.plotData,
                                            width=140,
                                            orientation="v",
                                            resizable="v",
                                            padding=20,
                                            padding_bottom=160)
        self.crossPlotVertical.plot(
            ("line_indexVertical", "line_valueVertical"), line_style="dot")

        self.crossPlotVertical.plot(
            ("scatter_indexVertical", "scatter_valueVertical",
             "scatter_colorVertical"),
            type="cmap_scatter",
            name="dot",
            color_mapper=self._cmap(image_value_range),
            marker="circle",
            marker_size=4)

        self.crossPlotVertical.index_range = self.polyplot.index_range.y_range

        # Create a container and add components
        self.container = chaco.HPlotContainer(padding=40,
                                              fill_padding=True,
                                              bgcolor="white",
                                              use_backbuffer=False)

        inner_cont = chaco.VPlotContainer(padding=40, use_backbuffer=True)
        inner_cont.add(self.crossPlotHorizontal)
        inner_cont.add(self.centralContainer)
        self.container.add(self.colorbar)
        self.container.add(inner_cont)
        self.container.add(self.crossPlotVertical)
Esempio n. 5
0
def contour_plot(measurements,
                 levels=[0.5, 0.95],
                 axContour=None,
                 wxtext=False,
                 square=True):
    """Plot contour for two axes of an RT-DC measurement
    
    Parameters
    ----------
    measurement : RTDCBase
        Contains measurement data.
    levels : float or list of floats in interval (0,1)
        Plot the contour at that particular level from the maximum (1).
    axContour : instance of matplotlib `Axis`
        Plotting axis for the contour.
    square : bool
        The plot has square shape.
    """
    mm = measurements[0]
    xax = mm.config["plotting"]["axis x"].lower()
    yax = mm.config["plotting"]["axis y"].lower()

    # Commence plotting
    if axContour is not None:
        raise NotImplementedError("Tell Chaco to reuse plots?")

    pd = ca.ArrayPlotData()
    contour_plot = ca.Plot(pd)
    contour_plot.id = "ShapeOut_contour_plot"

    scalex = mm.config["plotting"]["scale x"].lower()
    scaley = mm.config["plotting"]["scale y"].lower()

    ## Add isoelastics
    isoel = plot_common.get_isoelastics(mm)
    if isoel:
        for ii, data in enumerate(isoel):
            x_key = 'isoel_x' + str(ii)
            y_key = 'isoel_y' + str(ii)
            pd.set_data(x_key, data[:, 0])
            pd.set_data(y_key, data[:, 1])
            contour_plot.plot((x_key, y_key),
                              color="gray",
                              index_scale=scalex,
                              value_scale=scaley)

    #colors = [ "".join(map(chr, np.array(c[:3]*255,dtype=int))).encode('hex') for c in colors ]
    if not isinstance(levels, list):
        levels = [levels]

    set_contour_data(contour_plot, measurements, levels=levels)

    # Axes
    left_axis = ca.PlotAxis(contour_plot,
                            orientation='left',
                            title=dfn.feature_name2label[yax],
                            tick_generator=plot_common.MyTickGenerator())

    bottom_axis = ca.PlotAxis(contour_plot,
                              orientation='bottom',
                              title=dfn.feature_name2label[xax],
                              tick_generator=plot_common.MyTickGenerator())
    # Show log scale only with 10** values (#56)
    contour_plot.index_axis.tick_generator = plot_common.MyTickGenerator()
    contour_plot.value_axis.tick_generator = plot_common.MyTickGenerator()
    contour_plot.overlays.append(left_axis)
    contour_plot.overlays.append(bottom_axis)

    contour_plot.title = "Contours"

    contour_plot.title_font = "modern 12"

    # zoom tool
    zoom = cta.ZoomTool(contour_plot,
                        tool_mode="box",
                        color="beige",
                        minimum_screen_delta=50,
                        border_color="black",
                        border_size=1,
                        always_on=True,
                        drag_button="right",
                        enable_wheel=True,
                        zoom_factor=1.1)
    contour_plot.tools.append(zoom)
    contour_plot.aspect_ratio = 1
    contour_plot.use_downsampling = True

    # pan tool
    pan = cta.PanTool(contour_plot, drag_button="left")

    contour_plot.tools.append(pan)

    return contour_plot
Esempio n. 6
0
def scatter_plot(measurement,
                 axScatter=None,
                 square=True,
                 panzoom=True,
                 select=True):
    """Plot scatter plot for two axes of an RT-DC measurement
    
    Parameters
    ----------
    measurement : RTDCBase
        Contains measurement data.
    axScatter : instance of matplotlib `Axis`
        Plotting axis for the scatter data.
    square : bool
        The plot has square shape.
    panzoom : bool
        Add panning and zooming tools.
    select : bool
        Add point selection tool.
    """
    mm = measurement
    xax = mm.config["plotting"]["axis x"].lower()
    yax = mm.config["plotting"]["axis y"].lower()
    # Plotting area
    plotfilters = mm.config.copy()["plotting"]
    marker_size = plotfilters["scatter marker size"]

    # Commence plotting
    if axScatter is not None:
        raise NotImplementedError("Tell Chaco to reuse plots?")

    scalex = mm.config["plotting"]["scale x"].lower()
    scaley = mm.config["plotting"]["scale y"].lower()

    pd = ca.ArrayPlotData()

    sc_plot = ca.Plot(pd)
    sc_plot.id = mm.identifier

    ## Add isoelastics
    isoel = plot_common.get_isoelastics(mm)
    if isoel:
        for ii, data in enumerate(isoel):
            x_key = 'isoel_x' + str(ii)
            y_key = 'isoel_y' + str(ii)
            pd.set_data(x_key, data[:, 0])
            pd.set_data(y_key, data[:, 1])
            sc_plot.plot((x_key, y_key),
                         color="gray",
                         index_scale=scalex,
                         value_scale=scaley)

    # Display numer of events
    elabel = ca.PlotLabel(text="",
                          component=sc_plot,
                          vjustify="bottom",
                          hjustify="right",
                          name="events")
    elabel.id = "event_label_" + mm.identifier
    sc_plot.overlays.append(elabel)

    # Set content of scatter plot
    set_scatter_data(sc_plot, mm)

    plot_kwargs = {
        "name": "scatter_events",
        "marker": "square",
        #"fill_alpha": 1.0,
        "marker_size": int(marker_size),
        "outline_color": "transparent",
        "line_width": 0,
        "bgcolor": "white",
        "index_scale": scalex,
        "value_scale": scaley,
    }

    # Create the KDE plot
    if plotfilters["KDE"].lower() == "none":
        # Single-color plot
        plot_kwargs["data"] = ("index", "value")
        plot_kwargs["type"] = "scatter"
        plot_kwargs["color"] = "black"
    else:
        # Plots with density
        plot_kwargs["data"] = ("index", "value", "color")
        plot_kwargs["type"] = "cmap_scatter"
        plot_kwargs["color_mapper"] = ca.jet

    # Excluded events
    plot_kwargs_excl = plot_kwargs.copy()
    plot_kwargs_excl["name"] = "excluded_events"
    plot_kwargs_excl["data"] = ("excl_index", "excl_value")
    plot_kwargs_excl["type"] = "scatter"
    plot_kwargs_excl["color"] = 0x929292
    if pd.get_data("excl_index") is not None:
        sc_plot.plot(**plot_kwargs_excl)

    # Plot colored points on top of excluded events
    if pd.get_data("index") is not None:
        sc_plot.plot(**plot_kwargs)

    # Axes
    left_axis = ca.PlotAxis(sc_plot,
                            orientation='left',
                            title=dfn.feature_name2label[yax],
                            tick_generator=plot_common.MyTickGenerator())

    bottom_axis = ca.PlotAxis(sc_plot,
                              orientation='bottom',
                              title=dfn.feature_name2label[xax],
                              tick_generator=plot_common.MyTickGenerator())
    # Show log scale only with 10** values (#56)
    sc_plot.index_axis.tick_generator = plot_common.MyTickGenerator()
    sc_plot.value_axis.tick_generator = plot_common.MyTickGenerator()
    sc_plot.overlays.append(left_axis)
    sc_plot.overlays.append(bottom_axis)

    sc_plot.title = mm.title
    sc_plot.title_font = "modern 12"
    if plotfilters["Scatter Title Colored"]:
        mmlabelcolor = plotfilters["contour color"]
    else:
        mmlabelcolor = "black"
    sc_plot.title_color = mmlabelcolor

    # zoom tool
    if panzoom:
        zoom = cta.ZoomTool(sc_plot,
                            tool_mode="box",
                            color="beige",
                            minimum_screen_delta=50,
                            border_color="black",
                            border_size=1,
                            always_on=True,
                            drag_button="right",
                            enable_wheel=True,
                            zoom_factor=1.1)
        sc_plot.tools.append(zoom)
        sc_plot.aspect_ratio = 1
        sc_plot.use_downsampling = True

        # pan tool
        pan = cta.PanTool(sc_plot, drag_button="left")
        sc_plot.tools.append(pan)

    # select tool
    if select:
        my_plot = sc_plot.plots["scatter_events"][0]
        my_plot.tools.append(
            cta.ScatterInspector(my_plot,
                                 selection_mode="single",
                                 persistent_hover=False))
        my_plot.overlays.append(
            ca.ScatterInspectorOverlay(my_plot,
                                       hover_color="transparent",
                                       hover_marker_size=int(marker_size * 4),
                                       hover_outline_color="black",
                                       hover_line_width=1,
                                       selection_marker_size=int(marker_size *
                                                                 1.5),
                                       selection_outline_color="black",
                                       selection_line_width=1,
                                       selection_color="purple"))

    return sc_plot
Esempio n. 7
0
def CreateScatterPlot(measurement, xax="Area", yax="Defo",
                      axScatter=None, isoel=None, 
                      square=True, 
                      downsampling=None, downsample_events=None,
                      panzoom=True, select=True):
    """ Plot scatter plot for two axes of an RTDC measurement
    
    Parameters
    ----------
    measurement : instance of RTDS_DataSet
        Contains measurement data.
    xax : str
        x-Axis to plot (see `librtdc.dfn.cfgmap`)
    yax : str
        y-Axis to plot (see `librtdc.dfn.cfgmap`)
    axScatter : instance of matplotlib `Axis`
        Plotting axis for the scatter data.
    isoel : list for line plot
        Manually selected isoelastics to plot. Defaults to None.
        If no isoelastics are found, then a warning is raised.
    square : bool
        The plot has square shape.
    downsampling : int or None
        Filter events that are overdrawn by others (saves time).
        If set to None then
        Configuration["Plotting"]["Downsampling"] is used.
        Chaco does not yet have this implemented.
    downsample_events : int or None
        Number of events to draw in the down-sampled plot. This number
        is either 
        - >=1: limit total number of events drawn
        - <1: only perform 1st downsampling step with grid
        If set to None, then
        Configuration["Plotting"]["Downsample Events"] will be used.
    panzoom : bool
        Add panning and zooming tools.
    select : bool
        Add point selection tool.
    """
    mm = measurement

    # Plotting area
    plotfilters = mm.Configuration["Plotting"].copy()
    marker_size = plotfilters["Scatter Marker Size"]
    
    if downsampling is None:
        downsampling = plotfilters["Downsampling"]
        
    if downsample_events is None:
        downsample_events = plotfilters["Downsample Events"]
    
    # We will pretend as if we are plotting circularity vs. area
    areamin = plotfilters[xax+" Min"]
    areamax = plotfilters[xax+" Max"]
    circmin = plotfilters[yax+" Min"]
    circmax = plotfilters[yax+" Max"]

    if areamin == areamax:
        areamin = getattr(mm, dfn.cfgmaprev[xax]).min()
        areamax = getattr(mm, dfn.cfgmaprev[xax]).max()

    if circmin == circmax:
        circmin = getattr(mm, dfn.cfgmaprev[yax]).min()
        circmax = getattr(mm, dfn.cfgmaprev[yax]).max()

    # Commence plotting
    if axScatter is not None:
        raise NotImplementedError("Tell Chaco to reuse plots?")
        #plt.figure(1)
        #axScatter = plt.axes()

    if mm.Configuration["Filtering"]["Enable Filters"]:
        x = getattr(mm, dfn.cfgmaprev[xax])[mm._filter]
        y = getattr(mm, dfn.cfgmaprev[yax])[mm._filter]
    else:
        # filtering disabled
        x = getattr(mm, dfn.cfgmaprev[xax])
        y = getattr(mm, dfn.cfgmaprev[yax])
    
    if downsampling:
        lx = x.shape[0]
        x, y = mm.GetDownSampledScatter(
                                    downsample_events=downsample_events
                                    )
        positions = np.vstack([x.ravel(), y.ravel()])
        print("Downsampled from {} to {}".format(lx, x.shape[0]))
    else:
        positions = None

    density = mm.GetKDE_Scatter(yax=yax, xax=xax, positions=positions)

    scalex = mm.Configuration["Plotting"]["Scale X"].lower()
    scaley = mm.Configuration["Plotting"]["Scale Y"].lower()

    pd = ca.ArrayPlotData()
    
    scatter_plot = ca.Plot(pd)

    ## Add isoelastics
    if mm.Configuration["Plotting"]["Isoelastics"]:
        if isoel is None:
            chansize = mm.Configuration["General"]["Channel Width"]
            #plotdata = list()
            # look for isoelastics:
            for key in list(isoelastics.keys()):
                if float(key.split("um")[0]) == chansize > 0:
                    plotdict = isoelastics[key]
                    for key2 in list(plotdict.keys()):
                        if key2 == "{} {}".format(xax, yax):
                            isoel = plotdict[key2]
        if isoel is None:
            warnings.warn("Could not find matching isoelastics for"+
                          " Setting: x={} y={}, Channel width: {}".
                          format(xax, yax, chansize))
        else:
            for ii, data in enumerate(isoel):
                x_key = 'isoel_x'+str(ii)
                y_key = 'isoel_y'+str(ii)
                #
                # # Crop data points outside of the plotting area
                # #data = crop_linear_data(data, areamin, areamax, circmin, circmax)
                #
                pd.set_data(x_key, data[:,0])
                pd.set_data(y_key, data[:,1])
                scatter_plot.plot((x_key, y_key), color="gray",
                                  index_scale=scalex, value_scale=scaley)

    pd.set_data("index", x)
    pd.set_data("value", y)
    pd.set_data("color", density)

    plot_kwargs = {
                   "name": "my_plot",
                   "marker": "square",
                   #"fill_alpha": 1.0,
                   "marker_size": int(marker_size),
                   "outline_color": "transparent",
                   "line_width": 0,
                   "bgcolor": "white",
                   "index_scale": scalex,
                   "value_scale": scaley,
                    }
    
    # Plot filtered data in grey
    if (plotfilters["Scatter Plot Excluded Events"] and
        mm._filter.sum() != mm.time.shape[0]):
        # determine the number of points we are allowed to add
        if downsampling:
            # respect the maximum limit of plotted events
            excl_num = int(downsample_events - np.sum(mm._filter))
        else:
            # plot all excluded events
            excl_num = np.sum(~mm._filter)

        if excl_num > 0:
            excl_x = getattr(mm, dfn.cfgmaprev[xax])[~mm._filter][:excl_num]
            excl_y = getattr(mm, dfn.cfgmaprev[yax])[~mm._filter][:excl_num]
            pd.set_data("excl_index", excl_x)
            pd.set_data("excl_value", excl_y)
            plot_kwargs_excl = plot_kwargs.copy()
            plot_kwargs_excl["data"] = ("excl_index", "excl_value")
            plot_kwargs_excl["type"] = "scatter"
            plot_kwargs_excl["color"] = 0x929292
            scatter_plot.plot(**plot_kwargs_excl)

    # Create the KDE plot
    if plotfilters["KDE"].lower() == "none":
        # Single-color plot
        plot_kwargs["data"] = ("index", "value")
        plot_kwargs["type"] = "scatter"
        plot_kwargs["color"] = "black"
                  
    else:                
        # Plots with density
        plot_kwargs["data"] = ("index", "value", "color")
        plot_kwargs["type"] = "cmap_scatter"
        plot_kwargs["color_mapper"] = ca.jet

    scatter_plot.plot(**plot_kwargs)

    # Set x-y limits
    xlim = scatter_plot.index_mapper.range
    ylim = scatter_plot.value_mapper.range
    xlim.low = areamin
    xlim.high = areamax
    ylim.low = circmin
    ylim.high = circmax

    # Axes
    left_axis = ca.PlotAxis(scatter_plot, orientation='left',
                            title=dfn.axlabels[yax],
                            tick_generator=misc.MyTickGenerator())
    
    bottom_axis = ca.PlotAxis(scatter_plot, orientation='bottom',
                              title=dfn.axlabels[xax],
                              tick_generator=misc.MyTickGenerator())
    # Show log scale only with 10** values (#56)
    scatter_plot.index_axis.tick_generator=misc.MyTickGenerator()
    scatter_plot.value_axis.tick_generator=misc.MyTickGenerator()
    scatter_plot.overlays.append(left_axis)
    scatter_plot.overlays.append(bottom_axis)

    scatter_plot.title = mm.title
    scatter_plot.title_font = "modern 12"
    if plotfilters["Scatter Title Colored"]:
        mmlabelcolor = plotfilters["Contour Color"]
    else:
        mmlabelcolor = "black"
    scatter_plot.title_color = mmlabelcolor

    # Display numer of events
    if plotfilters["Show Events"]:
        elabel = ca.PlotLabel(text="{} events".format(np.sum(mm._filter)),
                              component=scatter_plot,
                              vjustify="bottom",
                              hjustify="right")
        scatter_plot.overlays.append(elabel)
        
    # zoom tool
    if panzoom:
        zoom = cta.ZoomTool(scatter_plot,
                        tool_mode="box",
                        color="beige",
                        minimum_screen_delta=50,
                        border_color="black",
                        border_size=1,
                        always_on=True,
                        drag_button="right",
                        enable_wheel=True,
                        zoom_factor=1.1)
        scatter_plot.tools.append(zoom)
        scatter_plot.aspect_ratio = 1
        scatter_plot.use_downsampling = True
        
        # pan tool
        pan = cta.PanTool(scatter_plot, drag_button="left")
        scatter_plot.tools.append(pan)

    if select:
        my_plot = scatter_plot.plots["my_plot"][0]
        my_plot.tools.append(
            cta.ScatterInspector(
                my_plot,
                selection_mode="single",
                persistent_hover=False))
        my_plot.overlays.append(
            ca.ScatterInspectorOverlay(
                my_plot,
                hover_color = "transparent",
                hover_marker_size = int(marker_size*4),
                hover_outline_color = "black",
                hover_line_width = 1,
                selection_marker_size = int(marker_size*1.5),
                selection_outline_color = "black",
                selection_line_width = 1,
                selection_color = "purple")
            )

    return scatter_plot
Esempio n. 8
0
def CreateContourPlot(measurements, xax="Area", yax="Defo", levels=.5,
                      axContour=None, isoel=None,
                      wxtext=False, square=True):
    """ Plot contour for two axes of an RTDC measurement
    
    Parameters
    ----------
    measurement : instance of RTDS_DataSet
        Contains measurement data.
    xax : str
        x-Axis to plot (see `librtdc.dfn.cfgmap`)
    yax : str
        y-Axis to plot (see `librtdc.dfn.cfgmap`)
    levels : float or list of floats in interval (0,1)
        Plot the contour at that particular level from the maximum (1).
    axContour : instance of matplotlib `Axis`
        Plotting axis for the contour.
    isoel : list for line plot
        Manually selected isoelastics to plot. Defaults to None.
        If no isoelastics are found, then a warning is raised.
    square : bool
        The plot has square shape.
    """

    mm = measurements[0]

    # Plotting area
    plotfilters = mm.Configuration["Plotting"]

    # We will pretend as if we are plotting circularity vs. area
    areamin = plotfilters[xax+" Min"]
    areamax = plotfilters[xax+" Max"]
    circmin = plotfilters[yax+" Min"]
    circmax = plotfilters[yax+" Max"]
    
    if areamin == areamax:
        areamin = getattr(mm, dfn.cfgmaprev[xax]).min()
        areamax = getattr(mm, dfn.cfgmaprev[xax]).max()

    if circmin == circmax:
        circmin = getattr(mm, dfn.cfgmaprev[yax]).min()
        circmax = getattr(mm, dfn.cfgmaprev[yax]).max()

    # Commence plotting
    if axContour is not None:
        raise NotImplementedError("Tell Chaco to reuse plots?")

    pd = ca.ArrayPlotData()
    contour_plot = ca.Plot(pd)

    scalex = mm.Configuration["Plotting"]["Scale X"].lower()
    scaley = mm.Configuration["Plotting"]["Scale Y"].lower()

    ## Add isoelastics
    if mm.Configuration["Plotting"]["Isoelastics"]:
        if isoel is None:
            chansize = mm.Configuration["General"]["Channel Width"]
            #plotdata = list()
            # look for isoelastics:
            for key in list(isoelastics.keys()):
                if float(key.split("um")[0]) == chansize > 0:
                    plotdict = isoelastics[key]
                    for key2 in list(plotdict.keys()):
                        if key2 == "{} {}".format(xax, yax):
                            isoel = plotdict[key2]
        if isoel is None:
            warnings.warn("Could not find matching isoelastics for"+
                          " Setting: x={} y={}, Channel width: {}".
                          format(xax, yax, chansize))
        else:
            for ii, data in enumerate(isoel):
                x_key = 'isoel_x'+str(ii)
                y_key = 'isoel_y'+str(ii)
                #
                # # Crop data events outside of the plotting area
                # #data = crop_linear_data(data, areamin, areamax, circmin, circmax)
                #
                pd.set_data(x_key, data[:,0])
                pd.set_data(y_key, data[:,1])
                contour_plot.plot((x_key, y_key), color="gray",
                                  index_scale=scalex, value_scale=scaley)


    #colors = [ "".join(map(chr, np.array(c[:3]*255,dtype=int))).encode('hex') for c in colors ]
    if not isinstance(levels, list):
        levels = [levels]

    for mm, ii in zip(measurements, range(len(measurements))):
        
        (X,Y,density) = mm.GetKDE_Contour(yax=yax, xax=xax)
        
        cname = "con_{}_{}_{}".format(mm.name, mm.file_hashes[0][1], ii)

        pd.set_data(cname, density)

        #plt.contour(x,y,density,1,colors=[c],label=name,linewidths=[2.5],zorder=5)
        plev = [np.max(density)*i for i in levels]

        if len(plev) == 2:
            styles = ["dot", "solid"]
        else:
            styles = "solid"

        
        # contour widths
        if "Contour Width" in mm.Configuration["Plotting"]:
            cwidth = mm.Configuration["Plotting"]["Contour Width"]
        else:
            cwidth = 1.2

        contour_plot.contour_plot(cname,
                                  type="line",
                                  xbounds = (X[0][0], X[0][-1]),
                                  ybounds = (Y[0][0], Y[-1][0]),
                                  levels = plev,
                                  colors = mm.Configuration["Plotting"]["Contour Color"],
                                  styles = styles,
                                  widths = [cwidth*.7, cwidth], # make outer lines slightly smaller
                                  )

    # Set x-y limits
    xlim = contour_plot.index_mapper.range
    ylim = contour_plot.value_mapper.range
    xlim.low = areamin
    xlim.high = areamax
    ylim.low = circmin
    ylim.high = circmax

    contour_plot.index_scale = scalex
    contour_plot.value_scale = scaley

    # Axes
    left_axis = ca.PlotAxis(contour_plot, orientation='left',
                            title=dfn.axlabels[yax],
                            tick_generator=misc.MyTickGenerator())
    
    bottom_axis = ca.PlotAxis(contour_plot, orientation='bottom',
                              title=dfn.axlabels[xax],
                              tick_generator=misc.MyTickGenerator())
    # Show log scale only with 10** values (#56)
    contour_plot.index_axis.tick_generator=misc.MyTickGenerator()
    contour_plot.value_axis.tick_generator=misc.MyTickGenerator()
    contour_plot.overlays.append(left_axis)
    contour_plot.overlays.append(bottom_axis)

    contour_plot.title = "Contours"

    contour_plot.title_font = "modern 12"

    # zoom tool
    zoom = cta.ZoomTool(contour_plot,
                        tool_mode="box",
                        color="beige",
                        minimum_screen_delta=50,
                        border_color="black",
                        border_size=1,
                        always_on=True,
                        drag_button="right",
                        enable_wheel=True,
                        zoom_factor=1.1)
    contour_plot.tools.append(zoom)
    contour_plot.aspect_ratio = 1
    contour_plot.use_downsampling = True
    
    # pan tool
    pan = cta.PanTool(contour_plot, drag_button="left")

    contour_plot.tools.append(pan)

    return contour_plot
Esempio n. 9
0
def legend_plot(measurements, title_font="modern 12",
                title="Legend", legend_font="modern 9"):
    """Plot legend for an RT-DC data set
    
    Parameters
    ----------
    measurements : list of RTDCBase
        Contains color information and titel.
        - mm.config["plotting"]["contour color"]
        - mm.title
    """
    # The legend is actually a list of plot labels
    aplot = ca.Plot()
    # normalize range from zero to 100 for convenience
    aplot.range2d.high=(100,100)
    aplot.range2d.low=(0,0)
    aplot.title = title
    aplot.title_font = title_font
    leftmarg = 7
    fname, fsize = legend_font.rsplit(" ", 1)
    fsize = int(fsize)
    autoscale = measurements[0].config["plotting"]["legend autoscaled"]
    if autoscale and len(measurements)>=10:
        # This case makes the legend entries fit into the plot window 
        lm = len(measurements)
        marker_size = int(np.floor(5/lm*9))
        fsize = int(np.floor(fsize/lm*9))
        increment = 100/(lm+1)
        # This is a heuristic setting that works for most plots:
        # (not sure how chaco defines marker positions)
        label_position = -6*(5/lm*9)**.3
    else:
        marker_size = 5
        increment = 10
        label_position = -10
    legend_font = " ".join([fname, str(fsize)])
    toppos = 100 - increment
        
    for mm in measurements:
        if mm.config["plotting"]["scatter title colored"]:
            mmlabelcolor = mm.config["plotting"]["contour color"]
        else:
            mmlabelcolor = "black"
        alabel = ca.DataLabel(
                        component=aplot, 
                        label_position=[0,label_position],
                        data_point=(leftmarg,toppos),
                        padding_bottom=0,
                        marker_size=marker_size,
                        bgcolor="transparent",
                        border_color="transparent",
                        label_text="  "+mm.title,
                        font=legend_font,
                        text_color=mmlabelcolor,
                        marker="circle",
                        marker_color="transparent",
                        marker_line_color=mm.config["plotting"]["contour color"],
                        show_label_coords=False,
                        arrow_visible=False
                              )
        toppos -= increment
        aplot.overlays.append(alabel)
    
    aplot.padding_left = 0
    aplot.y_axis = None
    aplot.x_axis = None
    aplot.x_grid = None
    aplot.y_grid = None

    # pan tool
    pan = cta.PanTool(aplot, drag_button="left")
    aplot.tools.append(pan)

    return aplot