Ejemplo n.º 1
0
    def generate_simulated_drawdown_table(self):
        pp = [50, 30, 20, 10, 5, 1]
        ddp = np.percentile(self.drawdowns, pp)

        pp_formatted = [float(p) / 100. for p in pp]

        source = ColumnDataSource(
            dict(probabilities=pp_formatted, drawdowns=ddp))
        probability_formatter = NumberFormatter(format='0.00')
        drawdown_formatter = NumberFormatter(format='(0.00)%')
        columns = [
            TableColumn(field="probabilities",
                        title="Probabilities",
                        width=70,
                        formatter=probability_formatter),
            TableColumn(field="drawdowns",
                        title="Drawdowns",
                        width=70,
                        formatter=drawdown_formatter)
        ]
        # display(dd_tbl)
        data_table = DataTable(source=source,
                               columns=columns,
                               height=220,
                               row_headers=False)
        return data_table
Ejemplo n.º 2
0
    def _get_columns(self):
        if self.value is None:
            return []

        indexes = self.indexes
        col_names = list(self.value.columns)
        if not self.hierarchical or len(indexes) == 1:
            col_names = indexes + col_names
        else:
            col_names = indexes[-1:] + col_names
        df = self.value.reset_index() if len(indexes) > 1 else self.value
        columns = []
        for col in col_names:
            if col in df.columns:
                data = df[col]
            else:
                data = df.index

            col_kwargs = {}
            kind = data.dtype.kind
            if kind == 'i':
                formatter = NumberFormatter()
                editor = IntEditor()
            elif kind == 'f':
                formatter = NumberFormatter(format='0,0.0[00000]')
                editor = NumberEditor()
            elif isdatetime(data) or kind == 'M':
                formatter = DateFormatter(format='%Y-%m-%d %H:%M:%S')
                editor = DateEditor()
            else:
                formatter = StringFormatter()
                editor = StringEditor()

            if col in self.editors:
                editor = self.editors[col]

            if col in indexes or editor is None:
                editor = CellEditor()

            if col in self.formatters:
                formatter = self.formatters[col]
            if str(col) != col:
                self._renamed_cols[str(col)] = col
            if isinstance(self.widths, int):
                col_kwargs['width'] = self.widths
            elif str(col) in self.widths:
                col_kwargs['width'] = self.widths.get(str(col))

            title = str(col)
            if col in indexes and len(indexes) > 1 and self.hierarchical:
                title = 'Index: %s' % ' | '.join(indexes)
            column = TableColumn(field=str(col),
                                 title=title,
                                 editor=editor,
                                 formatter=formatter,
                                 **col_kwargs)
            columns.append(column)
        return columns
Ejemplo n.º 3
0
def get_default_formatters(
    data: pd.DataFrame,
    int_format: str = INT_FORMAT,
    int_align: str = INT_ALIGN,
    float_format: str = FLOAT_FORMAT,
    float_align: str = FLOAT_ALIGN,
) -> Dict:
    """A dictionary of columns and formats for the the `DataFrame` Panel widget.

    #### Example Use Case

    ```python
    formatters = get_default_formatters(data)
    dataframe_widget = pn.widgets.DataFrame(data, formatters=formatters))
    ```

    ### Notes

    - if the index is 1-dimensional and the name is None we rename to 'index' in order to be able
    to format the index.
    - For the complete formattings specification see [numbrojs](http://numbrojs.com/format.html)

    Args:
        data (pd.DataFrame): A DataFrame of data
        int_format (str, optional): The int format string. Defaults to INT_FORMAT.
        int_align (str, optional): [description]. Defaults to INT_ALIGN.
        float_format (str, optional): [description]. Defaults to FLOAT_FORMAT.
        float_align (str, optional): [description]. Defaults to FLOAT_ALIGN.

    Returns:
        Dict[str,str] -- A dictionary of default formats for the columns
    """
    formatters = {}
    for column in data.columns:
        if data[column].dtype == INT_DTYPE:
            formatters[column] = NumberFormatter(format=int_format, text_align=int_align,)
        elif data[column].dtype == FLOAT_DTYPE:
            formatters[column] = NumberFormatter(format=float_format, text_align=float_align,)

    # Hack: Without a proper name we cannot format the index
    if len(data.index.names) == 1 and not data.index.name:
        data.index.name = "index"

    for (index, name,) in enumerate(data.index.names):
        if name:
            dtype = data.index.get_level_values(index).dtype
            if dtype == INT_DTYPE:
                formatters[name] = NumberFormatter(format=int_format, text_align=int_align,)
            elif dtype == FLOAT_DTYPE:
                formatters[name] = NumberFormatter(format=float_format, text_align=float_align,)

    return formatters
