Example #1
0
 def _make_tooltip(self):
     """If toolip is true, create it, either with default
     settings or using custom_tooltip object."""
     if self._enable_tooltip:
         if self._custom_tooltip:
             tt = self._custom_tooltip
         else:
             tt = Tooltip(fields=['x', 'y'],
                          formats=['', '.2f'],
                          labels=['Hour', 'ED'])
     else:
         tt = None
     return tt
Example #2
0
    def process(self, inputs):
        """
        Takes `datetime`, `open`, `close`, `high`, `volume` columns in the
        dataframe to plot the bqplot figure for this stock.

        Arguments
        -------
         inputs: list
            list of input dataframes.
        Returns
        -------
        bqplot.Figure
        """
        stock = inputs[0]
        num_points = self.conf['points']
        stride = max(len(stock) // num_points, 1)
        label = 'stock'
        if 'label' in self.conf:
            label = self.conf['label']
        sc = LinearScale()
        sc2 = LinearScale()
        dt_scale = DateScale()
        ax_x = Axis(label='Date', scale=dt_scale)
        ax_y = Axis(label='Price', scale=sc, orientation='vertical',
                    tick_format='0.0f')
        # Construct the marks
        ohlc = OHLC(x=stock['datetime'][::stride],
                    y=stock[['open', 'high', 'low', 'close']]
                    .as_gpu_matrix()[::stride, :],
                    marker='candle', scales={'x': dt_scale, 'y': sc},
                    format='ohlc', stroke='blue',
                    display_legend=True, labels=[label])
        bar = Bars(x=stock['datetime'][::stride],
                   y=stock['volume'][::stride],
                   scales={'x': dt_scale, 'y': sc2},
                   padding=0.2)
        def_tt = Tooltip(fields=['x', 'y'], formats=['%Y-%m-%d', '.2f'])
        bar.tooltip = def_tt
        bar.interactions = {
            'legend_hover': 'highlight_axes',
            'hover': 'tooltip',
            'click': 'select',
         }
        sc.min = stock['close'].min() - 0.3 * \
            (stock['close'].max() - stock['close'].min())
        sc.max = stock['close'].max()
        sc2.max = stock['volume'].max()*4.0
        f = Figure(axes=[ax_x, ax_y], marks=[ohlc, bar],
                   fig_margin={"top": 0, "bottom": 60,
                               "left": 60, "right": 60})
        return f
Example #3
0
    def __init__(self):
        # Initialize the chart with a default ticker
        self.data_chart = pd.DataFrame()
        self.chart_dropdown_x = Dropdown(description='X-Axis',
                                         layout=Layout(width='380px'))
        self.chart_dropdown_y = Dropdown(description='Y-Axis',
                                         layout=Layout(width='380px'))

        self.x_sc = LinearScale()
        self.y_sc = LinearScale()
        self.tt = Tooltip(fields=['name', 'x', 'y'],
                          formats=['', '.2f', '.2f'])
        self.scatter = Scatter(scales={
            'x': self.x_sc,
            'y': self.y_sc
        },
                               colors=['dodgerblue'],
                               tooltip=self.tt,
                               unhovered_style={'opacity': 0.5})

        self.ax_x = Axis(scale=self.x_sc)
        self.ax_y = Axis(scale=self.y_sc,
                         orientation='vertical',
                         tick_format='0.2f')
        self.fig = Figure(marks=[],
                          axes=[self.ax_x, self.ax_y],
                          animation_duration=1000,
                          padding_x=0,
                          layout={
                              'width': "100%",
                              'height': "500px"
                          })

        self.data_grid = DataGrid(layout={'width': "720px", 'height': "200px"})

        self.box = VBox([
            HBox([self.fig]),
            HBox([self.chart_dropdown_x, self.chart_dropdown_y])
        ])

        display(self.box)
Example #4
0
 def create_map(self, map_file):
     first_year = self.years[0]
     first_provincial_income_proportion = self.get_provincial_income_proportion(
         first_year)
     sc_geo = Mercator(scale_factor=7000, center=(5.5, 53.0))
     tooltip = Tooltip(fields=["name"], labels=["province"])
     return Map(
         map_data=topo_load(map_file),
         scales={
             "projection": sc_geo,
             "color": self.col_scale
         },
         colors={"default_color": "Grey"},
         color=first_provincial_income_proportion,
         tooltip=tooltip,
         interactions={
             "click": "select",
             "hover": "tooltip"
         },
         visible=True,
     )
    def __init__(self):
        self.niveau  = Dropdown(options=[('Niveau {}'.format(i), i) for i in RushHour.niveaux()])
        self.niveau.observe(lambda widget: self.change_niveau(widget.owner.value))

        self.voiture = Dropdown(options=[])
        self.modele = Plateau(1)
        self.vue = Figure(scale_x = LinearScale(min=0, max=self.modele.dimension),
                          scale_y = LinearScale(min=self.modele.dimension, max=0))
        self.vue.layout.width="75ex"
        self.vue.layout.width="75ex"
        self.vue.layout.height=self.vue.layout.width;

        self.vue.vue_voitures = {}
        for lettre, couleur in couleurs.items():
            vue_voiture = Lines(x=[], y=[],
                                scales={'x':self.vue.scale_x,
                                        'y':self.vue.scale_y},
                                fill='inside',
                                colors=[couleurs[lettre]],
                                visible=False,
                                tooltip=Tooltip(fields=["lettre"],show_labels=False),
                                )
            vue_voiture.lettre = "coucou" # lettre
            vue_voiture.on_click(lambda vue_voiture, _: self.choix_voiture(vue_voiture.lettre))
            self.vue.vue_voitures[lettre] = vue_voiture
        self.vue.marks = list(self.vue.vue_voitures.values())

        boutton_solution = Button(description="Solution")
        boutton_solution.on_click(self.montre_solution)
        VBox.__init__(self, [HBox([self.niveau, boutton_solution]),
                            self.vue,
                            self.boutton_direction('U'),
                            HBox([self.boutton_direction('L'), self.voiture, self.boutton_direction('R')]),
                            self.boutton_direction('D')
                           ])
        self.layout.align_items = 'center'
        self.change_niveau(1)
Example #6
0
def feature_byProperty(features, xProperties, seriesProperty, **kwargs):
    """Generates a Chart from a set of features. Plots property values of one or more features.
    Reference: https://developers.google.com/earth-engine/guides/charts_feature#uichartfeaturebyproperty

    Args:
        features (ee.FeatureCollection): The features to include in the chart.
        xProperties (list | dict): One of (1) a list of properties to be plotted on the x-axis; or (2) a (property, label) dictionary specifying labels for properties to be used as values on the x-axis.
        seriesProperty (str): The name of the property used to label each feature in the legend.

    Raises:
        Exception: If the provided xProperties is not a list or dict.
        Exception: If the chart fails to create.
    """
    try:
        df = ee_to_df(features)

        if isinstance(xProperties, list):
            x_data = xProperties
            y_data = df[xProperties].values
        elif isinstance(xProperties, dict):
            x_data = list(xProperties.values())
            y_data = df[list(xProperties.keys())].values
        else:
            raise Exception("xProperties must be a list or dictionary.")

        labels = list(df[seriesProperty])

        if "ylim" in kwargs:
            min_value = kwargs["ylim"][0]
            max_value = kwargs["ylim"][1]
        else:
            min_value = y_data.min()
            max_value = y_data.max()
            max_value = max_value + 0.2 * (max_value - min_value)

        if "title" not in kwargs:
            title = ""
        else:
            title = kwargs["title"]
        if "legend_location" not in kwargs:
            legend_location = "top-left"
        else:
            legend_location = kwargs["legend_location"]

        if "display_legend" not in kwargs:
            display_legend = True
        else:
            display_legend = kwargs["display_legend"]

        fig = plt.figure(
            title=title,
            legend_location=legend_location,
        )

        if "width" in kwargs:
            fig.layout.width = kwargs["width"]
        if "height" in kwargs:
            fig.layout.height = kwargs["height"]

        bar_chart = plt.bar(x=x_data,
                            y=y_data,
                            labels=labels,
                            display_legend=display_legend)

        bar_chart.type = "grouped"

        if "colors" in kwargs:
            bar_chart.colors = kwargs["colors"]

        if "xlabel" in kwargs:
            plt.xlabel(kwargs["xlabel"])
        if "ylabel" in kwargs:
            plt.ylabel(kwargs["ylabel"])
        plt.ylim(min_value, max_value)

        if "xlabel" in kwargs and ("ylabel" in kwargs):
            bar_chart.tooltip = Tooltip(
                fields=["x", "y"], labels=[kwargs["xlabel"], kwargs["ylabel"]])
        else:
            bar_chart.tooltip = Tooltip(fields=["x", "y"])

        plt.show()

    except Exception as e:
        raise Exception(e)
Example #7
0
def feature_histogram(features,
                      property,
                      maxBuckets=None,
                      minBucketWidth=None,
                      **kwargs):
    """
    Generates a Chart from a set of features.
    Computes and plots a histogram of the given property.
    - X-axis = Histogram buckets (of property value).
    - Y-axis = Frequency

    Reference:
    https://developers.google.com/earth-engine/guides/charts_feature#uichartfeaturehistogram

    Args:
        features  (ee.FeatureCollection): The features to include in the chart.
        property                   (str): The name of the property to generate the histogram for.
        maxBuckets       (int, optional): The maximum number of buckets (bins) to use when building a histogram;
                                          will be rounded up to a power of 2.
        minBucketWidth (float, optional): The minimum histogram bucket width, or null to allow any power of 2.

    Raises:
        Exception: If the provided xProperties is not a list or dict.
        Exception: If the chart fails to create.
    """
    import math

    if not isinstance(features, ee.FeatureCollection):
        raise Exception("features must be an ee.FeatureCollection")

    first = features.first()
    props = first.propertyNames().getInfo()
    if property not in props:
        raise Exception(
            f"property {property} not found. Available properties: {', '.join(props)}"
        )

    def nextPowerOf2(n):
        return pow(2, math.ceil(math.log2(n)))

    def grow_bin(bin_size, ref):
        while bin_size < ref:
            bin_size *= 2
        return bin_size

    try:

        raw_data = pd.to_numeric(
            pd.Series(features.aggregate_array(property).getInfo()))
        y_data = raw_data.tolist()

        if "ylim" in kwargs:
            min_value = kwargs["ylim"][0]
            max_value = kwargs["ylim"][1]
        else:
            min_value = raw_data.min()
            max_value = raw_data.max()

        data_range = max_value - min_value

        if not maxBuckets:
            initial_bin_size = nextPowerOf2(data_range / pow(2, 8))
            if minBucketWidth:
                if minBucketWidth < initial_bin_size:
                    bin_size = grow_bin(minBucketWidth, initial_bin_size)
                else:
                    bin_size = minBucketWidth
            else:
                bin_size = initial_bin_size
        else:
            initial_bin_size = math.ceil(data_range / nextPowerOf2(maxBuckets))
            if minBucketWidth:
                if minBucketWidth < initial_bin_size:
                    bin_size = grow_bin(minBucketWidth, initial_bin_size)
                else:
                    bin_size = minBucketWidth
            else:
                bin_size = initial_bin_size

        start_bins = (math.floor(min_value / bin_size) *
                      bin_size) - (bin_size / 2)
        end_bins = (math.ceil(max_value / bin_size) * bin_size) + (bin_size /
                                                                   2)

        if start_bins < min_value:
            y_data.append(start_bins)
        else:
            y_data[y_data.index(min_value)] = start_bins
        if end_bins > max_value:
            y_data.append(end_bins)
        else:
            y_data[y_data.index(max_value)] = end_bins

        num_bins = math.floor((end_bins - start_bins) / bin_size)

        if "title" not in kwargs:
            title = ""
        else:
            title = kwargs["title"]

        fig = plt.figure(title=title)

        if "width" in kwargs:
            fig.layout.width = kwargs["width"]
        if "height" in kwargs:
            fig.layout.height = kwargs["height"]

        if "xlabel" not in kwargs:
            xlabel = ""
        else:
            xlabel = kwargs["xlabel"]

        if "ylabel" not in kwargs:
            ylabel = ""
        else:
            ylabel = kwargs["ylabel"]

        histogram = plt.hist(
            sample=y_data,
            bins=num_bins,
            axes_options={
                "count": {
                    "label": ylabel
                },
                "sample": {
                    "label": xlabel
                }
            },
        )

        if "colors" in kwargs:
            histogram.colors = kwargs["colors"]
        if "stroke" in kwargs:
            histogram.stroke = kwargs["stroke"]
        else:
            histogram.stroke = "#ffffff00"
        if "stroke_width" in kwargs:
            histogram.stroke_width = kwargs["stroke_width"]
        else:
            histogram.stroke_width = 0

        if ("xlabel" in kwargs) and ("ylabel" in kwargs):
            histogram.tooltip = Tooltip(
                fields=["midpoint", "count"],
                labels=[kwargs["xlabel"], kwargs["ylabel"]],
            )
        else:
            histogram.tooltip = Tooltip(fields=["midpoint", "count"])
        plt.show()

    except Exception as e:
        raise Exception(e)
Example #8
0
def feature_groups(features, xProperty, yProperty, seriesProperty, **kwargs):
    """Generates a Chart from a set of features.
    Plots the value of one property for each feature.
    Reference:
    https://developers.google.com/earth-engine/guides/charts_feature#uichartfeaturegroups
    Args:
        features (ee.FeatureCollection): The feature collection to make a chart from.
        xProperty (str): Features labeled by xProperty.
        yProperty (str): Features labeled by yProperty.
        seriesProperty (str): The property used to label each feature in the legend.
    Raises:
        Exception: Errors when creating the chart.
    """

    try:
        df = ee_to_df(features)
        df[yProperty] = pd.to_numeric(df[yProperty])
        unique_series_values = df[seriesProperty].unique().tolist()
        new_column_names = []

        for value in unique_series_values:
            sample_filter = (df[seriesProperty] == value).map({
                True: 1,
                False: 0
            })
            column_name = str(yProperty) + "_" + str(value)
            df[column_name] = df[yProperty] * sample_filter
            new_column_names.append(column_name)

        if "labels" in kwargs:
            labels = kwargs["labels"]
        else:
            labels = [str(x) for x in unique_series_values]

        if "ylim" in kwargs:
            min_value = kwargs["ylim"][0]
            max_value = kwargs["ylim"][1]
        else:
            min_value = df[yProperty].to_numpy().min()
            max_value = df[yProperty].to_numpy().max()
            max_value = max_value + 0.2 * (max_value - min_value)

        if "title" not in kwargs:
            title = ""
        else:
            title = kwargs["title"]
        if "legend_location" not in kwargs:
            legend_location = "top-left"
        else:
            legend_location = kwargs["legend_location"]

        x_data = list(df[xProperty])
        y_data = [df[x] for x in new_column_names]

        plt.bar(x_data, y_data)
        fig = plt.figure(
            title=title,
            legend_location=legend_location,
        )

        if "width" in kwargs:
            fig.layout.width = kwargs["width"]
        if "height" in kwargs:
            fig.layout.height = kwargs["height"]

        if "display_legend" not in kwargs:
            display_legend = True
        else:
            display_legend = kwargs["display_legend"]

        bar_chart = plt.bar(x_data,
                            y_data,
                            labels=labels,
                            display_legend=display_legend)

        if "colors" in kwargs:
            bar_chart.colors = kwargs["colors"]

        if "xlabel" in kwargs:
            plt.xlabel(kwargs["xlabel"])
        if "ylabel" in kwargs:
            plt.ylabel(kwargs["ylabel"])
        plt.ylim(min_value, max_value)

        if "xlabel" in kwargs and ("ylabel" in kwargs):
            bar_chart.tooltip = Tooltip(
                fields=["x", "y"], labels=[kwargs["xlabel"], kwargs["ylabel"]])
        else:
            bar_chart.tooltip = Tooltip(fields=["x", "y"])

        plt.show()

    except Exception as e:
        raise Exception(e)
Example #9
0
def feature_byFeature(features, xProperty, yProperties, **kwargs):
    """Generates a Chart from a set of features. Plots the value of one or more properties for each feature.
    Reference: https://developers.google.com/earth-engine/guides/charts_feature#uichartfeaturebyfeature

    Args:
        features (ee.FeatureCollection): The feature collection to generate a chart from.
        xProperty (str): Features labeled by xProperty.
        yProperties (list): Values of yProperties.

    Raises:
        Exception: Errors when creating the chart.
    """

    try:

        df = ee_to_df(features)
        if "ylim" in kwargs:
            min_value = kwargs["ylim"][0]
            max_value = kwargs["ylim"][1]
        else:
            min_value = df[yProperties].to_numpy().min()
            max_value = df[yProperties].to_numpy().max()
            max_value = max_value + 0.2 * (max_value - min_value)

        if "title" not in kwargs:
            title = ""
        else:
            title = kwargs["title"]
        if "legend_location" not in kwargs:
            legend_location = "top-left"
        else:
            legend_location = kwargs["legend_location"]

        x_data = list(df[xProperty])
        y_data = df[yProperties].values.T.tolist()

        plt.bar(x_data, y_data)
        fig = plt.figure(
            title=title,
            legend_location=legend_location,
        )

        if "width" in kwargs:
            fig.layout.width = kwargs["width"]
        if "height" in kwargs:
            fig.layout.height = kwargs["height"]

        if "labels" in kwargs:
            labels = kwargs["labels"]
        else:
            labels = yProperties

        if "display_legend" not in kwargs:
            display_legend = True
        else:
            display_legend = kwargs["display_legend"]

        bar_chart = plt.bar(x_data,
                            y_data,
                            labels=labels,
                            display_legend=display_legend)

        bar_chart.type = "grouped"

        if "colors" in kwargs:
            bar_chart.colors = kwargs["colors"]

        if "xlabel" in kwargs:
            plt.xlabel(kwargs["xlabel"])
        if "ylabel" in kwargs:
            plt.ylabel(kwargs["ylabel"])
        plt.ylim(min_value, max_value)

        if "xlabel" in kwargs and ("ylabel" in kwargs):
            bar_chart.tooltip = Tooltip(
                fields=["x", "y"], labels=[kwargs["xlabel"], kwargs["ylabel"]])
        else:
            bar_chart.tooltip = Tooltip(fields=["x", "y"])

        plt.show()

    except Exception as e:
        raise Exception(e)
Example #10
0
# %% {"collapsed": true}
def get_data(year):
    year_index = year - 1800
    income = data['income'].apply(lambda x: x[year_index])
    life_exp = data['lifeExpectancy'].apply(lambda x: x[year_index])
    pop = data['population'].apply(lambda x: x[year_index])
    return income, life_exp, pop


# %% [markdown]
# #### Creating the Tooltip to display the required fields
#
# `bqplot`'s native `Tooltip` allows us to simply display the data fields we require on a mouse-interaction.

# %% {"collapsed": true}
tt = Tooltip(fields=['name', 'x', 'y'],
             labels=['Country Name', 'Income per Capita', 'Life Expectancy'])

# %% [markdown]
# #### Creating the Label to display the year
#
# Staying true to the `d3` recreation of the talk, we place a `Label` widget in the bottom-right of the `Figure` (it inherits the `Figure` co-ordinates when no scale is passed to it). With `enable_move` set to `True`, the `Label` can be dragged around.

# %% {"collapsed": true}
year_label = Label(x=[0.75],
                   y=[0.10],
                   default_size=46,
                   font_weight='bolder',
                   colors=['orange'],
                   text=[str(initial_year)],
                   enable_move=True)
Example #11
0
    def init_dashboard(self):
        from bqplot import DateScale, LinearScale, DateScale, Axis, Lines, Figure, Tooltip
        from bqplot.colorschemes import CATEGORY10, CATEGORY20
        from bqplot.toolbar import Toolbar
        from ipywidgets import VBox, Tab
        from IPython.display import display
        from tornado import gen

        cpu_sx = LinearScale()
        cpu_sy = LinearScale()
        cpu_x = Axis(label='Time (s)', scale=cpu_sx)
        cpu_y = Axis(label='CPU Usage (%)',
                     scale=cpu_sy,
                     orientation='vertical')
        mem_sx = LinearScale()
        mem_sy = LinearScale()
        mem_x = Axis(label='Time (s)', scale=mem_sx)
        mem_y = Axis(label='Memory Usage (MB)',
                     scale=mem_sy,
                     orientation='vertical')
        thru_sx = LinearScale()
        thru_sy = LinearScale()
        thru_x = Axis(label='Time (s)', scale=thru_sx)
        thru_y = Axis(label='Data Processed (MB)',
                      scale=thru_sy,
                      orientation='vertical')

        colors = CATEGORY20
        tt = Tooltip(fields=['name'], labels=['Filter Name'])
        self.cpu_lines = {
            str(n): Lines(labels=[str(n)],
                          x=[0.0],
                          y=[0.0],
                          colors=[colors[i]],
                          tooltip=tt,
                          scales={
                              'x': cpu_sx,
                              'y': cpu_sy
                          })
            for i, n in enumerate(self.other_nodes)
        }
        self.mem_lines = {
            str(n): Lines(labels=[str(n)],
                          x=[0.0],
                          y=[0.0],
                          colors=[colors[i]],
                          tooltip=tt,
                          scales={
                              'x': mem_sx,
                              'y': mem_sy
                          })
            for i, n in enumerate(self.other_nodes)
        }
        self.thru_lines = {
            str(n): Lines(labels=[str(n)],
                          x=[0.0],
                          y=[0.0],
                          colors=[colors[i]],
                          tooltip=tt,
                          scales={
                              'x': thru_sx,
                              'y': thru_sy
                          })
            for i, n in enumerate(self.other_nodes)
        }

        self.cpu_fig = Figure(marks=list(self.cpu_lines.values()),
                              axes=[cpu_x, cpu_y],
                              title='CPU Usage',
                              animation_duration=50)
        self.mem_fig = Figure(marks=list(self.mem_lines.values()),
                              axes=[mem_x, mem_y],
                              title='Memory Usage',
                              animation_duration=50)
        self.thru_fig = Figure(marks=list(self.thru_lines.values()),
                               axes=[thru_x, thru_y],
                               title='Data Processed',
                               animation_duration=50)

        tab = Tab()
        tab.children = [self.cpu_fig, self.mem_fig, self.thru_fig]
        tab.set_title(0, 'CPU')
        tab.set_title(1, 'Memory')
        tab.set_title(2, 'Throughput')
        display(tab)

        perf_queue = Queue()
        self.exit_perf = Event()

        def wait_for_perf_updates(q, exit, cpu_lines, mem_lines, thru_lines):
            while not exit.is_set():
                messages = []

                while not exit.is_set():
                    try:
                        messages.append(q.get(False))
                    except queue.Empty as e:
                        time.sleep(0.05)
                        break

                for message in messages:
                    filter_name, time_val, cpu, mem_info, processed = message
                    mem = mem_info[0] / 2.**20
                    vmem = mem_info[1] / 2.**20
                    proc = processed / 2.**20
                    cpu_lines[filter_name].x = np.append(
                        cpu_lines[filter_name].x, [time_val.total_seconds()])
                    cpu_lines[filter_name].y = np.append(
                        cpu_lines[filter_name].y, [cpu])
                    mem_lines[filter_name].x = np.append(
                        mem_lines[filter_name].x, [time_val.total_seconds()])
                    mem_lines[filter_name].y = np.append(
                        mem_lines[filter_name].y, [mem])
                    thru_lines[filter_name].x = np.append(
                        thru_lines[filter_name].x, [time_val.total_seconds()])
                    thru_lines[filter_name].y = np.append(
                        thru_lines[filter_name].y, [proc])

        for n in self.other_nodes:
            n.perf_queue = perf_queue

        self.perf_thread = Thread(target=wait_for_perf_updates,
                                  args=(perf_queue, self.exit_perf,
                                        self.cpu_lines, self.mem_lines,
                                        self.thru_lines))
        self.perf_thread.start()
Example #12
0
def plot_pulse_files(metafile, time=True, backend='bqplot'):
    '''
    plot_pulse_files(metafile)

    Helper function to plot a list of AWG files. A jupyter slider widget allows choice of sequence number.
    '''
    #If we only go one filename turn it into a list

    with open(metafile, 'r') as FID:
        meta_info = json.load(FID)
    fileNames = []
    for el in meta_info["instruments"].values():
        # Accomodate seq_file per instrument and per channel
        if isinstance(el, str):
            fileNames.append(el)
        elif isinstance(el, dict):
            for file in el.values():
                fileNames.append(file)

    line_names, num_seqs, data_dicts = extract_waveforms(fileNames, time=time)
    localname = os.path.split(fileNames[0])[1]
    sequencename = localname.split('-')[0]

    if backend == 'matplotlib':
        import matplotlib.pyplot as plt
        from ipywidgets import interact, IntSlider

        def update_plot(seq_ind):
            for line_name in line_names:
                dat = data_dicts[f"{line_name}_{seq_ind}"]
                plt.plot(dat['x'], dat['y'], label=line_name, linewidth=1.0)

        interact(update_plot,
                 seq_ind=IntSlider(min=1,
                                   max=num_seqs,
                                   step=1,
                                   value=1,
                                   description="Sequence Number"))

    elif backend == 'bqplot':
        from bqplot import DateScale, LinearScale, Axis, Lines, Figure, Tooltip
        from bqplot.colorschemes import CATEGORY10, CATEGORY20
        from ipywidgets import interact, IntSlider, VBox
        sx = LinearScale()
        sy = LinearScale(min=-1.0, max=2 * len(line_names) - 1.0)
        if time:
            ax = Axis(label='Time (ns)', scale=sx)
        else:
            ax = Axis(label="Samples", scale=sx)
        ay = Axis(label='Amplitude', scale=sy, orientation='vertical')

        colors = CATEGORY10 if len(line_names) < 10 else CATEGORY20
        lines = []
        tt = Tooltip(fields=['name'], labels=['Channel'])
        x_mult = 1.0e9 if time else 1
        for i, line_name in enumerate(line_names):
            dat = data_dicts[f"{line_name}_1"]
            lines.append(
                Lines(labels=[line_name],
                      x=x_mult * dat['x'],
                      y=dat['y'],
                      scales={
                          'x': sx,
                          'y': sy
                      },
                      tooltip=tt,
                      animate=False,
                      colors=[colors[i]]))

        slider = IntSlider(min=1,
                           max=num_seqs,
                           step=1,
                           description='Segment',
                           value=1)

        def segment_changed(change):
            for line, line_name in zip(lines, line_names):
                dat = data_dicts[f"{line_name}_{slider.value}"]
                line.x = x_mult * dat['x']
                line.y = dat['y']

        slider.observe(segment_changed, 'value')
        fig = Figure(marks=lines,
                     axes=[ax, ay],
                     title='Waveform Plotter',
                     animation_duration=50)
        return VBox([slider, fig])
Example #13
0
def feature_vector_distribution(features,
                                label_column,
                                bins=25,
                                group_columns=None,
                                f_lim=None,
                                colors=None):
    """
    features (dataframe): a data frame of feature vectors along with a label column and other metadata
    label_column (str): the name of the column in the features dataframe that refers to the label infomration
    bins (int): the number of bins in the histograms
    group_columns (list): if you want other metadata in the tooltip, these columns will be added
    f_lim (dict): this sets the limits for max and min of the plots to a constant 
        {'max':10, 'min':10}. otherwise defaults to the values of the current features 
        which can be missleading. 
    colors (list): list of colors to use. Internally has a list of 10. If the labels
        are longer you will need to pass your own
    
    """
    dist = unicode("640px")
    third_dist = unicode("213px")

    if f_lim:
        sc_x = LinearScale(min=f_lim['min'], max=f_lim['max'])
        sc_y = LinearScale(min=f_lim['min'], max=f_lim['max'])
    else:
        sc_x = LinearScale()
        sc_y = LinearScale()

    scale_y = LinearScale(min=0)

    x_ord_legend = OrdinalScale()
    y_lin_legend = LinearScale()

    if group_columns is None:
        count_column = features.columns[1]
        group_columns = []
    else:
        count_column = group_columns[0]

    if colors is None:
        colors = [
            "#E6B0AA", "#C39BD3", "#73C6B6", "#F7DC6F", "#F0B27A", "#D0D3D4",
            "#85929E", "#6E2C00", "#1A5276", "#17202A"
        ]
    box_color = 'black'

    feature_x = Dropdown(description='Feature 1')
    feature_y = Dropdown(description='Feature 2')

    feature_x.options = [
        x for x in features.columns if x not in [label_column] + group_columns
    ]
    feature_y.options = [
        x for x in features.columns if x not in [label_column] + group_columns
    ]

    feature1 = feature_x.options[0]
    feature2 = feature_y.options[1]

    tt = Tooltip(fields=['name'],
                 labels=[', '.join(['index', label_column] + group_columns)])

    scatters = []
    hists_y = []
    hists_x = []

    h_bins_x = get_h_bins(features[[feature1]], bins, f_lim)
    h_bins_y = get_h_bins(features[[feature2]], bins, f_lim)

    for index, group in enumerate(features.groupby([label_column])):

        # put the label column and any group column data in the tooltip
        names = []
        for row in range(group[1].shape[0]):
            names.append('{},'.format(row) + ','.join([
                str(x) for x in group[1][[label_column] +
                                         group_columns].iloc[row].values
            ]))

        # create a scatter plot for each group
        scatters.append(
            Scatter(
                x=group[1][feature1].values,
                y=group[1][feature2].values,
                names=names,
                display_names=False,
                default_opacities=[0.5],
                default_size=30,
                scales={
                    'x': sc_x,
                    'y': sc_y
                },
                colors=[colors[index]],
                tooltip=tt,
            ))

        # create a histograms using a bar chart for each group
        # histogram plot for bqplot does not have enough options (no setting range, no setting orientation)
        h_y, h_x = np.histogram(group[1][feature1].values, bins=h_bins_x)
        hists_x.append(
            Bars(x=h_x,
                 y=h_y,
                 opacities=[0.3] * bins,
                 scales={
                     'x': sc_x,
                     'y': scale_y
                 },
                 colors=[colors[index]],
                 orientation='vertical'))

        h_y, h_x = np.histogram(group[1][feature2].values, bins=h_bins_y)
        hists_y.append(
            Bars(x=h_x,
                 y=h_y,
                 opacities=[0.3] * bins,
                 scales={
                     'x': sc_x,
                     'y': scale_y
                 },
                 colors=[colors[index]],
                 orientation='horizontal'))

    # legend will show the names of the labels as well as a total count of each
    legend_bar = Bars(
        x=features.groupby(label_column).count()[count_column].index,
        y=features.groupby(label_column).count()[count_column].values,
        colors=colors,
        opacities=[0.3] * 6,
        scales={
            'x': x_ord_legend,
            'y': y_lin_legend
        },
        orientation='horizontal')

    ax_x_legend = Axis(
        scale=x_ord_legend,
        tick_style={'font-size': 24},
        label='',
        orientation='vertical',
        tick_values=features.groupby(label_column).count()[count_column].index)

    ax_y_legend = Axis(scale=y_lin_legend,
                       orientation='horizontal',
                       label='Total',
                       color=box_color,
                       num_ticks=4)

    #these are blank blank axis that are used to fill in the boarder for the top and right of the figures
    ax_top = Axis(scale=sc_x,
                  color=box_color,
                  side='top',
                  tick_style={'font-size': 0})
    ax_right = Axis(scale=sc_x,
                    color=box_color,
                    side='right',
                    tick_style={'font-size': 0})
    ax_left = Axis(scale=sc_x,
                   color=box_color,
                   side='left',
                   tick_style={'font-size': 0})
    ax_bottom = Axis(scale=sc_x,
                     color=box_color,
                     side='bottom',
                     tick_style={'font-size': 0})

    #scatter plot axis
    ax_x = Axis(label=feature1, scale=sc_x, color=box_color)
    ax_y = Axis(label=feature2,
                scale=sc_y,
                orientation='vertical',
                color=box_color)

    #count column of histogram
    ax_count_vert = Axis(label='',
                         scale=scale_y,
                         orientation='vertical',
                         color=box_color,
                         num_ticks=5)
    ax_count_horiz = Axis(label='',
                          scale=scale_y,
                          orientation='horizontal',
                          color=box_color,
                          num_ticks=5)

    #histogram bin axis
    ax_hist_x = Axis(label='',
                     scale=sc_x,
                     orientation='vertical',
                     color=box_color)
    ax_hist_y = Axis(label='',
                     scale=sc_x,
                     orientation='horizontal',
                     color=box_color)

    #create figures for each plot
    f_scatter = Figure(
        axes=[ax_x, ax_y, ax_top, ax_right],
        background_style={'fill': 'white'},  #css is inserted directly
        marks=scatters,
        min_aspect_ratio=1,
        max_aspect_ratio=1,
        fig_margin={
            "top": 0,
            "bottom": 60,
            "left": 60,
            "right": 0
        },
    )

    f_hists_y = Figure(
        axes=[ax_left, ax_count_horiz, ax_top, ax_right],
        background_style={'fill': 'white'},
        marks=hists_y,
        min_aspect_ratio=.33,
        max_aspect_ratio=.33,
        fig_margin={
            "top": 0,
            "bottom": 60,
            "left": 10,
            "right": 0
        },
    )

    f_hists_x = Figure(
        axes=[ax_count_vert, ax_bottom, ax_top, ax_right],
        background_style={'fill': 'white'},
        marks=hists_x,
        min_aspect_ratio=3,
        max_aspect_ratio=3,
        fig_margin={
            "top": 20,
            "bottom": 10,
            "left": 60,
            "right": 0
        },
    )

    f_legend = Figure(marks=[legend_bar],
                      axes=[ax_x_legend, ax_y_legend],
                      title='',
                      legend_location='bottom-right',
                      background_style={'fill': 'white'},
                      min_aspect_ratio=1,
                      max_aspect_ratio=1,
                      fig_margin={
                          "top": 10,
                          "bottom": 30,
                          "left": 20,
                          "right": 20
                      })

    # we already set the ratios, but it is necessary to set the size explicitly anyway
    # this is kind of cool, inserts this into the style in html
    f_legend.layout.height = third_dist
    f_legend.layout.width = third_dist
    f_hists_x.layout.height = third_dist
    f_hists_x.layout.width = dist
    f_hists_y.layout.height = dist
    f_hists_y.layout.width = third_dist
    f_scatter.layout.height = dist
    f_scatter.layout.width = dist

    # we create some functions that allow changes when the widgets notice an event
    def change_x_feature(b):
        h_bins_x = get_h_bins(features[[feature_x.value]], bins, f_lim)
        for index, group in enumerate(features.groupby([label_column])):
            scatters[index].x = group[1][feature_x.value]
            h_y, h_x = np.histogram(group[1][feature_x.value].values,
                                    bins=h_bins_x)
            hists_x[index].y = h_y

        ax_x.label = feature_x.value

    def change_y_feature(b):
        h_bins_y = get_h_bins(features[[feature_y.value]], bins, f_lim)
        for index, group in enumerate(features.groupby([label_column])):
            scatters[index].y = group[1][feature_y.value]
            h_y, h_x = np.histogram(group[1][feature_y.value].values,
                                    bins=h_bins_y)
            hists_y[index].y = h_y

        ax_y.label = feature_y.value

    # when the user selects a different feature, switch the data plotted
    feature_x.observe(change_x_feature, 'value')
    feature_y.observe(change_y_feature, 'value')

    #return the stacked figures to be plotted
    return VBox([
        HBox([feature_x, feature_y]),
        HBox([f_hists_x, f_legend]),
        HBox([f_scatter, f_hists_y])
    ])