Here are the examples of the python api bokeh.layouts.column taken from open source projects. By voting up you can indicate which examples are most useful and appropriate.
155 Examples
3
View Source File : utils.py
License : MIT License
Project Creator : allenbai01
License : MIT License
Project Creator : allenbai01
def save(self, title='Training Results'):
if len(self.figures) > 0:
if os.path.isfile(self.plot_path):
os.remove(self.plot_path)
output_file(self.plot_path, title=title)
plot = column(*self.figures)
save(plot)
self.figures = []
self.results.to_csv(self.path, index=False, index_label=False)
def load(self, path=None):
3
View Source File : utils.py
License : MIT License
Project Creator : allenbai01
License : MIT License
Project Creator : allenbai01
def show(self):
if len(self.figures) > 0:
plot = column(*self.figures)
show(plot)
#def plot(self, *kargs, **kwargs):
# line = Line(data=self.results, *kargs, **kwargs)
# self.figures.append(line)
def image(self, *kargs, **kwargs):
3
View Source File : trending_delta4.py
License : MIT License
Project Creator : cutright
License : MIT License
Project Creator : cutright
def __do_layout(self):
# TODO: Generalize for 1 or 2 groups
self.layout = column(row(self.select_y, self.select_linac[1], self.select_linac[2], self.avg_len_input,
self.percentile_input, self.bins_input),
row(self.select_energies[1], self.select_energies[2]),
row(self.start_date_picker, self.end_date_picker),
row(Div(text='Gamma Criteria: '), self.checkbox_button_group),
self.div_summary[1],
self.div_summary[2],
row(Spacer(width=10), self.fig),
Spacer(height=50),
row(Spacer(width=10), self.histogram),
Spacer(height=50),
row(Spacer(width=10), self.ichart),
row(self.div_center_line[1], self.div_ucl[1], self.div_lcl[1]),
row(self.div_center_line[2], self.div_ucl[2], self.div_lcl[2]))
def update_source_ticker(self, attr, old, new):
3
View Source File : log.py
License : Apache License 2.0
Project Creator : Drajan
License : Apache License 2.0
Project Creator : Drajan
def show(self, title=None):
title = title or self.title
if len(self.figures) > 0:
plot = column(
Div(text=' < h1 align="center">{} < /h1>'.format(title)), *self.figures)
show(plot)
def plot(self, *kargs, **kwargs):
3
View Source File : figures.py
License : GNU General Public License v3.0
Project Creator : gotzl
License : GNU General Public License v3.0
Project Creator : gotzl
def getTrackMapPanel(df):
mode_select = Select(title="Mode:", value='speed',
options=['oversteer',
'speed',
'pedals',
'throttle',
'brake',
'g_lon'])
layout = column(mode_select, getTrackMap(df, view='trackmap'))
def mode_change(attrname, old, new):
layout.children[1] = getTrackMap(df, view='trackmap', mode=new)
mode_select.on_change('value', mode_change)
return layout
3
View Source File : analyzer.py
License : GNU General Public License v3.0
Project Creator : happydasch
License : GNU General Public License v3.0
Project Creator : happydasch
def _get_analyzer_info(self):
tablegen = AnalysisTableGenerator(self._app.scheme)
acolumns = []
for analyzer in self._figurepage.analyzers:
table_header, elements = tablegen.get_tables(analyzer)
if table_header and elements:
acolumns.append(column([table_header] + elements))
info = gridplot(
acolumns,
ncols=self._app.scheme.analyzer_tab_num_cols,
sizing_mode='stretch_width',
toolbar_options={'logo': None})
return info
def _on_update_analyzer_info(self):
3
View Source File : config.py
License : GNU General Public License v3.0
Project Creator : happydasch
License : GNU General Public License v3.0
Project Creator : happydasch
def _create_fill_gaps_config(self):
title = Paragraph(
text='Fill Gaps',
css_classes=['config-title'])
if self._client.fill_gaps:
active = [0]
else:
active = []
self.chk_fill_gaps = CheckboxGroup(
labels=['Fill gaps with data'],
active=active)
return column([title, self.chk_fill_gaps], sizing_mode='stretch_width')
def _apply_fill_gaps_config(self):
3
View Source File : config.py
License : GNU General Public License v3.0
Project Creator : happydasch
License : GNU General Public License v3.0
Project Creator : happydasch
def _create_lookback_config(self):
title = Paragraph(
text='Lookback period',
css_classes=['config-title'])
self.sld_lookback = Slider(
title='Period for data to plot',
value=self._client.lookback,
start=1, end=200, step=1)
return column([title, self.sld_lookback], sizing_mode='stretch_width')
def _apply_lookback_config(self):
3
View Source File : metadata.py
License : GNU General Public License v3.0
Project Creator : happydasch
License : GNU General Public License v3.0
Project Creator : happydasch
def _get_strategy(self, strategy):
columns = []
childs = []
childs.append(self._get_title(f'Strategy: {obj2label(strategy)}'))
childs.append(self._get_parameter_table(strategy.params))
for o in strategy.observers:
childs.append(self._get_title(f'Observer: {obj2label(o)}'))
childs.append(self._get_parameter_table(o.params))
for a in strategy.analyzers:
childs.append(self._get_title(f'Analyzer: {obj2label(a)}{" [Analysis Table]" if hasattr(a, "get_analysis_table") else ""}'))
childs.append(self._get_parameter_table(a.params))
columns.append(column(childs))
return columns
def _get_indicators(self, strategy):
3
View Source File : metadata.py
License : GNU General Public License v3.0
Project Creator : happydasch
License : GNU General Public License v3.0
Project Creator : happydasch
def _get_indicators(self, strategy):
columns = []
childs = []
inds = strategy.getindicators()
for i in inds:
if isinstance(i, bt.IndicatorBase):
childs.append(self._get_title(
f'Indicator: {obj2label(i)}@{obj2data(i)}'))
childs.append(self._get_parameter_table(i.params))
columns.append(column(childs))
return columns
def _get_datas(self, strategy):
3
View Source File : source.py
License : GNU General Public License v3.0
Project Creator : happydasch
License : GNU General Public License v3.0
Project Creator : happydasch
def _get_panel(self):
title = Paragraph(
text='Source Code',
css_classes=['panel-title'])
child = column(
[title,
Div(text=self._getSource(),
css_classes=['source-pre'],
sizing_mode='stretch_width')],
sizing_mode='stretch_width')
return child, 'Source Code'
3
View Source File : edit.py
License : GNU General Public License v3.0
Project Creator : j-brady
License : GNU General Public License v3.0
Project Creator : j-brady
def init(self, doc):
""" initialise the bokeh app """
doc.add_root(
column(
self.intro_div,
row(column(self.p, self.doc_link), column(self.data_table, self.tabs)),
sizing_mode="stretch_both",
)
)
doc.title = "peakipy: Edit Fits"
@property
3
View Source File : _comparison.py
License : MIT License
Project Creator : metriculous-ml
License : MIT License
Project Creator : metriculous-ml
def _html_figure_table(
model_evaluations: Sequence[Evaluation], include_spacer: Optional[bool]
) -> str:
html_output = ""
rows = _figure_rows(model_evaluations, include_spacer=include_spacer)
if rows:
html_output += file_html(
models=column(rows, sizing_mode="scale_width"),
resources=CDN,
title="Comparison",
)
return html_output
def _figure_rows(
3
View Source File : uibokeh_well.py
License : Apache License 2.0
Project Creator : OpendTect
License : Apache License 2.0
Project Creator : OpendTect
def display(self):
if self.withui:
self.tracklayout = bl.column(self.track)
tracktab = bm.Panel(child=self.tracklayout, title="Plot")
datatab = bm.Panel(child=self.data_ui, title="Data")
settingstab = bm.Panel(child=self.settings_ui, title="Settings")
self.tabs = bm.Tabs(tabs=[datatab, tracktab, settingstab])
self.tabs.on_change('active', self._change_tab)
return self.tabs
else:
return self.track
def _getLogLimits(self, lognm):
3
View Source File : geoplot.py
License : MIT License
Project Creator : PatrikHlobil
License : MIT License
Project Creator : PatrikHlobil
def _get_figure(col):
"""Gets the bokeh.plotting.figure from a bokeh.layouts.column."""
from bokeh.layouts import column
from bokeh.plotting import figure
for children in col.children:
if isinstance(children, type(figure())):
return children
elif isinstance(children, type(column())):
return _get_figure(children)
def convert_geoDataFrame_to_patches(gdf, geometry_column):
3
View Source File : base.py
License : MIT License
Project Creator : phurwicz
License : MIT License
Project Creator : phurwicz
def view(self):
"""
???+ note "Define the high-level visual layout of the whole explorer."
"""
from bokeh.layouts import column
return column(self._layout_widgets(), self.figure)
def _build_tooltip(self, extra):
3
View Source File : specialization.py
License : MIT License
Project Creator : phurwicz
License : MIT License
Project Creator : phurwicz
def _layout_widgets(self):
"""Define the layout of widgets."""
layout_rows = (
row(self.subset_toggle_widget_column, self.selection_option_box),
row(
column(self.search_pos, self.search_neg),
column(self.search_filter_box),
),
row(self.dropdown_x_axis, self.dropdown_y_axis),
row(*self._dynamic_widgets.values()),
)
return column(*layout_rows)
class BokehTextAnnotator(BokehDataAnnotator, BokehForText):
3
View Source File : specialization.py
License : MIT License
Project Creator : phurwicz
License : MIT License
Project Creator : phurwicz
def _layout_widgets(self):
"""Define the layout of widgets."""
layout_rows = (
row(self.subset_toggle_widget_column, self.selection_option_box),
row(self.search_pos, self.search_neg),
row(self.annotator_input, self.annotator_apply),
row(self.dropdown_x_axis, self.dropdown_y_axis),
row(*self._dynamic_widgets.values()),
)
return column(*layout_rows)
class BokehTextSoftLabel(BokehSoftLabelExplorer, BokehForText):
3
View Source File : specialization.py
License : MIT License
Project Creator : phurwicz
License : MIT License
Project Creator : phurwicz
def _layout_widgets(self):
"""Define the layout of widgets."""
layout_rows = (
row(self.subset_toggle_widget_column, self.selection_option_box),
row(self.search_pos, self.search_neg),
row(self.score_filter),
row(self.dropdown_x_axis, self.dropdown_y_axis),
row(*self._dynamic_widgets.values()),
)
return column(*layout_rows)
class BokehTextMargin(BokehMarginExplorer, BokehForText):
3
View Source File : specialization.py
License : MIT License
Project Creator : phurwicz
License : MIT License
Project Creator : phurwicz
def _layout_widgets(self):
"""Define the layout of widgets."""
layout_rows = (
row(self.subset_toggle_widget_column, self.selection_option_box),
row(self.search_pos, self.search_neg),
row(self.dropdown_x_axis, self.dropdown_y_axis),
row(*self._dynamic_widgets.values()),
)
return column(*layout_rows)
class BokehTextSnorkel(BokehSnorkelExplorer, BokehForText):
3
View Source File : specialization.py
License : MIT License
Project Creator : phurwicz
License : MIT License
Project Creator : phurwicz
def _layout_widgets(self):
"""Define the layout of widgets."""
layout_rows = (
row(self.subset_toggle_widget_column, self.selection_option_box),
row(self.search_pos, self.search_neg),
row(self.lf_apply_trigger, self.lf_filter_trigger, self.lf_list_refresher),
row(self.dropdown_x_axis, self.dropdown_y_axis),
row(*self._dynamic_widgets.values()),
)
return column(*layout_rows)
class BokehAudioFinder(BokehDataFinder, BokehForAudio):
3
View Source File : specialization.py
License : MIT License
Project Creator : phurwicz
License : MIT License
Project Creator : phurwicz
def _layout_widgets(self):
"""Define the layout of widgets."""
layout_rows = (
row(self.subset_toggle_widget_column, self.selection_option_box),
row(
column(self.search_sim, self.search_threshold),
column(self.search_filter_box),
),
row(self.dropdown_x_axis, self.dropdown_y_axis),
row(*self._dynamic_widgets.values()),
)
return column(*layout_rows)
class BokehAudioAnnotator(BokehDataAnnotator, BokehForAudio):
3
View Source File : specialization.py
License : MIT License
Project Creator : phurwicz
License : MIT License
Project Creator : phurwicz
def _layout_widgets(self):
"""Define the layout of widgets."""
layout_rows = (
row(self.subset_toggle_widget_column, self.selection_option_box),
row(self.search_sim, self.search_threshold),
row(self.annotator_input, self.annotator_apply),
row(self.dropdown_x_axis, self.dropdown_y_axis),
row(*self._dynamic_widgets.values()),
)
return column(*layout_rows)
class BokehAudioSoftLabel(BokehSoftLabelExplorer, BokehForAudio):
3
View Source File : specialization.py
License : MIT License
Project Creator : phurwicz
License : MIT License
Project Creator : phurwicz
def _layout_widgets(self):
"""Define the layout of widgets."""
layout_rows = (
row(self.subset_toggle_widget_column, self.selection_option_box),
row(self.search_sim, self.search_threshold),
row(self.score_filter),
row(self.dropdown_x_axis, self.dropdown_y_axis),
row(*self._dynamic_widgets.values()),
)
return column(*layout_rows)
class BokehAudioMargin(BokehMarginExplorer, BokehForAudio):
3
View Source File : specialization.py
License : MIT License
Project Creator : phurwicz
License : MIT License
Project Creator : phurwicz
def _layout_widgets(self):
"""Define the layout of widgets."""
layout_rows = (
row(self.subset_toggle_widget_column, self.selection_option_box),
row(self.search_sim, self.search_threshold),
row(self.dropdown_x_axis, self.dropdown_y_axis),
row(*self._dynamic_widgets.values()),
)
return column(*layout_rows)
class BokehAudioSnorkel(BokehSnorkelExplorer, BokehForAudio):
3
View Source File : specialization.py
License : MIT License
Project Creator : phurwicz
License : MIT License
Project Creator : phurwicz
def _layout_widgets(self):
"""Define the layout of widgets."""
layout_rows = (
row(self.subset_toggle_widget_column, self.selection_option_box),
row(self.search_sim, self.search_threshold),
row(self.lf_apply_trigger, self.lf_filter_trigger, self.lf_list_refresher),
row(self.dropdown_x_axis, self.dropdown_y_axis),
row(*self._dynamic_widgets.values()),
)
return column(*layout_rows)
class BokehImageFinder(BokehDataFinder, BokehForImage):
3
View Source File : specialization.py
License : MIT License
Project Creator : phurwicz
License : MIT License
Project Creator : phurwicz
def _layout_widgets(self):
"""Define the layout of widgets."""
layout_rows = (
row(self.subset_toggle_widget_column, self.selection_option_box),
row(
column(self.search_sim, self.search_threshold),
column(self.search_filter_box),
),
row(self.dropdown_x_axis, self.dropdown_y_axis),
row(*self._dynamic_widgets.values()),
)
return column(*layout_rows)
class BokehImageAnnotator(BokehDataAnnotator, BokehForImage):
3
View Source File : specialization.py
License : MIT License
Project Creator : phurwicz
License : MIT License
Project Creator : phurwicz
def _layout_widgets(self):
"""Define the layout of widgets."""
layout_rows = (
row(self.subset_toggle_widget_column, self.selection_option_box),
row(self.search_sim, self.search_threshold),
row(self.annotator_input, self.annotator_apply),
row(self.dropdown_x_axis, self.dropdown_y_axis),
row(*self._dynamic_widgets.values()),
)
return column(*layout_rows)
class BokehImageSoftLabel(BokehSoftLabelExplorer, BokehForImage):
3
View Source File : specialization.py
License : MIT License
Project Creator : phurwicz
License : MIT License
Project Creator : phurwicz
def _layout_widgets(self):
"""Define the layout of widgets."""
layout_rows = (
row(self.subset_toggle_widget_column, self.selection_option_box),
row(self.search_sim, self.search_threshold),
row(self.score_filter),
row(self.dropdown_x_axis, self.dropdown_y_axis),
row(*self._dynamic_widgets.values()),
)
return column(*layout_rows)
class BokehImageMargin(BokehMarginExplorer, BokehForImage):
3
View Source File : specialization.py
License : MIT License
Project Creator : phurwicz
License : MIT License
Project Creator : phurwicz
def _layout_widgets(self):
"""Define the layout of widgets."""
layout_rows = (
row(self.subset_toggle_widget_column, self.selection_option_box),
row(self.search_sim, self.search_threshold),
row(self.dropdown_x_axis, self.dropdown_y_axis),
row(*self._dynamic_widgets.values()),
)
return column(*layout_rows)
class BokehImageSnorkel(BokehSnorkelExplorer, BokehForImage):
3
View Source File : specialization.py
License : MIT License
Project Creator : phurwicz
License : MIT License
Project Creator : phurwicz
def _layout_widgets(self):
"""Define the layout of widgets."""
layout_rows = (
row(self.subset_toggle_widget_column, self.selection_option_box),
row(self.search_sim, self.search_threshold),
row(self.lf_apply_trigger, self.lf_filter_trigger, self.lf_list_refresher),
row(self.dropdown_x_axis, self.dropdown_y_axis),
row(*self._dynamic_widgets.values()),
)
return column(*layout_rows)
3
View Source File : subroutine.py
License : MIT License
Project Creator : phurwicz
License : MIT License
Project Creator : phurwicz
def recipe_layout(*components, style="horizontal"):
"""
???+ note "Create a recipe-level layout of bokeh objects."
| Param | Type | Description |
| :--------- | :------- | :----------------------------------- |
| `*components` | `bokeh` objects | objects to be plotted |
| `style` | `str` | "horizontal" or "vertical" |
"""
if style == "horizontal":
return row(*components)
elif style == "vertical":
return column(*components)
else:
raise ValueError(f"Unexpected layout style {style}")
def get_explorer_class(task, feature):
3
View Source File : bokeh_helper.py
License : MIT License
Project Creator : phurwicz
License : MIT License
Project Creator : phurwicz
def show_as_interactive(obj, **kwargs):
"""
???+ note "Wrap a bokeh LayoutDOM as an application to allow Python callbacks."
Must have the same signature as `bokeh.io.show()`[https://docs.bokeh.org/en/latest/docs/reference/io.html#bokeh.io.show].
"""
from bokeh.io import show
from bokeh.models.layouts import LayoutDOM
assert isinstance(obj, LayoutDOM), f"Expected Bokeh LayoutDOM, got {type(obj)}"
def handle(doc):
doc.add_root(column(obj))
return show(handle, **kwargs)
def bokeh_hover_tooltip(
3
View Source File : test_layouts.py
License : MIT License
Project Creator : rthorst
License : MIT License
Project Creator : rthorst
def test_gridplot_merge_tools_nested():
p1, p2, p3, p4, p5, p6, p7 = figure(), figure(), figure(), figure(), figure(), figure(), figure()
r1 = row(p1, p2)
r2 = row(p3, p4)
c = column(row(p5), row(p6))
gridplot([[r1, r2], [c, p7]], merge_tools=True)
for p in p1, p2, p3, p4, p5, p6, p7:
assert p.toolbar_location is None
def test_gridplot_None():
3
View Source File : log.py
License : MIT License
Project Creator : shunithaviv
License : MIT License
Project Creator : shunithaviv
def show(self, title=None):
title = title or self.title
if len(self.figures) > 0:
plot = column(
Div(text=' < h1 align="center">{} < /h1>'.format(title)), *self.figures)
show(plot)
def plot(self, x, y, title=None, xlabel=None, ylabel=None, legend=None,
3
View Source File : utils.py
License : MIT License
Project Creator : wenwei202
License : MIT License
Project Creator : wenwei202
def show(self):
if len(self.figures) > 0:
plot = column(*self.figures)
show(plot)
def plot(self, *kargs, **kwargs):
0
View Source File : line.py
License : GNU Affero General Public License v3.0
Project Creator : andrewcooke
License : GNU Affero General Public License v3.0
Project Creator : andrewcooke
def htile(maps, n):
return column([row(maps[i:i + n]) for i in range(0, len(maps), n)])
def vtile(maps, n):
0
View Source File : line.py
License : GNU Affero General Public License v3.0
Project Creator : andrewcooke
License : GNU Affero General Public License v3.0
Project Creator : andrewcooke
def vtile(maps, n):
return row([column(maps[i::n]) for i in range(n)])
0
View Source File : month.py
License : GNU Affero General Public License v3.0
Project Creator : andrewcooke
License : GNU Affero General Public License v3.0
Project Creator : andrewcooke
def month(month):
f'''
# Month: {month}
'''
'''
$contents
'''
'''
## Preparation
'''
s = session('-v2')
output_file(filename='/dev/null')
map_size = 100
month_start = to_date(month).replace(day=1)
'''
## Generate Plot
'''
def days():
for i in Calendar().iterweekdays():
yield Div(text=f' < h2>{day_name[i]} < /h2>')
day = month_start - dt.timedelta(days=month_start.weekday())
while day.replace(day=1) < = month_start:
for weekday in range(7):
if day.month == month_start.month:
contents = [Div(text=f' < h1>{day.strftime("%d")} < /h1>')]
for a in s.query(ActivityJournal). \
filter(ActivityJournal.start >= local_date_to_time(day),
ActivityJournal.start < local_date_to_time(day + dt.timedelta(days=1))).all():
df = Statistics(s, activity_journal=a). \
by_name(ActivityReader, N.SPHERICAL_MERCATOR_X, N.SPHERICAL_MERCATOR_Y).df
contents.append(map_thumbnail(map_size, map_size, df, title=False))
df = Statistics(s, activity_journal=a). \
by_name(ActivityCalculator, N.ACTIVE_DISTANCE, N.ACTIVE_TIME).df
contents.append(Div(
text=f'{format_km(df[N.ACTIVE_DISTANCE][0])} {format_seconds(df[N.ACTIVE_TIME][0])}'))
else:
contents = [Spacer()]
yield column(contents)
day += dt.timedelta(days=1)
show(grid(list(days()), ncols=7))
0
View Source File : plot.py
License : BSD 3-Clause "New" or "Revised" License
Project Creator : canzarlab
License : BSD 3-Clause "New" or "Revised" License
Project Creator : canzarlab
def interactive(
umap_object,
labels=None,
values=None,
hover_data=None,
theme=None,
cmap="Blues",
color_key=None,
color_key_cmap="Spectral",
background="white",
width=800,
height=800,
point_size=None,
subset_points=None,
interactive_text_search=False,
interactive_text_search_columns=None,
interactive_text_search_alpha_contrast=0.95,
):
"""Create an interactive bokeh plot of a UMAP embedding.
While static plots are useful, sometimes a plot that
supports interactive zooming, and hover tooltips for
individual points is much more desireable. This function
provides a simple interface for creating such plots. The
result is a bokeh plot that will be displayed in a notebook.
Note that more complex tooltips etc. will require custom
code -- this is merely meant to provide fast and easy
access to interactive plotting.
Parameters
----------
umap_object: trained UMAP object
A trained UMAP object that has a 2D embedding.
labels: array, shape (n_samples,) (optional, default None)
An array of labels (assumed integer or categorical),
one for each data sample.
This will be used for coloring the points in
the plot according to their label. Note that
this option is mutually exclusive to the ``values``
option.
values: array, shape (n_samples,) (optional, default None)
An array of values (assumed float or continuous),
one for each sample.
This will be used for coloring the points in
the plot according to a colorscale associated
to the total range of values. Note that this
option is mutually exclusive to the ``labels``
option.
hover_data: DataFrame, shape (n_samples, n_tooltip_features)
(optional, default None)
A dataframe of tooltip data. Each column of the dataframe
should be a Series of length ``n_samples`` providing a value
for each data point. Column names will be used for
identifying information within the tooltip.
theme: string (optional, default None)
A color theme to use for plotting. A small set of
predefined themes are provided which have relatively
good aesthetics. Available themes are:
* 'blue'
* 'red'
* 'green'
* 'inferno'
* 'fire'
* 'viridis'
* 'darkblue'
* 'darkred'
* 'darkgreen'
cmap: string (optional, default 'Blues')
The name of a matplotlib colormap to use for coloring
or shading points. If no labels or values are passed
this will be used for shading points according to
density (largely only of relevance for very large
datasets). If values are passed this will be used for
shading according the value. Note that if theme
is passed then this value will be overridden by the
corresponding option of the theme.
color_key: dict or array, shape (n_categories) (optional, default None)
A way to assign colors to categoricals. This can either be
an explicit dict mapping labels to colors (as strings of form
'#RRGGBB'), or an array like object providing one color for
each distinct category being provided in ``labels``. Either
way this mapping will be used to color points according to
the label. Note that if theme
is passed then this value will be overridden by the
corresponding option of the theme.
color_key_cmap: string (optional, default 'Spectral')
The name of a matplotlib colormap to use for categorical coloring.
If an explicit ``color_key`` is not given a color mapping for
categories can be generated from the label list and selecting
a matching list of colors from the given colormap. Note
that if theme
is passed then this value will be overridden by the
corresponding option of the theme.
background: string (optional, default 'white')
The color of the background. Usually this will be either
'white' or 'black', but any color name will work. Ideally
one wants to match this appropriately to the colors being
used for points etc. This is one of the things that themes
handle for you. Note that if theme
is passed then this value will be overridden by the
corresponding option of the theme.
width: int (optional, default 800)
The desired width of the plot in pixels.
height: int (optional, default 800)
The desired height of the plot in pixels
point_size: int (optional, default None)
The size of each point marker
subset_points: array, shape (n_samples,) (optional, default None)
A way to select a subset of points based on an array of boolean
values.
interactive_text_search: bool (optional, default False)
Whether to include a text search widget above the interactive plot
interactive_text_search_columns: list (optional, default None)
Columns of data source to search. Searches labels and hover_data by default.
interactive_text_search_alpha_contrast: float (optional, default 0.95)
Alpha value for points matching text search. Alpha value for points
not matching text search will be 1 - interactive_text_search_alpha_contrast
Returns
-------
"""
if theme is not None:
cmap = _themes[theme]["cmap"]
color_key_cmap = _themes[theme]["color_key_cmap"]
background = _themes[theme]["background"]
if labels is not None and values is not None:
raise ValueError(
"Conflicting options; only one of labels or values should be set"
)
points = umap_object.embedding_
if subset_points is not None:
if len(subset_points) != points.shape[0]:
raise ValueError(
"Size of subset points ({}) does not match number of input points ({})".format(
len(subset_points), points.shape[0]
)
)
points = points[subset_points]
if points.shape[1] != 2:
raise ValueError("Plotting is currently only implemented for 2D embeddings")
if point_size is None:
point_size = 100.0 / np.sqrt(points.shape[0])
data = pd.DataFrame(umap_object.embedding_, columns=("x", "y"))
if labels is not None:
data["label"] = labels
if color_key is None:
unique_labels = np.unique(labels)
num_labels = unique_labels.shape[0]
color_key = _to_hex(
plt.get_cmap(color_key_cmap)(np.linspace(0, 1, num_labels))
)
if isinstance(color_key, dict):
data["color"] = pd.Series(labels).map(color_key)
else:
unique_labels = np.unique(labels)
if len(color_key) < unique_labels.shape[0]:
raise ValueError(
"Color key must have enough colors for the number of labels"
)
new_color_key = {k: color_key[i] for i, k in enumerate(unique_labels)}
data["color"] = pd.Series(labels).map(new_color_key)
colors = "color"
elif values is not None:
data["value"] = values
palette = _to_hex(plt.get_cmap(cmap)(np.linspace(0, 1, 256)))
colors = btr.linear_cmap(
"value", palette, low=np.min(values), high=np.max(values)
)
else:
colors = matplotlib.colors.rgb2hex(plt.get_cmap(cmap)(0.5))
if subset_points is not None:
data = data[subset_points]
if hover_data is not None:
hover_data = hover_data[subset_points]
if points.shape[0] < = width * height // 10:
if hover_data is not None:
tooltip_dict = {}
for col_name in hover_data:
data[col_name] = hover_data[col_name]
tooltip_dict[col_name] = "@" + col_name
tooltips = list(tooltip_dict.items())
else:
tooltips = None
data["alpha"] = 1
# bpl.output_notebook(hide_banner=True) # this doesn't work for non-notebook use
data_source = bpl.ColumnDataSource(data)
plot = bpl.figure(
width=width,
height=height,
tooltips=tooltips,
background_fill_color=background,
)
plot.circle(
x="x",
y="y",
source=data_source,
color=colors,
size=point_size,
alpha="alpha",
)
plot.grid.visible = False
plot.axis.visible = False
if interactive_text_search:
text_input = TextInput(value="", title="Search:")
if interactive_text_search_columns is None:
interactive_text_search_columns = []
if hover_data is not None:
interactive_text_search_columns.extend(hover_data.columns)
if labels is not None:
interactive_text_search_columns.append("label")
if len(interactive_text_search_columns) == 0:
warn(
"interactive_text_search_columns set to True, but no hover_data or labels provided."
"Please provide hover_data or labels to use interactive text search."
)
else:
callback = CustomJS(
args=dict(
source=data_source,
matching_alpha=interactive_text_search_alpha_contrast,
non_matching_alpha=1 - interactive_text_search_alpha_contrast,
search_columns=interactive_text_search_columns,
),
code="""
var data = source.data;
var text_search = cb_obj.value;
var search_columns_dict = {}
for (var col in search_columns){
search_columns_dict[col] = search_columns[col]
}
// Loop over columns and values
// If there is no match for any column for a given row, change the alpha value
var string_match = false;
for (var i = 0; i < data.x.length; i++) {
string_match = false
for (var j in search_columns_dict) {
if (String(data[search_columns_dict[j]][i]).includes(text_search) ) {
string_match = true
}
}
if (string_match){
data['alpha'][i] = matching_alpha
}else{
data['alpha'][i] = non_matching_alpha
}
}
source.change.emit();
""",
)
text_input.js_on_change("value", callback)
plot = column(text_input, plot)
# bpl.show(plot)
else:
if hover_data is not None:
warn(
"Too many points for hover data -- tooltips will not"
"be displayed. Sorry; try subssampling your data."
)
if interactive_text_search:
warn(
"Too many points for text search." "Sorry; try subssampling your data."
)
hv.extension("bokeh")
hv.output(size=300)
hv.opts('RGB [bgcolor="{}", xaxis=None, yaxis=None]'.format(background))
if labels is not None:
point_plot = hv.Points(data, kdims=["x", "y"])
plot = hd.datashade(
point_plot,
aggregator=ds.count_cat("color"),
color_key=color_key,
cmap=plt.get_cmap(cmap),
width=width,
height=height,
)
elif values is not None:
min_val = data.values.min()
val_range = data.values.max() - min_val
data["val_cat"] = pd.Categorical(
(data.values - min_val) // (val_range // 256)
)
point_plot = hv.Points(data, kdims=["x", "y"], vdims=["val_cat"])
plot = hd.datashade(
point_plot,
aggregator=ds.count_cat("val_cat"),
cmap=plt.get_cmap(cmap),
width=width,
height=height,
)
else:
point_plot = hv.Points(data, kdims=["x", "y"])
plot = hd.datashade(
point_plot,
aggregator=ds.count(),
cmap=plt.get_cmap(cmap),
width=width,
height=height,
)
return plot
0
View Source File : utils.py
License : Apache License 2.0
Project Creator : CNES
License : Apache License 2.0
Project Creator : CNES
def compare_2_disparities(
input_first_disp_map: xr.Dataset, first_title: str, input_second_disp_map: xr.Dataset, second_title: str
) -> None:
"""
Show 2 disparity maps
:param input_first_disp_map: disparity map
:type input_first_disp_map: dataset
:param first_title: disparity map title
:type first_title: str
:param input_second_disp_map: disparity map
:type input_second_disp_map: dataset
:param second_title: disparity map title
:type second_title: str
:return: none
"""
output_notebook()
size = 0.5
first_disp_map = add_validity_mask_to_dataset(input_first_disp_map)
second_disp_map = add_validity_mask_to_dataset(input_second_disp_map)
valid_idx = np.where(first_disp_map["validity_mask"].data == 0)
min_d = np.nanmin(first_disp_map["disparity_map"].data[valid_idx])
max_d = np.nanmax(first_disp_map["disparity_map"].data[valid_idx])
cmap_pandora = pandora_cmap()
mapper_avec_opti = LinearColorMapper(palette=cmap_to_palette(cmap_pandora), low=min_d, high=max_d)
color_bar = ColorBar(
color_mapper=mapper_avec_opti, ticker=BasicTicker(), label_standoff=12, border_line_color=None, location=(0, 0)
)
dw = first_disp_map["disparity_map"].shape[1]
dh = first_disp_map["disparity_map"].shape[0]
if first_title == None:
first_title = "First disparity map"
if second_title == None:
second_title = "Second disparity map"
# First disparity map
first_fig = figure(
title=first_title, width=450, height=450, tools=["reset", "pan", "box_zoom"], output_backend="webgl"
)
first_fig.image(
image=[np.flip(first_disp_map["disparity_map"].data, 0)], x=1, y=0, dw=dw, dh=dh, color_mapper=mapper_avec_opti
)
x = np.where(first_disp_map["invalid_mask"].data != 0)[1]
y = dh - np.where(first_disp_map["invalid_mask"].data != 0)[0]
first_inv_msk = first_fig.circle(x=x, y=y, size=size, color="black")
legend = Legend(items=[("inv msk", [first_inv_msk])], location="center", click_policy="hide")
first_fig.add_layout(legend, "below")
first_fig.add_layout(color_bar, "right")
# Second disparity map
second_fig = figure(
title=second_title,
width=450,
height=450,
tools=["reset", "pan", "box_zoom"],
output_backend="webgl",
x_range=first_fig.x_range,
y_range=first_fig.y_range,
)
second_fig.image(
image=[np.flip(second_disp_map["disparity_map"].data, 0)], x=1, y=0, dw=dw, dh=dh, color_mapper=mapper_avec_opti
)
x = np.where(second_disp_map["invalid_mask"].data != 0)[1]
y = dh - np.where(second_disp_map["invalid_mask"].data != 0)[0]
second_inv_msk = second_fig.circle(x=x, y=y, size=size, color="black")
legend = Legend(
items=[("inv msk", [second_inv_msk])], glyph_height=10, glyph_width=10, location="center", click_policy="hide"
)
second_fig.add_layout(legend, "below")
second_fig.add_layout(color_bar, "right")
layout = column(row(first_fig, second_fig))
show(layout)
def compare_3_disparities_and_error(
0
View Source File : utils.py
License : Apache License 2.0
Project Creator : CNES
License : Apache License 2.0
Project Creator : CNES
def compare_3_disparities_and_error(
input_first_disp_map: xr.Dataset,
first_title: str,
input_second_disp_map: xr.Dataset,
second_title: str,
input_third_disp_map: xr.Dataset,
third_title: str,
error_map: np.array,
error_title: str,
) -> None:
"""
Show 3 disparity maps and error
:param input_first_disp_map: disparity map
:type input_first_disp_map: dataset
:param first_title: disparity map title
:type first_title: str
:param input_second_disp_map: disparity map
:type input_second_disp_map: dataset
:param second_title: disparity map title
:type second_title: str
:param input_third_disp_map: disparity map
:type input_third_disp_map: dataset
:param third_title: disparity map title
:type third_title: str
:param error_map: error map
:type error_map: np.array
:param error_title: error title
:type error_title: str
:return: none
"""
output_notebook()
size = 0.5
first_disp_map = add_validity_mask_to_dataset(input_first_disp_map)
second_disp_map = add_validity_mask_to_dataset(input_second_disp_map)
third_disp_map = add_validity_mask_to_dataset(input_third_disp_map)
valid_idx = np.where(first_disp_map["validity_mask"].data == 0)
min_d = np.nanmin(first_disp_map["disparity_map"].data[valid_idx])
max_d = np.nanmax(first_disp_map["disparity_map"].data[valid_idx])
cmap_pandora = pandora_cmap()
mapper_avec_opti = LinearColorMapper(palette=cmap_to_palette(cmap_pandora), low=min_d, high=max_d)
color_bar = ColorBar(
color_mapper=mapper_avec_opti, ticker=BasicTicker(), label_standoff=12, border_line_color=None, location=(0, 0)
)
dw = first_disp_map["disparity_map"].shape[1]
dh = first_disp_map["disparity_map"].shape[0]
# First disparity map
first_fig = figure(
title=first_title, width=400, height=400, tools=["reset", "pan", "box_zoom"], output_backend="webgl"
)
first_fig.image(
image=[np.flip(first_disp_map["disparity_map"].data, 0)], x=1, y=0, dw=dw, dh=dh, color_mapper=mapper_avec_opti
)
x = np.where(first_disp_map["invalid_mask"].data != 0)[1]
y = dh - np.where(first_disp_map["invalid_mask"].data != 0)[0]
first_inv_msk = first_fig.circle(x=x, y=y, size=size, color="black")
legend = Legend(items=[("inv msk", [first_inv_msk])], location="center", click_policy="hide")
first_fig.add_layout(legend, "below")
first_fig.add_layout(color_bar, "right")
# Second disparity map
second_fig = figure(
title=second_title,
width=400,
height=400,
tools=["reset", "pan", "box_zoom"],
output_backend="webgl",
x_range=first_fig.x_range,
y_range=first_fig.y_range,
)
second_fig.image(
image=[np.flip(second_disp_map["disparity_map"].data, 0)], x=1, y=0, dw=dw, dh=dh, color_mapper=mapper_avec_opti
)
x = np.where(second_disp_map["invalid_mask"].data != 0)[1]
y = dh - np.where(second_disp_map["invalid_mask"].data != 0)[0]
second_inv_msk = second_fig.circle(x=x, y=y, size=size, color="black")
legend = Legend(
items=[("inv msk", [second_inv_msk])], glyph_height=10, glyph_width=10, location="center", click_policy="hide"
)
second_fig.add_layout(legend, "below")
second_fig.add_layout(color_bar, "right")
# Third disparity map
third_fig = figure(
title=third_title,
width=400,
height=400,
tools=["reset", "pan", "box_zoom"],
output_backend="webgl",
x_range=first_fig.x_range,
y_range=first_fig.y_range,
)
third_fig.image(
image=[np.flip(third_disp_map["disparity_map"].data, 0)], x=1, y=0, dw=dw, dh=dh, color_mapper=mapper_avec_opti
)
x = np.where(third_disp_map["invalid_mask"].data != 0)[1]
y = dh - np.where(third_disp_map["invalid_mask"].data != 0)[0]
third_inv_msk = third_fig.circle(x=x, y=y, size=size, color="black")
legend = Legend(
items=[("inv msk", [third_inv_msk])], glyph_height=10, glyph_width=10, location="center", click_policy="hide"
)
third_fig.add_layout(legend, "below")
third_fig.add_layout(color_bar, "right")
# Error plot
error_fig = figure(
title=error_title,
width=400,
height=400,
tools=["reset", "pan", "box_zoom"],
output_backend="webgl",
x_range=first_fig.x_range,
y_range=first_fig.y_range,
)
min_d = 0
max_d = 10
reds_cmap = cm.get_cmap("Reds", 256)
mapper_avec_opti = LinearColorMapper(palette=cmap_to_palette(reds_cmap), low=min_d, high=max_d)
color_bar = ColorBar(
color_mapper=mapper_avec_opti, ticker=BasicTicker(), label_standoff=12, border_line_color=None, location=(0, 0)
)
error_fig.image(image=[np.flip(error_map, 0)], x=1, y=0, dw=dw, dh=dh, color_mapper=mapper_avec_opti)
error_fig.add_layout(color_bar, "right")
layout = column(row(first_fig, second_fig), row(third_fig, error_fig))
show(layout)
def compare_disparity_and_error(
0
View Source File : utils.py
License : Apache License 2.0
Project Creator : CNES
License : Apache License 2.0
Project Creator : CNES
def compare_disparity_and_error(
input_first_disp_map: xr.Dataset, first_title: str, error_map: np.array, error_title: str
) -> None:
"""
Show disparity map and error
:param left_disp_map: disparity map
:type left_disp_map: dataset
:param title: disparity map title
:type title: str
:param error_map: error map
:type error_map: np.array
:param error_title: error title
:type error_title: str
:return: none
"""
output_notebook()
size = 0.5
# Disparity map
first_disp_map = add_validity_mask_to_dataset(input_first_disp_map)
valid_idx = np.where(first_disp_map["validity_mask"].data == 0)
min_d = np.nanmin(first_disp_map["disparity_map"].data[valid_idx])
max_d = np.nanmax(first_disp_map["disparity_map"].data[valid_idx])
cmap_pandora = pandora_cmap()
mapper_avec_opti = LinearColorMapper(palette=cmap_to_palette(cmap_pandora), low=min_d, high=max_d)
color_bar = ColorBar(
color_mapper=mapper_avec_opti, ticker=BasicTicker(), label_standoff=12, border_line_color=None, location=(0, 0)
)
dw = first_disp_map["disparity_map"].shape[1]
dh = first_disp_map["disparity_map"].shape[0]
first_fig = figure(
title=first_title,
width=450,
height=450,
tools=["reset", "pan", "box_zoom"],
output_backend="webgl",
sizing_mode="scale_width",
)
first_fig.image(
image=[np.flip(first_disp_map["disparity_map"].data, 0)], x=1, y=0, dw=dw, dh=dh, color_mapper=mapper_avec_opti
)
x = np.where(first_disp_map["invalid_mask"].data != 0)[1]
y = dh - np.where(first_disp_map["invalid_mask"].data != 0)[0]
first_inv_msk = first_fig.circle(x=x, y=y, size=size, color="black")
legend = Legend(items=[("inv msk", [first_inv_msk])], location="center", click_policy="hide")
first_fig.add_layout(legend, "below")
first_fig.add_layout(color_bar, "right")
# Error plot
error_fig = figure(
title=error_title,
width=450,
height=450,
tools=["reset", "pan", "box_zoom"],
output_backend="webgl",
x_range=first_fig.x_range,
y_range=first_fig.y_range,
sizing_mode="scale_width",
)
min_d = 0
max_d = 10
reds_cmap = cm.get_cmap("Reds", 256)
mapper_avec_opti = LinearColorMapper(palette=cmap_to_palette(reds_cmap), low=min_d, high=max_d)
color_bar = ColorBar(
color_mapper=mapper_avec_opti, ticker=BasicTicker(), label_standoff=12, border_line_color=None, location=(0, 0)
)
error_fig.image(image=[np.flip(error_map, 0)], x=1, y=0, dw=dw, dh=dh, color_mapper=mapper_avec_opti)
# Add disparity's error mask on error
x = np.where(first_disp_map["invalid_mask"].data != 0)[1]
y = dh - np.where(first_disp_map["invalid_mask"].data != 0)[0]
error_inv_msk = error_fig.circle(x=x, y=y, size=size, color="black")
legend = Legend(items=[("inv msk", [error_inv_msk])], location="center", click_policy="hide")
error_fig.add_layout(legend, "below")
error_fig.add_layout(color_bar, "right")
layout = column(row(first_fig, error_fig))
show(layout)
def show_input_images(img_left: xr.Dataset, img_right: xr.Dataset) -> None:
0
View Source File : utils.py
License : Apache License 2.0
Project Creator : CNES
License : Apache License 2.0
Project Creator : CNES
def show_input_images(img_left: xr.Dataset, img_right: xr.Dataset) -> None:
"""
Show input images and anaglyph
:param left_disp_map: disparity map
:type left_disp_map: dataset
:param right_disp_map: right disparity map
:type right_disp_map: dataset
:return: none
"""
output_notebook()
dw = np.flip(img_left.im.data, 0).shape[1]
dh = np.flip(img_right.im.data, 0).shape[0]
width = 320
height = 320
# Image left
img_left_data = img_left.im.data
left_fig = bpl.figure(title="Left image", width=width, height=height)
left_fig.image(image=[np.flip(img_left_data, 0)], x=1, y=0, dw=dw, dh=dh)
# Image right
img_right_data = img_right.im.data
right_fig = bpl.figure(
title="Right image", width=width, height=height, x_range=left_fig.x_range, y_range=left_fig.y_range
)
right_fig.image(image=[np.flip(img_right_data, 0)], x=1, y=0, dw=dw, dh=dh)
# Anaglyph
img_left, img_right_align = xr.align(img_left, img_right)
anaglyph = np.stack((img_left.im, img_right_align.im, img_right_align.im), axis=-1)
clip_percent = 5
vmin_ref = np.percentile(img_left.im, clip_percent)
vmax_ref = np.percentile(img_left.im, 100 - clip_percent)
vmin_sec = np.percentile(img_right.im, clip_percent)
vmax_sec = np.percentile(img_right.im, 100 - clip_percent)
vmin_anaglyph = np.array([vmin_ref, vmin_sec, vmin_sec])
vmax_anaglyph = np.array([vmax_ref, vmax_sec, vmax_sec])
img = np.clip((anaglyph - vmin_anaglyph) / (vmax_anaglyph - vmin_anaglyph), 0, 1)
anaglyph = np.clip((anaglyph - vmin_anaglyph) / (vmax_anaglyph - vmin_anaglyph), 0, 1)
# Add 4rth channel to use bokeh's image_rgba function
img = np.empty((dh, dw), dtype=np.uint32)
view = img.view(dtype=np.uint8).reshape(dh, dw, 4)
for i in range(dh):
for j in range(dw):
view[i, j, 0] = anaglyph[i, j, 0] * 255
view[i, j, 1] = anaglyph[i, j, 1] * 255
view[i, j, 2] = anaglyph[i, j, 2] * 255
view[i, j, 3] = 255
anaglyph_fig = bpl.figure(
title="Anaglyph", width=width, height=height, x_range=left_fig.x_range, y_range=left_fig.y_range
)
anaglyph_fig.image_rgba(image=[np.flip(img, 0)], x=1, y=0, dw=dw, dh=dh)
layout = column(row(left_fig, right_fig, anaglyph_fig))
show(layout)
def get_error(
0
View Source File : plot.py
License : BSD 3-Clause "New" or "Revised" License
Project Creator : CoffeaTeam
License : BSD 3-Clause "New" or "Revised" License
Project Creator : CoffeaTeam
def bokeh_plot(histo, jup_url="http://127.0.0.1:8889"):
if not isnotebook():
raise NotImplementedError("Only usable in jupyter notebook")
import bokeh.plotting.figure as bk_figure
from bokeh.io import show
from bokeh import palettes
from bokeh.layouts import row, column
from bokeh.models import ColumnDataSource
from bokeh.models.widgets import RadioButtonGroup, CheckboxButtonGroup
from bokeh.models.widgets import RangeSlider, Div
from bokeh.io import output_notebook # enables plot interface in J notebook
# init bokeh
from bokeh.application import Application
from bokeh.application.handlers import FunctionHandler
from bokeh.core.validation import silence
from bokeh.core.validation.warnings import EMPTY_LAYOUT
silence(EMPTY_LAYOUT, True)
output_notebook()
# Set up widgets
cfg_labels = ["Ghost"]
wi_config = CheckboxButtonGroup(labels=cfg_labels, active=[0])
wi_dense_select = RadioButtonGroup(
labels=[ax.name for ax in histo.dense_axes()], active=0
)
wi_sparse_select = RadioButtonGroup(
labels=[ax.name for ax in histo.sparse_axes()], active=0
)
# Dense widgets
sliders = {}
for ax in histo.dense_axes():
edge_vals = (histo.axis(ax.name).edges()[0], histo.axis(ax.name).edges()[-1])
_smallest_bin = numpy.min(numpy.diff(histo.axis(ax.name).edges()))
sliders[ax.name] = RangeSlider(
title=ax.name,
value=edge_vals,
start=edge_vals[0],
end=edge_vals[1],
step=_smallest_bin,
name=ax.name,
)
# Cat widgets
togglers = {}
for ax in histo.sparse_axes():
togglers[ax.name] = CheckboxButtonGroup(
labels=[i.name for i in ax.identifiers()], active=[0], name=ax.name
)
# Toggles for all widgets
configers = {}
for ax in histo.sparse_axes():
configers[ax.name] = CheckboxButtonGroup(
labels=["Display", "Ghost"], active=[0, 1], name=ax.name
)
for ax in histo.dense_axes():
configers[ax.name] = CheckboxButtonGroup(
labels=["Display"], active=[0], name=ax.name
)
# Figure
fig = bk_figure(
title="1D Projection",
plot_width=500,
plot_height=500,
min_border=20,
toolbar_location=None,
)
fig.yaxis.axis_label = "N"
fig.xaxis.axis_label = "Quantity"
# Iterate over possible overlays
_max_idents = 0 # Max number of simultaneou histograms
for ax in histo.sparse_axes():
_max_idents = max(_max_idents, len([i.name for i in ax.identifiers()]))
# Data source list
sources = []
sources_ghost = []
for i in range(_max_idents):
sources.append(ColumnDataSource(dict(left=[], top=[], right=[], bottom=[])))
sources_ghost.append(
ColumnDataSource(dict(left=[], top=[], right=[], bottom=[]))
)
# Hist list
hists = []
hists_ghost = []
for i in range(_max_idents):
if _max_idents < 10:
_color = palettes.Category10[min(max(3, _max_idents), 10)][i]
else:
_color = palettes.magma(_max_idents)[i]
hists.append(
fig.quad(
left="left",
right="right",
top="top",
bottom="bottom",
source=sources[i],
alpha=0.9,
color=_color,
)
)
hists_ghost.append(
fig.quad(
left="left",
right="right",
top="top",
bottom="bottom",
source=sources_ghost[i],
alpha=0.05,
color=_color,
)
)
def update_data(attrname, old, new):
sparse_active = wi_sparse_select.active
sparse_name = [ax.name for ax in histo.sparse_axes()][sparse_active]
sparse_other = [ax.name for ax in histo.sparse_axes() if ax.name != sparse_name]
dense_active = wi_dense_select.active
dense_name = [ax.name for ax in histo.dense_axes()][dense_active]
dense_other = [ax.name for ax in histo.dense_axes() if ax.name != dense_name]
# Apply cuts in projections
_h = histo.copy()
for proj_ax in sparse_other:
_idents = histo.axis(proj_ax).identifiers()
_labels = [ident.name for ident in _idents]
if 0 in configers[proj_ax].active:
_h = _h.integrate(
proj_ax, [_labels[i] for i in togglers[proj_ax].active]
)
else:
_h = _h.integrate(proj_ax)
for proj_ax in dense_other:
_h = _h.integrate(
proj_ax, slice(sliders[proj_ax].value[0], sliders[proj_ax].value[1])
)
for cat_ix in range(_max_idents):
# Update histo for each toggled overlay
if cat_ix in togglers[sparse_name].active:
cat_value = histo.axis(sparse_name).identifiers()[cat_ix]
h1d = _h.integrate(sparse_name, cat_value)
# Get shown histogram
values = h1d.project(dense_name).values()
if values != {}:
h = values[()]
bins = h1d.axis(dense_name).edges()
# Apply cuts on shown axis
bin_los = bins[:-1][bins[:-1] > sliders[dense_name].value[0]]
bin_his = bins[1:][bins[1:] < sliders[dense_name].value[1]]
new_bins = numpy.intersect1d(bin_los, bin_his)
bin_ixs = numpy.searchsorted(bins, new_bins)[:-1]
h = h[bin_ixs]
sources[cat_ix].data = dict(
left=new_bins[:-1],
right=new_bins[1:],
top=h,
bottom=numpy.zeros_like(h),
)
else:
sources[cat_ix].data = dict(left=[], right=[], top=[], bottom=[])
# Add ghosts
if 0 in wi_config.active:
h1d = histo.integrate(sparse_name, cat_value)
for proj_ax in sparse_other:
_idents = histo.axis(proj_ax).identifiers()
_labels = [ident.name for ident in _idents]
if 1 not in configers[proj_ax].active:
h1d = h1d.integrate(
proj_ax, [_labels[i] for i in togglers[proj_ax].active]
)
else:
h1d = h1d.integrate(proj_ax)
values = h1d.project(dense_name).values()
if values != {}:
h = h1d.project(dense_name).values()[()]
bins = h1d.axis(dense_name).edges()
sources_ghost[cat_ix].data = dict(
left=bins[:-1],
right=bins[1:],
top=h,
bottom=numpy.zeros_like(h),
)
else:
sources_ghost[cat_ix].data = dict(
left=[], right=[], top=[], bottom=[]
)
else:
sources[cat_ix].data = dict(left=[], right=[], top=[], bottom=[])
sources_ghost[cat_ix].data = dict(left=[], right=[], top=[], bottom=[])
# Cosmetics
fig.xaxis.axis_label = dense_name
for name, slider in sliders.items():
slider.on_change("value", update_data)
for name, toggler in togglers.items():
toggler.on_change("active", update_data)
for name, configer in configers.items():
configer.on_change("active", update_data)
# Button
for w in [wi_dense_select, wi_sparse_select, wi_config]:
w.on_change("active", update_data)
from bokeh.models.widgets import Panel, Tabs
layout = row(
fig,
column(
Div(
text=" < b>Overlay Axis: < /b>",
style={"font-size": "100%", "color": "black"},
),
wi_sparse_select,
Div(
text=" < b>Plot Axis: < /b>", style={"font-size": "100%", "color": "black"}
),
wi_dense_select,
Div(
text=" < b>Categorical Cuts: < /b>",
style={"font-size": "100%", "color": "black"},
),
*[toggler for name, toggler in togglers.items()],
Div(
text=" < b>Dense Cuts: < /b>", style={"font-size": "100%", "color": "black"}
),
*[slider for name, slider in sliders.items()]
),
)
# Config prep
incl_lists = [[], [], []]
for i, key in enumerate(list(configers.keys())):
incl_lists[i // max(5, len(list(configers.keys())) / 3)].append(
Div(
text=" < b>{}: < /b>".format(key),
style={"font-size": "70%", "color": "black"},
)
)
incl_lists[i // max(5, len(list(configers.keys())) / 3)].append(configers[key])
layout_cfgs = column(
row(
column(
Div(
text=" < b>Configs: < /b>",
style={"font-size": "100%", "color": "black"},
),
wi_config,
)
),
Div(
text=" < b>Axis togglers: < /b>", style={"font-size": "100%", "color": "black"}
),
row(
column(incl_lists[0]),
column(incl_lists[1]),
column(incl_lists[2]),
),
)
# Update active buttons
def update_layout(attrname, old, new):
active_axes = [None]
for name, wi in configers.items():
if 0 in wi.active:
active_axes.append(name)
for child in layout.children[1].children:
if child.name not in active_axes:
child.visible = False
else:
child.visible = True
for name, configer in configers.items():
configer.on_change("active", update_layout)
tab1 = Panel(child=layout, title="Projection")
tab2 = Panel(child=layout_cfgs, title="Configs")
tabs = Tabs(tabs=[tab1, tab2])
def modify_doc(doc):
doc.add_root(row(tabs, width=800))
doc.title = "Sliders"
handler = FunctionHandler(modify_doc)
app = Application(handler)
show(app, notebook_url=jup_url)
update_data("", "", "")
0
View Source File : log.py
License : Apache License 2.0
Project Creator : Drajan
License : Apache License 2.0
Project Creator : Drajan
def save(self, title=None):
"""save the json file.
Parameters
----------
title: string
title of the HTML file
"""
title = title or self.title
if len(self.figures) > 0:
if os.path.isfile(self.plot_path):
os.remove(self.plot_path)
if self.first_save:
self.first_save = False
logging.info('Plot file saved at: {}'.format(
os.path.abspath(self.plot_path)))
output_file(self.plot_path, title=title)
plot = column(
Div(text=' < h1 align="center">{} < /h1>'.format(title)), *self.figures)
save(plot)
self.clear()
if self.data_format == 'json':
self.results.to_json(self.data_path, orient='records', lines=True)
else:
self.results.to_csv(self.data_path, index=False, index_label=False)
def load(self, path=None):
0
View Source File : bokeh_sliders.py
License : GNU General Public License v3.0
Project Creator : drscotthawley
License : GNU General Public License v3.0
Project Creator : drscotthawley
def update_effect(attrname, old, new):
global effect, model, knob_names, knob_ranges, num_knobs, knob_sliders
# match the menu option with the right entry in effects_dict
long_name = effect_select.value
plot.title.text = f"Trying to setup effect '{long_name}'..."
shortname = ''
for key, val in effects_dict.items():
if val['name'] == long_name:
shortname = key
break
if '' == shortname:
plot.title.text = f"**ERROR: Effect '{long_name}' not defined**"
return
effect = effects_dict[shortname]['effect']
num_knobs = 0
if effect is not None:
knob_names, knob_ranges = effect.knob_names, np.array(effect.knob_ranges)
num_knobs = len(knob_names)
# try to read the checkpoint file
checkpoint_file = effects_dict[shortname]['checkpoint']
model = setup_model(checkpoint_file, fatal=False)
if model is None:
msg = f"**ERROR: checkpoint file '{checkpoint_file}' not found**"
print("\n",msg)
plot.title.text = msg
# rebuild the entire display (because knobs have changed)
knob_sliders = []
if num_knobs > 0:
knobs_wc = knob_ranges.mean(axis=1)
for k in range(num_knobs):
start, end = knob_ranges[k][0], knob_ranges[k][1]
mid = knobs_wc[k]
step = (end-start)/25
tmp = Slider(title=knob_names[k], value=mid, start=start, end=end, step=step)
knob_sliders.append(tmp)
for w in knob_sliders: # since we now defined new widgets, we need triggers for them
w.on_change('value', update_data)
inputs = column([effect_select, input_select]+knob_sliders )
curdoc().clear()
curdoc().add_root(row(inputs, plot, width=800))
curdoc().title = "SignalTrain Demo"
update_data(attrname, old, new)
def update_input(attrname, old, new):
0
View Source File : visual_midi.py
License : MIT License
Project Creator : dubreuia
License : MIT License
Project Creator : dubreuia
def plot(self, pm: PrettyMIDI):
"""
Plots the pretty midi object as a plot object.
:param pm: the PrettyMIDI instance to plot
:return: the bokeh plot layout
"""
preset = self._preset
# Calculates the QPM from the MIDI file, might raise exception if confused
qpm = self._get_qpm(pm)
# Initialize the tools, those are present on the right hand side
plot = bokeh.plotting.figure(
tools="reset,hover,save,wheel_zoom,pan",
toolbar_location=preset.toolbar_location)
# Setup the hover and the data dict for bokeh,
# each property must match a property in the data dict
plot.select(dict(type=bokeh.models.HoverTool)).tooltips = ({
"program": "@program",
"pitch": "@top",
"velocity": "@velocity",
"duration": "@duration",
"start_time": "@left",
"end_time": "@right"})
data = dict(
program=[],
top=[],
bottom=[],
left=[],
right=[],
duration=[],
velocity=[],
color=[])
# Puts the notes in the dict for bokeh and saves first
# and last note time, bigger and smaller pitch
pitch_min = None
pitch_max = None
first_note_start = None
last_note_end = None
index_instrument = 0
for instrument in pm.instruments:
for note in instrument.notes:
pitch_min = min(pitch_min or self._MAX_PITCH, note.pitch)
pitch_max = max(pitch_max or self._MIN_PITCH, note.pitch)
color = self._get_color(index_instrument, note)
note_start = note.start
note_end = note.start + (note.end - note.start)
data["program"].append(instrument.program)
data["top"].append(note.pitch)
if self._show_velocity:
data["bottom"].append(note.pitch + (note.velocity / 127))
else:
data["bottom"].append(note.pitch + 1)
data["left"].append(note_start)
data["right"].append(note_end)
data["duration"].append(note_end - note_start)
data["velocity"].append(note.velocity)
data["color"].append(color)
first_note_start = min(first_note_start or sys.maxsize, note_start)
last_note_end = max(last_note_end or 0, note_end)
index_instrument = index_instrument + 1
# Shows an empty plot even if there are no notes
if first_note_start is None or last_note_end is None or pitch_min is None or pitch_max is None:
pitch_min = self._MIN_PITCH
pitch_max = pitch_min + 5
first_note_start = 0
last_note_end = 0
# Gets the pitch range (min, max) from either the provided arguments
# or min and max values from the notes
if self._plot_pitch_range_start is not None:
pitch_min = self._plot_pitch_range_start
else:
pitch_min = min(self._MAX_PITCH, pitch_min)
if self._plot_pitch_range_stop is not None:
pitch_max = self._plot_pitch_range_stop
else:
pitch_max = max(self._MIN_PITCH, pitch_max)
pitch_range = pitch_max + 1 - pitch_min
# Draws the rectangles on the plot from the data
source = ColumnDataSource(data=data)
plot.quad(left="left",
right="right",
top="top",
bottom="bottom",
line_alpha=1,
line_color="black",
color="color",
source=source)
# Draws the y grid by hand, because the grid has label on the ticks, but
# for a plot like this, the labels needs to fit in between the ticks.
# Also useful to change the background of the grid each line
for pitch in range(pitch_min, pitch_max + 1):
# Draws the background box and contours, on the underlay layer, so
# that the rectangles and over the box annotations
fill_alpha = (0.15 if pitch % 2 == 0 else 0.00)
box = BoxAnnotation(bottom=pitch,
top=pitch + 1,
fill_color="gray",
fill_alpha=fill_alpha,
line_color="black",
line_alpha=0.3,
line_width=1,
level="underlay")
plot.add_layout(box)
label = Label(
x=preset.label_y_axis_offset_x,
y=pitch + preset.label_y_axis_offset_y,
x_units="screen",
text=str(pitch),
render_mode="css",
text_font_size=preset.label_text_font_size,
text_font_style=preset.label_text_font_style)
plot.add_layout(label)
# Gets the time signature from pretty midi, or 4/4 if none
if self._midi_time_signature:
numerator, denominator = self._midi_time_signature.split("/")
time_signature = TimeSignature(int(numerator), int(denominator), 0)
else:
if pm.time_signature_changes:
if len(pm.time_signature_changes) > 1:
raise Exception("Multiple time signatures are not supported")
time_signature = pm.time_signature_changes[0]
else:
time_signature = TimeSignature(4, 4, 0)
# Gets seconds per bar and seconds per beat
if len(pm.get_beats()) >= 2:
seconds_per_beat = pm.get_beats()[1] - pm.get_beats()[0]
else:
seconds_per_beat = 0.5
if len(pm.get_downbeats()) >= 2:
seconds_per_bar = pm.get_downbeats()[1] - pm.get_downbeats()[0]
else:
seconds_per_bar = 2.0
# Defines the end time of the plot in seconds
if self._plot_bar_range_stop is not None:
plot_end_time = self._plot_bar_range_stop * seconds_per_bar
else:
# Calculates the plot start and end time, the start time can start after
# notes or truncate notes if the plot is too long (we left truncate the
# plot with the bounds)
# The plot start and plot end are a multiple of seconds per bar (closest
# smaller value for the start time, closest higher value for the end time)
plot_end_time = int((last_note_end) / seconds_per_bar) * seconds_per_bar
# If the last note end is exactly on a multiple of seconds per bar,
# we don't start a new one
is_on_bar = math.isclose(last_note_end % seconds_per_bar, seconds_per_bar)
is_on_bar_exact = math.isclose(last_note_end % seconds_per_bar, 0.0)
if not is_on_bar and not is_on_bar_exact:
plot_end_time += seconds_per_bar
# Defines the start time of the plot in seconds
if self._plot_bar_range_start is not None:
plot_start_time = self._plot_bar_range_start * seconds_per_bar
else:
start_time = int(first_note_start / seconds_per_bar) * seconds_per_bar
plot_max_length_time = self._plot_max_length_bar * seconds_per_bar
plot_start_time = max(plot_end_time - plot_max_length_time, start_time)
# Draws the vertical bar grid, with a different background color
# for each bar
if preset.show_bar:
bar_count = 0
for bar_time in pm.get_downbeats():
fill_alpha_index = bar_count % len(self._bar_fill_alphas)
fill_alpha = self._bar_fill_alphas[fill_alpha_index]
box = BoxAnnotation(left=bar_time,
right=bar_time + seconds_per_bar,
fill_color="gray",
fill_alpha=fill_alpha,
line_color="black",
line_width=2,
line_alpha=0.5,
level="underlay")
plot.add_layout(box)
bar_count += 1
# Draws the vertical beat grid, those are only grid lines
if preset.show_beat:
for beat_time in pm.get_beats():
box = BoxAnnotation(left=beat_time,
right=beat_time + seconds_per_beat,
fill_color=None,
line_color="black",
line_width=1,
line_alpha=0.4,
level="underlay")
plot.add_layout(box)
# Configure x axis
plot.xaxis.bounds = (plot_start_time, plot_end_time)
plot.xaxis.axis_label = "time (SEC)"
plot.xaxis.axis_label_text_font_size = preset.axis_label_text_font_size
plot.xaxis.ticker = bokeh.models.SingleIntervalTicker(interval=1)
plot.xaxis.major_tick_line_alpha = 0.9
plot.xaxis.major_tick_line_width = 1
plot.xaxis.major_tick_out = preset.axis_x_major_tick_out
plot.xaxis.minor_tick_line_alpha = 0
plot.xaxis.major_label_text_font_size = preset.label_text_font_size
plot.xaxis.major_label_text_font_style = preset.label_text_font_style
# Configure y axis
plot.yaxis.bounds = (pitch_min, pitch_max + 1)
plot.yaxis.axis_label = "pitch (MIDI)"
plot.yaxis.axis_label_text_font_size = preset.axis_label_text_font_size
plot.yaxis.ticker = bokeh.models.SingleIntervalTicker(interval=1)
plot.yaxis.major_label_text_alpha = 0
plot.yaxis.major_tick_line_alpha = 0.9
plot.yaxis.major_tick_line_width = 1
plot.yaxis.major_tick_out = preset.axis_y_major_tick_out
plot.yaxis.minor_tick_line_alpha = 0
plot.yaxis.axis_label_standoff = preset.axis_y_label_standoff
plot.outline_line_width = 1
plot.outline_line_alpha = 1
plot.outline_line_color = "black"
# The x grid is deactivated because is draw by hand (see x grid code)
plot.xgrid.grid_line_color = None
# The y grid is deactivated because is draw by hand (see y grid code)
plot.ygrid.grid_line_color = None
# Configure the plot size and range
if self._plot_title is None:
plot_title_text = "Visual MIDI (%s QPM, %s/%s)" % (
str(int(qpm)), time_signature.numerator, time_signature.denominator)
else:
plot_title_text = self._plot_title
plot.title = Title(text=plot_title_text,
text_font_size=preset.title_text_font_size)
plot.plot_width = preset.plot_width
if preset.row_height:
plot.plot_height = pitch_range * preset.row_height
else:
plot.plot_height = preset.plot_height
plot.x_range = Range1d(plot_start_time, plot_end_time)
plot.y_range = Range1d(pitch_min, pitch_max + 1)
plot.min_border_right = 50
if self._live_reload and preset.stop_live_reload_button:
callback = CustomJS(code="clearInterval(liveReloadInterval)")
button = Button(label="stop live reload")
button.js_on_click(callback)
layout = column(button, plot)
else:
layout = column(plot)
return layout
def save(self, pm: PrettyMIDI, filepath: str):
0
View Source File : plotting.py
License : Apache License 2.0
Project Creator : EPFL-LCSB
License : Apache License 2.0
Project Creator : EPFL-LCSB
def summarize_model(model,time_data,groups,
output_path='.', model_tag='', backend ='png'):
summary_plots = dict()
detailed_plots = dict()
cleaned_groups = dict()
# Cleanup missing vars
for key, varnames in groups.items():
cleaned_groups[key] = [x for x in varnames if x in time_data.index or x == 'total']
groups = cleaned_groups
total_groups = {k:v for k,v in groups.items() if 'total' in v and 'pathway_enz' in k}
for key,data_type in groups.items():
summary_plots[key] = make_summary_plots(model,time_data,key,data_type)
detailed_plots[key] = make_detailed_plots(model,time_data,data_type,backend)
summary_plots['growth'] = make_growth_plot(model,time_data)
summary_plots['mass_ratios'] = plot_mass(model,time_data)
if model is not None:
summary_plots['subsystems'] = plot_subsystems(model,time_data)
summary_plots['total'] = make_total_plot(model, time_data, total_groups)
output_folder = join(output_path)#,model_tag)#+'_'+get_timestr())
if not exists(output_folder):
makedirs(output_folder)
bp.curdoc().clear()
bp.output_file(join(output_folder,'summary.html'), title = model_tag)
for p in summary_plots.values():
p.output_backend = backend
bp.show(column(list(summary_plots.values())))
for key,this_dp in detailed_plots.items():
bp.curdoc().clear()
bp.output_file(join(output_folder,'{}.html'.format(key)))
for p in this_dp.children:
try:
p.output_backend = backend
except AttributeError:
# Fails for gridplots
pass
# from bokeh.layouts import GridBox
# if isinstance(p,GridBox):
# p.children[0][0].output_backend = backend
# else: # Toolbox bar etc..
# pass
bp.show(this_dp)
def make_summary_plots(model, time_data, key, data_type, total=False):
0
View Source File : plot_buffer.py
License : GNU General Public License v3.0
Project Creator : eqcorrscan
License : GNU General Public License v3.0
Project Creator : eqcorrscan
def define_plot(
doc: Document,
rt_client: _StreamingClient,
channels: list,
tribe: RealTimeTribe,
inventory: Inventory,
detections: list,
map_options: dict,
plot_options: dict,
plot_length: float,
update_interval: int,
data_color: str = "grey",
lowcut: float = 1.0,
highcut: float = 10.0,
offline: bool = False,
):
"""
Set up a bokeh plot for real-time plotting.
Defines a moving data stream and a map.
Parameters
----------
doc
Bokeh document to edit - usually called as a partial
rt_client
RealTimeClient streaming data
channels
Channels to plot
tribe
Tribe to plot
inventory
Inventory to plot
detections
Detections to plot - should be a list that is updated in place.
map_options
Dictionary of options for the map
plot_options
Dictionary of options for plotting in general
plot_length
Length of data plot
update_interval
Update frequency in seconds
data_color
Colour to data stream
lowcut
Lowcut for filtering data stream
highcut
Highcut for filtering data stream
offline
Flag to set time-stamps to data time-stamps if True, else timestamps
will be real-time
"""
# Set up the data source
Logger.info("Getting stream to define plot")
stream = rt_client.stream.copy().split().detrend()
if lowcut and highcut:
stream.filter("bandpass", freqmin=lowcut, freqmax=highcut)
title = "Streaming data: {0}-{1} Hz bandpass".format(lowcut, highcut)
elif lowcut:
stream.filter("highpass", lowcut)
title = "Streaming data: {0} Hz highpass".format(lowcut)
elif highcut:
stream.filter("lowpass", highcut)
title = "Streaming data: {0} Hz lowpass".format(highcut)
else:
title = "Raw streaming data"
stream.merge()
Logger.info(f"Have the stream: \n{stream}")
template_lats, template_lons, template_alphas, template_ids = (
[], [], [], [])
for template in tribe:
try:
origin = (template.event.preferred_origin() or
template.event.origins[0])
except IndexError:
continue
template_lats.append(origin.latitude)
template_lons.append(origin.longitude % 360)
template_alphas.append(0)
template_ids.append(template.event.resource_id.id.split("/")[-1])
station_lats, station_lons, station_ids = ([], [], [])
for network in inventory:
for station in network:
station_lats.append(station.latitude)
station_lons.append(station.longitude % 360)
station_ids.append(station.code)
# Get plot bounds in web mercator
Logger.info("Defining map")
transformer = Transformer.from_crs(
"epsg:4326", "epsg:3857", always_xy=True)
try:
min_lat, min_lon, max_lat, max_lon = (
min(template_lats + station_lats),
min(template_lons + station_lons),
max(template_lats + station_lats),
max(template_lons + station_lons))
except ValueError as e:
Logger.error(e)
Logger.info("Setting map bounds to NZ")
min_lat, min_lon, max_lat, max_lon = (-47., 165., -34., 179.9)
Logger.info(f"Map bounds: {min_lon}, {min_lat} - {max_lon}, {max_lat}")
bottom_left = transformer.transform(min_lon, min_lat)
top_right = transformer.transform(max_lon, max_lat)
map_x_range = (bottom_left[0], top_right[0])
map_y_range = (bottom_left[1], top_right[1])
template_x, template_y = ([], [])
for lon, lat in zip(template_lons, template_lats):
_x, _y = transformer.transform(lon, lat)
template_x.append(_x)
template_y.append(_y)
station_x, station_y = ([], [])
for lon, lat in zip(station_lons, station_lats):
_x, _y = transformer.transform(lon, lat)
station_x.append(_x)
station_y.append(_y)
template_source = ColumnDataSource({
'y': template_y, 'x': template_x,
'lats': template_lats, 'lons': template_lons,
'template_alphas': template_alphas, 'id': template_ids})
station_source = ColumnDataSource({
'y': station_y, 'x': station_x,
'lats': station_lats, 'lons': station_lons, 'id': station_ids})
Logger.info("Allocated data sources")
trace_sources = {}
trace_data_range = {}
# Allocate empty arrays
for channel in channels:
tr = stream.select(id=channel)[0]
times = np.arange(
tr.stats.starttime.datetime,
(tr.stats.endtime + tr.stats.delta).datetime,
step=dt.timedelta(seconds=tr.stats.delta))
data = tr.data
trace_sources.update(
{channel: ColumnDataSource({'time': times, 'data': data})})
trace_data_range.update({channel: (data.min(), data.max())})
# Set up the map to go on the left side
Logger.info("Adding features to map")
map_plot = figure(
title="Template map", x_range=map_x_range, y_range=map_y_range,
x_axis_type="mercator", y_axis_type="mercator", **map_options)
url = 'http://a.basemaps.cartocdn.com/rastertiles/voyager/{Z}/{X}/{Y}.png'
attribution = "Tiles by Carto, under CC BY 3.0. Data by OSM, under ODbL"
map_plot.add_tile(WMTSTileSource(url=url, attribution=attribution))
map_plot.circle(
x="x", y="y", source=template_source, fill_color="firebrick",
line_color="grey", line_alpha=.2,
fill_alpha="template_alphas", size=10)
map_plot.triangle(
x="x", y="y", size=10, source=station_source, color="blue", alpha=1.0)
# Set up the trace plots
Logger.info("Setting up streaming plot")
trace_plots = []
if not offline:
now = dt.datetime.utcnow()
else:
now = max([tr.stats.endtime for tr in stream]).datetime
p1 = figure(
y_axis_location="right", title=title,
x_range=[now - dt.timedelta(seconds=plot_length), now],
plot_height=int(plot_options["plot_height"] * 1.2),
**{key: value for key, value in plot_options.items()
if key != "plot_height"})
p1.yaxis.axis_label = None
p1.xaxis.axis_label = None
p1.min_border_bottom = 0
p1.min_border_top = 0
if len(channels) != 1:
p1.xaxis.major_label_text_font_size = '0pt'
p1_line = p1.line(
x="time", y='data', source=trace_sources[channels[0]],
color=data_color, line_width=1)
legend = Legend(items=[(channels[0], [p1_line])])
p1.add_layout(legend, 'right')
datetick_formatter = DatetimeTickFormatter(
days=["%m/%d"], months=["%m/%d"],
hours=["%m/%d %H:%M:%S"], minutes=["%m/%d %H:%M:%S"],
seconds=["%m/%d %H:%M:%S"], hourmin=["%m/%d %H:%M:%S"],
minsec=["%m/%d %H:%M:%S"])
p1.xaxis.formatter = datetick_formatter
# Add detection lines
Logger.info("Adding detection artists")
detection_source = _get_pick_times(detections, channels[0])
detection_source.update(
{"pick_values": [[
int(min(stream.select(id=channels[0])[0].data) * .9),
int(max(stream.select(id=channels[0])[0].data) * .9)]
for _ in detection_source['picks']]})
detection_sources = {channels[0]: ColumnDataSource(detection_source)}
detection_lines = MultiLine(
xs="picks", ys="pick_values", line_color="red", line_dash="dashed",
line_width=1)
p1.add_glyph(detection_sources[channels[0]], detection_lines)
trace_plots.append(p1)
if len(channels) > 1:
for i, channel in enumerate(channels[1:]):
p = figure(
x_range=p1.x_range,
y_axis_location="right", **plot_options)
p.yaxis.axis_label = None
p.xaxis.axis_label = None
p.min_border_bottom = 0
# p.min_border_top = 0
p_line = p.line(
x="time", y="data", source=trace_sources[channel],
color=data_color, line_width=1)
legend = Legend(items=[(channel, [p_line])])
p.add_layout(legend, 'right')
p.xaxis.formatter = datetick_formatter
# Add detection lines
detection_source = _get_pick_times(detections, channel)
detection_source.update(
{"pick_values": [[
int(min(stream.select(id=channel)[0].data) * .9),
int(max(stream.select(id=channel)[0].data) * .9)]
for _ in detection_source['picks']]})
detection_sources.update({
channel: ColumnDataSource(detection_source)})
detection_lines = MultiLine(
xs="picks", ys="pick_values", line_color="red",
line_dash="dashed", line_width=1)
p.add_glyph(detection_sources[channel], detection_lines)
trace_plots.append(p)
if i != len(channels) - 2:
p.xaxis.major_label_text_font_size = '0pt'
plots = gridplot([[map_plot, column(trace_plots)]])
previous_timestamps = {
channel: stream.select(id=channel)[0].stats.endtime
for channel in channels}
def update():
Logger.debug("Plot updating")
_stream = rt_client.stream.split().detrend()
if lowcut and highcut:
_stream.filter("bandpass", freqmin=lowcut, freqmax=highcut)
elif lowcut:
_stream.filter("highpass", lowcut)
elif highcut:
_stream.filter("lowpass", highcut)
_stream.merge()
for _i, _channel in enumerate(channels):
try:
_tr = _stream.select(id=_channel)[0]
except IndexError:
Logger.debug("No channel for {0}".format(_channel))
continue
new_samples = int(_tr.stats.sampling_rate * (
previous_timestamps[_channel] - _tr.stats.endtime))
if new_samples == 0:
Logger.debug("No new data for {0}".format(_channel))
continue
_new_data = _tr.slice(
starttime=previous_timestamps[_channel])
new_times = np.arange(
_new_data.stats.starttime.datetime,
(_tr.stats.endtime + _tr.stats.delta).datetime,
step=dt.timedelta(seconds=_tr.stats.delta))
new_data = {'time': new_times[1:], 'data': _new_data.data[1:]}
Logger.debug("Channl: {0}\tNew times: {1}\t New data: {2}".format(
_tr.id, new_data["time"].shape, new_data["data"].shape))
trace_sources[_channel].stream(
new_data=new_data,
rollover=int(plot_length * _tr.stats.sampling_rate))
new_picks = _get_pick_times(detections, _channel)
new_picks.update({
'pick_values': [
[int(np.nan_to_num(
trace_sources[_channel].data['data']).max() * .9),
int(np.nan_to_num(
trace_sources[_channel].data['data']).min() * .9)]
for _ in new_picks['picks']]})
detection_sources[_channel].data = new_picks
previous_timestamps.update({_channel: _tr.stats.endtime})
Logger.debug("New data plotted for {0}".format(_channel))
if not offline:
now = dt.datetime.utcnow()
else:
try:
now = max([tr.stats.endtime for tr in _stream]).datetime
except ValueError:
return
trace_plots[0].x_range.start = now - dt.timedelta(seconds=plot_length)
trace_plots[0].x_range.end = now
_update_template_alphas(
detections, tribe, decay=plot_length, now=now,
datastream=template_source)
Logger.info("Adding callback")
doc.add_periodic_callback(update, update_interval)
doc.title = "EQcorrscan Real-time plotter"
doc.add_root(plots)
Logger.info("Plot defined")
def _update_template_alphas(
See More Examples