Ejemplo n.º 4
0
    def panel(self):
        result = bootstrap
        price_slider = pn.widgets.RangeSlider.from_param(
            self.param.price_slider, step=10000, format='0.0a')
        result.sidebar.append(price_slider)
        result.sidebar.append(self.param.rooms_slider)
        result.sidebar.append(self.param.bathrooms_slider)
        result.sidebar.append(self.param.type)
        result.sidebar.append(self.param.transit_time)

        image_format = r'<div> <img src="<%= value %>" height="70" alt="<%= value %>" width="70" style="float: left; margin: 0px 15px 15px 0px;" border="2" ></img> </div>'
        tabulator_formatters = {
            'price': NumberFormatter(format='$0,0'),
            'size': NumberFormatter(format='0,0 sqft'),
            'photo': HTMLTemplateFormatter(template=image_format)
        }

        df_widget = pn.widgets.Tabulator(self.filter_df(),
                                         pagination='remote',
                                         page_size=10,
                                         formatters=tabulator_formatters,
                                         sizing_mode='scale_both')
        df_widget.add_filter(self.param.price_slider, 'price')
        df_widget.add_filter(self.param.rooms_slider, 'bedrooms')

        # df_pins = pn.widgets.Tabulator(self.distance_df(), pagination='remote', page_size=10, sizing_mode='scale_both')

        layout = pn.Row(
            pn.Card(pn.bind(self.location,
                            x=self.stream.param.x,
                            y=self.stream.param.y),
                    title="Map",
                    sizing_mode='stretch_height'),
            pn.Column(
                pn.Card(df_widget,
                        title="Properties",
                        sizing_mode='scale_both')))

        result.sidebar.append(
            pn.Card(pn.bind(self.distance_df,
                            x=self.stream.param.x,
                            y=self.stream.param.y),
                    title="Pins",
                    sizing_mode='scale_both'))

        bootstrap.main.append(layout)
        bootstrap.main.append(pn.Card(self.details_area, title='Details'))

        return result
Ejemplo n.º 5
0
    def generate_stationarity_table(self):
        # Test for non-stationarity
        adf_res = adfuller(self.daily_returns)

        # Output tables of stats
        raw_data = dict(
            test_stat=[adf_res[0]],
            p_value=[adf_res[1]],
            conclusion=[
                'non-stationarity = {} @ 5%'.format(
                    'REJECTED' if adf_res[1] < 0.05 else 'NOT REJECTED')
            ])
        source = ColumnDataSource(raw_data)
        number_formatter = NumberFormatter(format='-0.0000')
        columns = [
            TableColumn(field="test_stat",
                        title="ADF Test Statistic",
                        width=150),
            TableColumn(field="p_value",
                        title="p-value",
                        width=80,
                        formatter=number_formatter),
            TableColumn(field="conclusion", title="Conclusion", width=400),
        ]
        data_table = DataTable(source=source,
                               columns=columns,
                               width=650,
                               height=100,
                               row_headers=False)
        return data_table
Ejemplo n.º 6
0
def test_dataframe_formatter(dataframe, document, comm):
    formatter = NumberFormatter(format='0.0000')
    table = DataFrame(dataframe, formatters={'float': formatter})
    model = table.get_root(document, comm)
    model_formatter = model.columns[2].formatter
    assert model_formatter is not formatter
    assert isinstance(model_formatter, NumberFormatter)
    assert model_formatter.format == formatter.format
def table_elements(data, columns):
    """Table describing the contribution of each element"""
    formatters = {
        "weights": NumberFormatter(format="0 %"),
        "element_net_gross": NumberFormatter(format="0 %"),
        "contribution": NumberFormatter(format="0.0"),
    }

    return pn.widgets.Tabulator(
        data.assign(
            weights=lambda df: df.loc[:, "weights"] / 100,
            element_net_gross=lambda df: df.loc[:, "element_net_gross"] / 100,
        ),
        disabled=True,
        titles=columns.as_dict(),
        layout="fit_data_fill",
        formatters=formatters,
        sizing_mode="stretch_width",
    )
Ejemplo n.º 8
0
 def error_summary_stats_table(self):
     from bokeh.models.widgets.tables import NumberFormatter
     data = self.filter_data_rows()
     stats_df = data.describe(
         percentiles=[0.025, 0.2, 0.3, 0.5, 0.7, 0.8, 0.975]).T
     stats_df = stats_df.round(3)
     formatter = NumberFormatter(format='0.000')
     return pn.pane.DataFrame(stats_df,
                              width=1350,
                              formatters={'float': formatter},
                              widths={'index': 300})
