Esempio n. 1
0
    def generate_graph(self):
        """
        Generate the graph; return a 2-tuple of strings, script to place in the
        head of the HTML document and div content for the graph itself.

        :return: 2-tuple (script, div)
        :rtype: tuple
        """
        logger.debug('Generating graph for %s', self._graph_id)
        # tools to use
        tools = [
            PanTool(),
            BoxZoomTool(),
            WheelZoomTool(),
            SaveTool(),
            ResetTool(),
            ResizeTool()
        ]

        # generate the stacked area graph
        try:
            g = Area(
                self._data, x='Date', y=self._y_series_names,
                title=self._title, stack=True, xlabel='Date',
                ylabel='Downloads', tools=tools,
                # note the width and height will be set by JavaScript
                plot_height=400, plot_width=800,
                toolbar_location='above', legend=False
            )
        except Exception as ex:
            logger.error("Error generating %s graph", self._graph_id)
            logger.error("Data: %s", self._data)
            logger.error("y=%s", self._y_series_names)
            raise ex

        lines = []
        legend_parts = []
        # add a line at the top of each Patch (stacked area) for hovertool
        for renderer in g.select(GlyphRenderer):
            if not isinstance(renderer.glyph, Patches):
                continue
            series_name = renderer.data_source.data['series'][0]
            logger.debug('Adding line for Patches %s (series: %s)', renderer,
                         series_name)
            line = self._line_for_patches(self._data, g, renderer, series_name)
            if line is not None:
                lines.append(line)
                legend_parts.append((series_name, [line]))

        # add the Hovertool, specifying only our line glyphs
        g.add_tools(
            HoverTool(
                tooltips=[
                    (self._y_name, '@SeriesName'),
                    ('Date', '@FmtDate'),
                    ('Downloads', '@Downloads'),
                ],
                renderers=lines,
                line_policy='nearest'
            )
        )

        # legend outside chart area
        legend = Legend(legends=legend_parts, location=(0, 0))
        g.add_layout(legend, 'right')
        return components(g)
Esempio n. 2
0
# 4

# 5
tkr_sel = ['BTC', 'ETH']
mcafr_vcc_mat = mca_vcc_mat.div(mca_vcc_mat.sum(1), axis=0)
mcafr_vcc_mat.columns
mcafr_vcc_mat_mthly = mcafr_vcc_mat.resample('MS').first()
mcafr_vcc_mat_mthly[tkr_sel].isnull().sum()
p4 = Area(mcafr_vcc_mat_mthly.loc['2016':, tkr_sel],
          stack=True, color=['Orange','Green'])
#p4.line(mcafr_vcc_mat_mthly.loc['2016':,'BLX'].index,
#        mcafr_vcc_mat_mthly.loc['2016':,'BLX'])

hover = HoverTool(tooltips=[('BTC', '@BTC'),
                            ('ETH', '@ETH')])
p4.add_tools(hover)
output_file('output/bokeh/mcafr2.html', mode='cdn')
show(p4)

# test
test = pd.DataFrame({'col1': [1, 2], 'col2': [3, 4]})
p6 = Area(test, stack=True)
output_file('output/bokeh/p6.html', mode='cdn')
show(p6)

### bokeh server

# Perform necessary imports
from bokeh.io import curdoc
from bokeh.layouts import widgetbox
from bokeh.models import Slider
    def _plot_public_data_statistics(self, all_data, version_attr_name,
                                     title_name, label_cb):
        """
        generic method to plot flight hours one data type
        :param all_data: list with all types as string
        :param version_attr_name: attribute name of _VersionData
        :param title_name: name of the data for the title (and hover tool)
        :param label_cb: callback to create the label
        :return: bokeh plot
        """

        # change data structure
        data_hours = {}  # key=data id, value=list of hours for each version
        for d in all_data:
            data_hours[d] = []

        versions = []  # sorted list of all versions
        for ver in sorted(self._version_data,
                          key=functools.cmp_to_key(_Log.compare_version)):
            versions.append(ver)

            # all data points of the requested type for this version
            version_type_data = getattr(self._version_data[ver],
                                        version_attr_name)

            for d in all_data:
                if not d in version_type_data:
                    version_type_data[d] = 0.
                data_hours[d].append(version_type_data[d])

        # cumulative over each version
        for key in all_data:
            data_hours[key] = np.array(data_hours[key])
            data_hours[key + "_cum"] = np.cumsum(data_hours[key])

        # create a 2D numpy array. We could directly pass the dict to the bokeh
        # plot, but then we don't have control over the sorting order
        X = np.zeros((len(all_data), len(versions)))
        i = 0
        all_data_sorted = []
        for key in sorted(
                all_data,
                key=lambda data_key: data_hours[data_key + "_cum"][-1]):
            X[i, :] = data_hours[key + "_cum"]
            all_data_sorted.append(key)
            i += 1
        all_data = all_data_sorted

        colors = viridis(len(all_data))
        # alternative: use patches: http://bokeh.pydata.org/en/latest/docs/gallery/brewer.html
        area = Area(X,
                    title="Flight Hours per " + title_name,
                    tools=TOOLS,
                    active_scroll=ACTIVE_SCROLL_TOOLS,
                    stack=True,
                    xlabel='version (including development states)',
                    ylabel='',
                    color=colors)

        # now set the labels
        for i in range(len(all_data)):
            area.legend[0].items[i].label = props.value(
                label_cb(all_data[i], False))
        area.legend[0].items.reverse()

        # stack the data: we'll need it for the hover tool
        last = np.zeros(len(versions))
        for i in range(len(all_data)):
            last = last + X[i, :]
            data_hours[all_data[i] + '_stacked'] = last
        data_hours['x'] = np.arange(len(versions))

        # hover tool
        source = ColumnDataSource(data=data_hours)
        for d in all_data:
            renderer = area.circle(x='x',
                                   y=d + '_stacked',
                                   source=source,
                                   size=10,
                                   alpha=0,
                                   name=d)
            g1_hover = HoverTool(renderers=[renderer],
                                 tooltips=[
                                     (title_name, label_cb(d, True)),
                                     ('Flight hours (only this version)',
                                      '@' + d + '{0,0.0}'),
                                     ('Flight hours (up to this version)',
                                      '@' + d + '_cum{0,0.0}')
                                 ])
            area.add_tools(g1_hover)

        # TODO: space x-axis entries according to version release date?
        area.xaxis.formatter = FuncTickFormatter(code="""
            var versions = """ + str(versions) + """;
            return versions[Math.floor(tick)]
        """)
        area.xaxis.ticker = FixedTicker(ticks=list(range(len(versions))))
        self._setup_plot(area)
        return area