Ejemplo n.º 9
0
    def generate_summary_table(self):
        # Output tables of stats
        rows = ['Input data'] + self.fitted_stats.keys()
        means = [np.mean(self.daily_returns)
                 ] + [float(s[0]) for s in self.fitted_stats.values()]
        variances = [np.var(self.daily_returns)
                     ] + [float(s[1]) for s in self.fitted_stats.values()]
        skews = [skew(self.daily_returns)
                 ] + [float(s[2]) for s in self.fitted_stats.values()]
        kurtosises = [kurtosis(self.daily_returns)
                      ] + [float(s[3]) for s in self.fitted_stats.values()]
        raw_data = dict(rows=rows,
                        means=means,
                        variances=variances,
                        skews=skews,
                        kurtosises=kurtosises)

        source = ColumnDataSource(raw_data)
        number_formatter = NumberFormatter(format='-0.0000')
        columns = [
            TableColumn(field="rows", title="", width=200),
            TableColumn(field="means",
                        title="Mean",
                        width=80,
                        formatter=number_formatter),
            TableColumn(field="variances",
                        title="Variance",
                        width=80,
                        formatter=number_formatter),
            TableColumn(field="skews",
                        title="Skewness",
                        width=80,
                        formatter=number_formatter),
            TableColumn(field="kurtosises",
                        title="Kurtosis",
                        width=80,
                        formatter=number_formatter)
        ]
        data_table = DataTable(source=source,
                               columns=columns,
                               width=550,
                               height=150,
                               row_headers=False)
        return data_table
Ejemplo n.º 10
0
 def _data(self, ):
     # data is simple example. In the real world in would depend on among other self.frequency
     data = pd.DataFrame(
         {"int": [
             1,
             2,
             3000,
         ]},
         index=[
             1,
             2,
             3,
         ],
     )
     formatters = {
         "int": NumberFormatter(
             format="0.0",
             text_align="right",
         )
     }
     return pn.widgets.DataFrame(
         data,
         formatters=formatters,
     )
Ejemplo n.º 11
0
    def __init__(self):

        # app variables
        self.active = True
        self.playAnimation = None
        self.start_epoch = None
        self.stop_epoch = None
        self.current_epoch = None

        # get initial configuration
        self.available_models = inspect.getmembers(StandardEphemerisModels,
                                                   inspect.isfunction)
        self.ephemeris_model = self.available_models[0][1]()
        self.spice_provider = SpiceProvider()
        self.spice_provider.SPICE_IDS = self.ephemeris_model.objects
        self.spice_provider.SPICE_NAMES = {
            v: k
            for k, v in self.ephemeris_model.objects.items()
        }

        # init data sources
        self.plot_source = self.spice_provider.state_source
        self.table_source = self.spice_provider.ephemeris_source
        self.cum_source = self.spice_provider.cum_source

        # gather options from ephemeris model and spice provider
        self.allowed_models = {
            model[1]().name: model[1]
            for model in self.available_models
        }
        allowed_objects = [
            self.spice_provider.fromId(name)
            for name in self.ephemeris_model.objects
        ]
        allowed_frames = self.ephemeris_model.FRAMES
        allowed_corrections = [name for name in SpiceProvider.CORRECTIONS]
        allowed_durations = [
            str(v) for v in self.ephemeris_model.DURATION_DAYS
        ]
        allowed_intervals = [name for name in SpiceProvider.INTERVALS]

        # set up widgets
        self.model = Select(title="Ephemeris Model",
                            options=list(self.allowed_models.keys()))

        self.center = Select(title="Center",
                             value=self.ephemeris_model.center,
                             options=allowed_objects)

        self.target = Select(title="Target",
                             value=self.ephemeris_model.target,
                             options=allowed_objects)

        self.frames = Select(title="Frame",
                             value=self.ephemeris_model.frame,
                             options=allowed_frames)

        self.planes = RadioButtonGroup(labels=['XY', 'YZ', 'XZ'], active=0)

        self.vector = Select(title='Vector Type',
                             value=self.ephemeris_model.vector_type,
                             options=allowed_corrections)

        self.epoch = DatePicker(title="Select Epoch",
                                value=datetime.strftime(
                                    self.ephemeris_model.epoch, "%Y-%m-%d"))

        self.offset = Slider(title="Days Since Epoch",
                             value=self.ephemeris_model.offset,
                             start=0,
                             end=self.ephemeris_model.duration,
                             step=1)

        self.duration = Select(title="Duration (Days)",
                               value=str(self.ephemeris_model.duration),
                               options=allowed_durations)

        self.interval = Select(title="Time Step",
                               value=str(self.ephemeris_model.step_size),
                               options=allowed_intervals)

        # create buttons
        self.play_button = Button(label="Play")
        self.exportRange = Div(text="Start and Stop Epoch: ")
        self.update_button = Button(label="Play")
        self.export_button = Button(label="Export")

        self.infoDiv = Div(
            text=
            "<hr>All ephemeris data shown on this website was obtained from publicly available "
            "SPICE files located at <a href='https://naif.jpl.nasa.gov/naif/data.html'>"
            "https://naif.jpl.nasa.gov/naif/data.html</a>, which is hosted by the  "
            "Navigation and Ancillary Information Facility (NAIF) at the NASA Jet Propulsion "
            "Laboratory. The exception is the SPICE kernel for the Parker Solar Probe, which is "
            "available at <a href='https://sppgway.jhuapl.edu/ancil_products'>"
            "https://sppgway.jhuapl.edu/ancil_products</a>, hosted by the Johns Hopkins University "
            "Applied Physics Laboratory. SpiceyPy is being used to process the SPICE files.",
            sizing_mode='stretch_width')

        # create plot tab objects
        self.plot = figure(match_aspect=True,
                           sizing_mode="stretch_both",
                           title="Astropynamics",
                           tools="hover, pan, reset, save",
                           tooltips=[("name", "@index")])

        self.plot.add_tools(BoxZoomTool(match_aspect=True))
        self.plot.circle('px',
                         'py',
                         size='radii',
                         source=self.plot_source,
                         line_width=3,
                         line_alpha=0.5,
                         name='XY')
        self.plot.circle('px',
                         'pz',
                         size='radii',
                         source=self.plot_source,
                         line_width=3,
                         line_alpha=0.5,
                         name='XZ').visible = False
        self.plot.circle('py',
                         'pz',
                         size='radii',
                         source=self.plot_source,
                         line_width=3,
                         line_alpha=0.5,
                         name='YZ').visible = False
        self.plot.line('px',
                       'py',
                       source=self.cum_source,
                       line_width=2,
                       line_alpha=0.5,
                       color='red',
                       name='XYOrbit')
        self.plot.line('px',
                       'pz',
                       source=self.cum_source,
                       line_width=2,
                       line_alpha=0.5,
                       color='red',
                       name='XZOrbit').visible = False
        self.plot.line('py',
                       'pz',
                       source=self.cum_source,
                       line_width=2,
                       line_alpha=0.5,
                       color='red',
                       name='YZOrbit').visible = False

        self.plotLayout = column(self.plot,
                                 self.offset,
                                 sizing_mode="stretch_width")
        self.plotTab = Panel(child=self.plotLayout, title="Display")

        # create data table tab objects
        fmt = NumberFormatter(format='0.000', text_align=TextAlign.right)
        columns = [
            TableColumn(field="index",
                        title="Epoch",
                        formatter=DateFormatter(format="%m/%d/%Y %H:%M:%S")),
            TableColumn(field="px", title="PX", formatter=fmt, width=10),
            TableColumn(field="py", title="PY", formatter=fmt),
            TableColumn(field="pz", title="PZ", formatter=fmt),
            TableColumn(field="vx", title="VX", formatter=fmt),
            TableColumn(field="vy", title="VY", formatter=fmt),
            TableColumn(field="vz", title="VZ", formatter=fmt)
        ]

        self.ephemerisTable = DataTable(source=self.table_source,
                                        columns=columns,
                                        sizing_mode="stretch_both")
        self.ephemerisLayout = column(self.exportRange,
                                      self.ephemerisTable,
                                      sizing_mode="stretch_width")
        self.dataTab = Panel(child=self.ephemerisLayout, title="Table")

        self.kernels = Div()
        self.kernelTab = Panel(child=self.kernels, title="Kernels")

        self.tabs = Tabs(tabs=[self.plotTab, self.dataTab, self.kernelTab])

        # init data
        self.model.value = "The Solar System"
        self.update_model(None, 0, self.model.value)
        self.update_epochs(None, 0, 0)
        self.update_states(None, 0, 0)

        self.model.on_change('value', self.update_model)
        self.frames.on_change('value', self.update_epochs)
        self.planes.on_change('active', self.update_plot_view)
        self.center.on_change('value', self.update_epochs)
        self.target.on_change('value', self.update_epochs)
        self.offset.on_change('value', self.update_offset)
        self.epoch.on_change('value', self.update_epochs)
        self.duration.on_change('value', self.update_epochs)
        self.interval.on_change('value', self.update_epochs)
        self.update_button.on_click(self.update_onclick)
        self.tabs.on_change('active', self.update_button_type)

        self.inputs = column(self.model, self.frames, self.planes, self.center,
                             self.target, self.epoch, self.duration,
                             self.interval, self.update_button)
Ejemplo n.º 12
0
def test_dataframe_formatter(dataframe, document, comm):
    formatter = NumberFormatter(format='0.0000')
    table = DataFrame(dataframe, formatters={'float': formatter})
    model = table.get_root(document, comm)
    assert model.columns[2].formatter is formatter
Ejemplo n.º 13
0
def data_viewer(dataset, tables, columns_per_table, **widget_args):
    """Show all data in a downloadable table"""

    formatters = {
        "ng_vsh40_pct": NumberFormatter(format="0 %"),
        "thickness_mtvd": NumberFormatter(format="0.0"),
        "top_depth_mtvd": NumberFormatter(format="0.0"),
        "base_depth_mtvd": NumberFormatter(format="0.0"),
    }

    def get_filename(table):
        return f"{dataset}-{table}.xlsx"

    def get_data(table_name):
        columns = columns_per_table.get(table_name, {})
        return (readers.read_all(
            config.app.apps.reader, dataset,
            table_name).loc[:, columns.keys()].sort_values(
                by="ng_vsh40_pct", ascending=False).reset_index(drop=True))

    table_name = pn.widgets.Select(
        name="Choose table",
        options={t.title(): t
                 for t in tables},
        value=tables[0],
        size=1,
    )
    filename = pn.widgets.TextInput(name="File name",
                                    value=get_filename(table_name.value))

    @pn.depends(table_name.param.value)
    def table(table_name):
        data = get_data(table_name).assign(
            ng_vsh40_pct=lambda d: d.ng_vsh40_pct / 100  # Show N:G as percent
        )

        return pn.widgets.Tabulator(
            data,
            disabled=True,
            titles=columns_per_table[table_name],
            formatters=formatters,
            layout="fit_data_table",
            **widget_args,
        )

    @pn.depends(table_name.param.value, watch=True)
    def update_filename(table_name):
        filename.value = get_filename(table_name)

    def download_file():
        """Download data as an Excel file"""
        output_bytes = io.BytesIO()

        # Write data as Excel
        excel_writer = pd.ExcelWriter(output_bytes, engine="xlsxwriter")
        get_data(table_name.value).to_excel(
            excel_writer, sheet_name=table_name.value.title(), index=False)
        excel_writer.save()

        # Reset output stream and return it
        output_bytes.seek(0)
        return output_bytes

    @pn.depends(filename.param.value)
    def download_button(filename):
        return pn.widgets.FileDownload(callback=download_file,
                                       filename=filename,
                                       button_type="success")

    return pn.Row(
        pn.Column(
            table_name,
            filename,
            download_button,
        ),
        pn.Column(table, sizing_mode="stretch_width"),
    )
Ejemplo n.º 14
0
    def __init__(self, model):
        """
        Construct separation dashboard
        """
        # Save reference to model
        self.model = model

        ################################
        # Process button
        ################################

        self.process = Button(label="Generate",
                              button_type="primary",
                              name='process',
                              sizing_mode='scale_width',
                              css_classes=['generate'])
        self.process.js_on_click(CustomJS(code="toggleLoading()"))

        ################################
        # Widgets
        ################################

        # Data type selection
        self.data_type = RadioButtonGroup(
            labels=["All Data", "Experimental", "Simulated"],
            active=0,
            css_classes=['dtypes'])

        # Adsorbate drop-down selections
        self.g1_sel = Select(title="Adsorbate 1",
                             options=self.model.ads_list,
                             value=self.model.g1,
                             css_classes=['g-selectors'])
        self.g2_sel = Select(title="Adsorbate 2",
                             options=self.model.ads_list,
                             value=self.model.g2)

        # Temperature selection
        self.t_absolute = Spinner(value=self.model.t_abs,
                                  title='Temperature:',
                                  css_classes=['t-abs'])
        self.t_tolerance = Spinner(value=self.model.t_tol,
                                   title='Tolerance:',
                                   css_classes=['t-tol'])

        # Combined in a layout
        self.dsel_widgets = layout([
            [self.data_type],
            [self.g1_sel, self.g2_sel, self.t_absolute, self.t_tolerance],
        ],
                                   sizing_mode='scale_width',
                                   name="widgets")

        ################################
        # KPI Plots
        ################################

        # Top graph generation
        tooltip = load_tooltip()
        self.p_henry, rend1 = self.top_graph("K", "Henry coefficient (log)",
                                             self.model.data,
                                             self.model.errors, tooltip)
        self.p_loading, rend2 = self.top_graph(
            "L", "Uptake at selected pressure (bar)", self.model.data,
            self.model.errors, tooltip)
        self.p_wc, rend3 = self.top_graph(
            "W", "Working capacity in selected range (bar)", self.model.data,
            self.model.errors, tooltip)

        # Give graphs the same hover and select effect
        sel = Circle(fill_alpha=1, fill_color="red", line_color=None)
        nonsel = Circle(fill_alpha=0.2, fill_color="blue", line_color=None)
        for rend in [rend1, rend2, rend3]:
            rend.selection_glyph = sel
            rend.nonselection_glyph = nonsel
            rend.hover_glyph = sel

        # Pressure slider
        self.p_slider = Slider(
            title="Pressure (bar)",
            value=0.5,
            start=0,
            end=20,
            step=0.5,
            callback_policy='throttle',
            callback_throttle=200,
        )

        # Working capacity slider
        self.wc_slider = RangeSlider(
            title="Working capacity (bar)",
            value=(0.5, 5),
            start=0,
            end=20,
            step=0.5,
            callback_policy='throttle',
            callback_throttle=200,
        )

        # Material datatable
        self.mat_list = DataTable(
            columns=[
                TableColumn(field="labels", title="Material", width=300),
                TableColumn(field="sel",
                            title="KH2/KH1",
                            width=35,
                            formatter=NumberFormatter(format='‘0.0a’')),
                TableColumn(field="psa_W",
                            title="PSA-API",
                            width=35,
                            formatter=NumberFormatter(format='‘0.0a’')),
            ],
            source=self.model.data,
            index_position=None,
            selectable='checkbox',
            scroll_to_selection=True,
            width=400,
            fit_columns=True,
        )

        # Custom css classes for interactors
        self.p_henry.css_classes = ['g-henry']
        self.p_loading.css_classes = ['g-load']
        self.p_wc.css_classes = ['g-wcap']
        self.mat_list.css_classes = ['t-details']

        # Generate the axis labels
        self.top_graph_labels()

        self.kpi_plots = layout([
            [
                gridplot([[self.mat_list, self.p_henry],
                          [self.p_loading, self.p_wc]],
                         sizing_mode='scale_width')
            ],
            [self.p_slider, self.wc_slider],
        ],
                                sizing_mode='scale_width',
                                name="kpiplots")
        self.kpi_plots.children[0].css_classes = ['kpi']
        self.kpi_plots.children[1].css_classes = ['p-selectors']

        ################################
        # Isotherm details explorer
        ################################

        # Isotherm display graphs
        self.p_g1iso = self.bottom_graph(self.model.g1_iso_sel, self.model.g1)
        self.p_g2iso = self.bottom_graph(self.model.g2_iso_sel, self.model.g2)

        # Isotherm display palette
        self.c_cyc = cycle(gen_palette(20))

        self.detail_plots = layout([
            [self.p_g1iso, self.p_g2iso],
        ],
                                   sizing_mode='scale_width',
                                   name="detailplots")
        self.detail_plots.children[0].css_classes = ['isotherms']
Ejemplo n.º 15
0
df = pd.DataFrame(
    {
        "int": [1, 2, 3],
        "float": [3.14, 6.28, 9.42],
        "str": ["A", "B", "C"],
        "bool": [True, False, True],
        "date":
        [dt.date(2019, 1, 1),
         dt.date(2020, 1, 1),
         dt.date(2020, 1, 10)],
    },
    index=[1, 2, 3],
)

bokeh_formatters = {
    "float": NumberFormatter(format="0.00"),
    "bool": BooleanFormatter(),
}

theme = TABULATOR_THEME.get(template.theme, "site")
df_widget = pn.widgets.Tabulator(df,
                                 formatters=bokeh_formatters,
                                 theme=theme,
                                 sizing_mode="stretch_both")
df_widget._configuration["layout"] = "fitDataFill"
df_widget._configuration["responsiveLayout"] = "collapse"
df_widget._configuration["columns"] = [
    {
        "int": "Name",
        "field": "name",
        "responsive": 0
Ejemplo n.º 16
0
    def _get_column_definitions(self, col_names, df):
        import pandas as pd
        indexes = self.indexes
        columns = []
        for col in col_names:
            if col in df.columns:
                data = df[col]
            else:
                data = df.index

            if isinstance(data, pd.DataFrame):
                raise ValueError("DataFrame contains duplicate column names.")

            col_kwargs = {}
            kind = data.dtype.kind
            if kind == 'i':
                formatter = NumberFormatter()
                editor = IntEditor()
            elif kind == 'b':
                formatter = StringFormatter()
                editor = CheckboxEditor()
            elif kind == 'f':
                formatter = NumberFormatter(format='0,0.0[00000]')
                editor = NumberEditor()
            elif isdatetime(data) or kind == 'M':
                if len(data) and isinstance(data.values[0], dt.date):
                    date_format = '%Y-%m-%d'
                else:
                    date_format = '%Y-%m-%d %H:%M:%S'
                formatter = DateFormatter(format=date_format)
                editor = DateEditor()
            else:
                formatter = StringFormatter()
                editor = StringEditor()

            if col in self.editors and not isinstance(self.editors[col],
                                                      (dict, str)):
                editor = self.editors[col]

            if col in indexes or editor is None:
                editor = CellEditor()

            if col in self.formatters and not isinstance(
                    self.formatters[col], (dict, str)):
                formatter = self.formatters[col]

            if str(col) != col:
                self._renamed_cols[str(col)] = col

            if isinstance(self.widths, int):
                col_kwargs['width'] = self.widths
            elif str(col) in self.widths:
                col_kwargs['width'] = self.widths.get(str(col))

            title = self.titles.get(col, str(col))
            if col in indexes and len(indexes) > 1 and self.hierarchical:
                title = 'Index: %s' % ' | '.join(indexes)
            column = TableColumn(field=str(col),
                                 title=title,
                                 editor=editor,
                                 formatter=formatter,
                                 **col_kwargs)
            columns.append(column)
        return columns
Ejemplo n.º 17
0
    def create_ui(self, data):
        self.logger.info("number of data items %d", len(data))

        # Create data source and data table
        # path, score, software_id, featcnt, featfreq, app name, app path, decision, status, comment, active in play, still voilating
        decision_editor = SelectEditor(options=[
            "Unprocessed", "GPL Violation", "LGPL Violation",
            "Open Source App", "False Positive", "False Negative (LGPL)",
            "False Negative (GPL)"
        ])
        status_editor = SelectEditor(options=[
            "Unprocessed", "Emailed", "Confirmed", "Denied", "Authorized"
        ])
        if self.app_info:
            columns = [
                TableColumn(field="myindex", title="Id"),
                TableColumn(field="path", title="File Path"),
                TableColumn(field="score", title="Score"),
                TableColumn(field="normscore",
                            title="NormScore",
                            formatter=NumberFormatter(format="0.00")),
                TableColumn(field="partial", title="PartialMatch"),
                TableColumn(field="repo_id", title="Repo ID"),
                TableColumn(field="software_name", title="OSS"),
                TableColumn(field="version", title="Version"),
                TableColumn(
                    field="featcnt",
                    title="FeatCount",
                ),
                TableColumn(
                    field="featfreq",
                    title="FeatFreq",
                ),
                TableColumn(field="package_name", title="Package"),
                TableColumn(field="app_path", title="App Path"),
                TableColumn(field="app_count", title="App Count"),
                TableColumn(field="decision",
                            title="Decision",
                            editor=decision_editor),
                TableColumn(field="status",
                            title="Status",
                            editor=status_editor),
                TableColumn(field="comment", title="Comment"),
                # I am not sure whether we should add these two fields here.
                # TableColumn(field="active", title="Active in Play"),
                # TableColumn(field="still_violating", title="Still Violating"),
            ]
        else:
            template_str = '<a href="' + self.REPO_URL + '/<%= value %>"><%= value %></a>'
            columns = [
                TableColumn(
                    field="myindex",
                    title="Id",
                ),
                TableColumn(field="name", title="Name"),
                TableColumn(field="score",
                            title="Score",
                            formatter=NumberFormatter(format="0.00")),
                TableColumn(field="normscore",
                            title="NormScore",
                            formatter=NumberFormatter(format="0.00")),
                TableColumn(field="partial", title="PartialMatch"),
                TableColumn(field="repo_id", title="RepoID"),
                TableColumn(
                    field="software_name",
                    title="OSS",
                    formatter=HTMLTemplateFormatter(template=template_str)),
                TableColumn(field="featcnt",
                            title="FeatCount",
                            formatter=NumberFormatter(format="0,000,000")),
                TableColumn(field="featfreq",
                            title="FeatFreq",
                            formatter=NumberFormatter(format="0,000,000")),
                TableColumn(field="version", title="Version"),
                TableColumn(field="decision",
                            title="Decision",
                            editor=decision_editor),
                TableColumn(field="status",
                            title="Status",
                            editor=status_editor),
                TableColumn(field="comment", title="Comment"),
                TableColumn(field="path", title="Path"),
            ]

        # source is the displayed table, and can be modified by user
        # original_source is the original data, it is the base, and can only be modified by the program
        self.source = ColumnDataSource(self._data)
        self.original_source = ColumnDataSource(self._data)
        self.data_table = DataTable(source=self.source,
                                    columns=columns,
                                    width=2000,
                                    height=2000,
                                    editable=True,
                                    sortable=True)  # Disable sortable for now!

        # selector or filters
        # reference link for callback: https://gist.github.com/dennisobrien/450d7da20daaba6d39d0
        min_matching_score_slider = Slider(start=0,
                                           end=2,
                                           value=0.3,
                                           step=.01,
                                           title="Minimum Matching Score")
        max_matching_score_slider = Slider(start=0,
                                           end=2,
                                           value=0.7,
                                           step=.01,
                                           title="Maximum Matching Score")
        featfreq_slider = Slider(start=0,
                                 end=10000,
                                 value=0,
                                 step=1,
                                 title="Minimum Matching Num of Features")
        featcnt_slider = Slider(start=0,
                                end=10000,
                                value=50,
                                step=1,
                                title="Minimum Feature Count is OSS")
        kind_select = Select(value="All", options=["All", "Java", "Native"])
        file_select = Select(value="Name", options=["Name", "MD5", "Path"])
        search_input = TextInput(value=None,
                                 title="Enter library to search",
                                 callback=None)
        search_button = Button(label="Search", button_type="success")

        download_callback_code = """
        var data = source.get('data');
        var filetext = 'Id,File Name,Matching Score,Normalized Matching Score,Repo ID,Software Name,Feature Count,Feature Freq.,Version,Decision,Status,Comment,File Path\\n';

        var order = ['myindex', 'name', 'score', 'normscore', 'repo_id', 'software_name', 'featcnt', 'featfreq', 'version', 'decision', 'status', 'comment', 'path'];

        for (var i = 0; i < data['path'].length; ++i) {
            var currRow = [];
            for (var item in order) {
                key = order[item]
                currRow.push(data[key][i]);
            }
            var joined = currRow.join().concat('\\n');
            filetext = filetext.concat(joined);
        }

        var filename = 'violations.csv';
        var blob = new Blob([filetext], { type: 'text/csv;charset=utf-8;' });
        
        //addresses IE
        if (navigator.msSaveBlob) {
            //navigator.msSaveBlob(blob, filename);
        }
        else {
            var link = document.createElement("a");
            link = document.createElement('a');
            link.href = URL.createObjectURL(blob);
            link.download = filename;
            link.target = "_blank";
            link.style.visibility = 'hidden';
            link.dispatchEvent(new MouseEvent('click'));
        }
        """

        # enable downloading of results as a csv file
        download_button = Button(label="Download", button_type="success")
        download_button.callback = CustomJS(args=dict(source=self.source),
                                            code=download_callback_code)

        # enable comparison of selected rows
        compare_button = Button(label="Compare", button_type="success")
        compare_button.on_click(self.compare_callback)

        # update on change
        #controls = [min_matching_score_slider, max_matching_score_slider, featfreq_slider, \
        #            featcnt_slider, kind_select, file_select, button]
        #for item in controls:
        #    item.on_change('value', lambda attr, old, new: self.update_source(item))

        combined_callback_code = """
        var data = source.get('data');
        var original_data = original_source.get('data');
        var min_score = min_matching_score_slider.get('value');
        var max_score = max_matching_score_slider.get('value');
        var search_input = search_input.get('value');
        var min_featfreq = featfreq_slider.get('value');
        var min_featcnt = featcnt_slider.get('value');
        var kind = kind_select.get('value');
        console.log("min score: " + min_score + ", max score: " + max_score + ", min_featfreq: " + min_featfreq + ", min_featcnt" + min_featcnt + ", kind" + kind);
        var java_suffix = ".dex";
        var native_suffix = ".so";

        console.log("searchinput: " + search_input);
        var re;
        if (search_input) {
            re = new RegExp(search_input);
        } else {
            re = new RegExp(".*");
        }

        for (var key in original_data) {
            data[key] = [];
            for (var i = 0; i < original_data['path'].length; ++i) {
                if ((original_data['normscore'][i] >= min_score) && (original_data['normscore'][i] <= max_score) && (original_data['featfreq'][i] >= min_featfreq) &&
                    (original_data['featcnt'][i] >= min_featcnt)) {
                    // filter by java
                    if (kind == "Java" && original_data['path'][i].indexOf(java_suffix, original_data['path'][i].length - java_suffix.length) === -1)
                        continue;
                    // filter by native
                    if (kind == "Native" && original_data['path'][i].indexOf(native_suffix, original_data['path'][i].length - native_suffix.length) === -1)
                        continue;
                    // filter by search regex
                    if (!re.test(original_data['name'][i])) {
                        console.log("mismatch: " + original_data['name'][i]);
                        continue;
                    }
                    // this row is the expected kind
                    data[key].push(original_data[key][i]);
                }
            }
        }
        source.trigger('change');
        target.trigger('change');
        """
        generic_callback = CustomJS(args=dict(
            source=self.source,
            original_source=self.original_source,
            search_input=search_input,
            max_matching_score_slider=max_matching_score_slider,
            min_matching_score_slider=min_matching_score_slider,
            featfreq_slider=featfreq_slider,
            featcnt_slider=featcnt_slider,
            kind_select=kind_select,
            target=self.data_table),
                                    code=combined_callback_code)
        min_matching_score_slider.callback = generic_callback
        max_matching_score_slider.callback = generic_callback
        featfreq_slider.callback = generic_callback
        featcnt_slider.callback = generic_callback
        search_button.callback = generic_callback
        kind_select.callback = generic_callback

        # install callback when a row gets selected
        self.source.on_change('selected', self.selected_callback)

        ###########################################################
        # Main
        ###########################################################
        controls = [min_matching_score_slider, max_matching_score_slider, featfreq_slider, \
                    featcnt_slider, kind_select, file_select, search_input, search_button, \
                    download_button, compare_button]
        plots_box = widgetbox(*controls, width=800, sizing_mode="fixed")
        layout = column(plots_box, self.data_table, sizing_mode="fixed")

        return layout