Here are the examples of the python api bokeh.core.properties.value taken from open source projects. By voting up you can indicate which examples are most useful and appropriate.
12 Examples
3
Source : _message_graphs.py
with MIT License
from mnemocron
with MIT License
from mnemocron
def histogram_month_stacked(filename, data, namea, nameb):
bkh.reset_output()
bkh.output_file(filename, title=filename)
##### STACKED BAR GRAPH for monthly data
fig = bkh.figure(x_axis_type='datetime',
title='Messages per Month',
width=720, height=480)
fig.vbar_stack([namea, nameb], x='index',
width=timedelta(days=20),
color=colors, source=data,
legend=[value(x) for x in [namea, nameb]])
fig.xaxis.axis_label = 'Date'
fig.yaxis.axis_label = 'Message count'
bkh.show(fig)
return
'''
3
Source : test_annotations.py
with MIT License
from rthorst
with MIT License
from rthorst
def test_legend_item_with_value_label_and_different_data_sources_does_not_raise_a_validation_error():
legend_item = LegendItem()
gr_1 = GlyphRenderer(data_source=ColumnDataSource())
gr_2 = GlyphRenderer(data_source=ColumnDataSource())
legend_item.label = value('label')
legend_item.renderers = [gr_1, gr_2]
with mock.patch('bokeh.core.validation.check.log') as mock_logger:
check_integrity([legend_item])
assert mock_logger.error.call_count == 0
def test_legend_item_with_field_label_raises_error_if_field_not_in_cds():
3
Source : test_figure.py
with MIT License
from rthorst
with MIT License
from rthorst
def test_returns_renderers(self):
fruits = ['Apples', 'Pears', 'Nectarines', 'Plums', 'Grapes', 'Strawberries']
years = ["2015", "2016", "2017"]
colors = ["#c9d9d3", "#718dbf", "#e84d60"]
data = {'fruits' : fruits,
'2015' : [2, 1, 4, 3, 2, 4],
'2016' : [5, 3, 4, 2, 4, 6],
'2017' : [3, 2, 4, 4, 5, 3]}
source = ColumnDataSource(data=data)
p = bpf.figure()
renderers = p.hbar_stack(years, y='fruits', height=0.9, color=colors, source=source,
legend=[value(x) for x in years], name=years)
assert len(renderers) == 3
assert renderers[0].name == "2015"
assert renderers[1].name == "2016"
assert renderers[2].name == "2017"
class Test_vbar_stack(object):
3
Source : test_figure.py
with MIT License
from rthorst
with MIT License
from rthorst
def test_returns_renderers(self):
fruits = ['Apples', 'Pears', 'Nectarines', 'Plums', 'Grapes', 'Strawberries']
years = ["2015", "2016", "2017"]
colors = ["#c9d9d3", "#718dbf", "#e84d60"]
data = {'fruits' : fruits,
'2015' : [2, 1, 4, 3, 2, 4],
'2016' : [5, 3, 4, 2, 4, 6],
'2017' : [3, 2, 4, 4, 5, 3]}
source = ColumnDataSource(data=data)
p = bpf.figure()
renderers = p.vbar_stack(years, x='fruits', width=0.9, color=colors, source=source,
legend=[value(x) for x in years], name=years)
assert len(renderers) == 3
assert renderers[0].name == "2015"
assert renderers[1].name == "2016"
assert renderers[2].name == "2017"
def Test_figure_legends(obejct):
0
Source : quantify_profiles.py
with GNU Affero General Public License v3.0
from DennisSchmitz
with GNU Affero General Public License v3.0
from DennisSchmitz
def draw_stacked_bars(df, perc, sample="", parts=[], outfile="", colours=COLOURS):
"""
Takes a file of quantified read annotations by a pipeline (e.g. PZN)
and draws a stacked bar chart using Bokeh, creating an interactive
HTML file.
Input:
- A Pandas dataframe with all the required data
- The column name of Sample IDs (as string)
- The column names for the numbers ("parts", as list)
- The title of the figure (as string)
- The name of the output file (as string)
- The colours to be used for the bars (as list of strings - hexcodes)
Output:
- Interactive (Bokeh) stacked bar chart that visualises
the composition of each sample in your experiment
"""
# Set a comfortable length depending on the number of samples to show:
if len(df[sample]) > 40:
width = len(df[sample]) * 20
# Have the graph grow horizontally to accomodate large numbers of samples
elif len(df[sample]) > 25:
width = len(df[sample]) * 33
else:
# With a minimum of 800 to display the legend
width = 800
nr_fig = figure(
x_range=df[sample],
plot_height=800,
plot_width=width,
title="Composition of samples (read-based)",
toolbar_location=None,
tools="hover, pan",
tooltips="@%s $name: @$name" % sample,
)
nr_fig.vbar_stack(
parts,
x=sample,
width=0.9,
color=colours,
source=df,
legend=[value(x) for x in parts],
)
nr_fig.y_range.start = 0
nr_fig.x_range.range_padding = 0.1
nr_fig.xgrid.grid_line_color = None
nr_fig.axis.minor_tick_line_color = None
nr_fig.outline_line_color = None
nr_fig.legend.location = "top_left"
nr_fig.legend.orientation = "horizontal"
nr_fig.xaxis.major_label_orientation = 1
nr_panel = Panel(child=nr_fig, title="Absolute number of reads")
perc_fig = figure(
x_range=perc[sample],
plot_height=800,
plot_width=width,
title="Composition of samples (percentages)",
toolbar_location=None,
tools="hover, pan",
tooltips="@%s $name: @$name" % sample,
)
perc_fig.vbar_stack(
parts,
x=sample,
width=0.9,
color=colours,
source=perc,
legend=[value(x) for x in parts],
)
perc_fig.y_range.start = 0
perc_fig.x_range.range_padding = 0.1
perc_fig.xgrid.grid_line_color = None
perc_fig.axis.minor_tick_line_color = None
perc_fig.outline_line_color = None
perc_fig.legend.location = "top_left"
perc_fig.legend.orientation = "horizontal"
perc_fig.xaxis.major_label_orientation = 1
perc_panel = Panel(child=perc_fig, title="Percentage of reads")
tabs = Tabs(tabs=[nr_panel, perc_panel])
output_file(outfile)
save(tabs)
return None
def main():
0
Source : ui.py
with Apache License 2.0
from IntelLabs
with Apache License 2.0
from IntelLabs
def _create_plot() -> (Figure, ColumnDataSource):
"""Utility function for creating and styling the bar plot."""
global source, aspects, stats
pos_counts, neg_counts = (
[stats.loc[(asp, pol, False), "Quantity"] for asp in aspects] for pol in POLARITIES
)
np.seterr(divide="ignore")
source = ColumnDataSource(
data={
"aspects": aspects,
"POS": pos_counts,
"NEG": neg_counts,
"log-POS": np.log2(pos_counts),
"log-NEG": np.log2(neg_counts),
}
)
np.seterr(divide="warn")
p = figure(
plot_height=145,
sizing_mode="scale_width",
x_range=aspects,
toolbar_location="right",
tools="save, tap",
)
rs = [
p.vbar(
x=dodge("aspects", -0.207, range=p.x_range),
top="log-POS",
width=0.4,
source=source,
color="limegreen",
legend=value("POS"),
name="POS",
),
p.vbar(
x=dodge("aspects", 0.207, range=p.x_range),
top="log-NEG",
width=0.4,
source=source,
color="orangered",
legend=value("NEG"),
name="NEG",
),
]
for r in rs:
p.add_tools(
HoverTool(tooltips=[("Aspect", "@aspects"), (r.name, "@" + r.name)], renderers=[r])
)
p.add_layout(
Title(text=" " * 7 + "Sentiment Count (log scale)", align="left", text_font_size="23px"),
"left",
)
p.yaxis.ticker = []
p.y_range.start = 0
p.xgrid.grid_line_color = None
p.xaxis.major_label_text_font_size = "20pt"
p.legend.label_text_font_size = "20pt"
return p, source
def _update_events(events: DataTable, in_domain: bool) -> None:
0
Source : visualize.py
with Apache License 2.0
from IQTLabs
with Apache License 2.0
from IQTLabs
def visualize(
k_mers,
target_freqs,
optimized_freqs,
original_freqs=None,
title="Freqgen Optimization Results",
plot_height=400,
plot_width=1200,
show=True,
filepath="freqgen.html",
codons=False,
):
"""Creates a visualization of the results of a Freqgen optimization.
Note:
Currently, this function does not support the visualization of codon
optimization *and* *k*-mer optimization simultaneously.
Args:
k_mers (list): A list of the *k*-mers to use as the labels for the *x*-axis.
target_freqs (list): A list of the target frequencies in the same order as the `k_mers` argument.
optimized_freqs (list): A list of the resultant frequencies in the same order as the `k_mers` argument.
original_freqs (list, optional): A list of the original frequencies in the same order as the `k_mers` argument.
title (str, optional): A title to use for the graph. Defaults to "Freqgen Optimization Results".
plot_height (int, optional): The height for the graph. Defaults to 400.
plot_width (int, optional): The width for the graph. Defaults to 1200.
show (bool, optional): Whether to show the plot or simply return it. Defaults to True.
filepath (str, optional): The output filepath. Defaults to "freqgen.html".
codons (bool, optional): Whether codons are included in the input vectors. If they are, the *x*-axis legend will updated accordingly.
Note:
Codons must be denoted with a ``*`` in the ``k_mers`` argument. For example, the codon GAG should be passed as ``GAG*``
Returns:
bokeh.plotting.figure.Figure: A Bokeh figure containing the bar graph.
"""
# validate that all the codons that should be there are there
if codons and len([k_mer for k_mer in k_mers if k_mer.endswith("*")]) != 64:
raise ValueError("You appear to be passing an incomplete list of codons.")
codons_only = False
if all([k_mer.endswith("*") for k_mer in k_mers]) and codons:
k_mers = [k_mer[:-1] for k_mer in k_mers]
codons_only = True
output_file(filepath)
categories = ["Original", "Target", "Optimized"]
data = {"k_mers": k_mers, "Target": target_freqs, "Optimized": optimized_freqs}
# adjust spacing depending on if there's three bars or two
if not isinstance(original_freqs, type(None)):
offset = 0.25
data["Original"] = original_freqs
else:
offset = 0.15
# identify the greatest y value for setting bounds
y_max = max((max(target_freqs), max(optimized_freqs)))
if not isinstance(original_freqs, type(None)):
y_max = max((max(original_freqs), y_max))
source = ColumnDataSource(data=data)
p = figure(
x_range=k_mers,
plot_height=plot_height,
plot_width=plot_width,
title=title,
y_range=(0, 1.2 * y_max),
)
if not isinstance(original_freqs, type(None)):
p.vbar(
x=dodge("k_mers", -0.25, range=p.x_range),
top="Original",
width=0.2,
source=source,
color=Set2_3[0],
legend=value("Original"),
)
p.vbar(
x=dodge(
"k_mers",
0.0 if not isinstance(original_freqs, type(None)) else -offset,
range=p.x_range,
),
top="Target",
width=0.2,
source=source,
color=Set2_3[1],
legend=value("Target"),
)
p.vbar(
x=dodge("k_mers", offset, range=p.x_range),
top="Optimized",
width=0.2,
source=source,
color=Set2_3[2],
legend=value("Optimized"),
)
p.x_range.range_padding = 0.05
p.xgrid.grid_line_color = None
p.legend.location = "top_right"
p.legend.orientation = "horizontal"
p.legend.click_policy = "hide"
# decide the x-axis label
if codons_only:
p.xaxis.axis_label = "codon"
elif codons:
p.xaxis.axis_label = "k-mer (* denotes codon)"
else:
p.xaxis.axis_label = "k-mer"
if len(k_mers) >= 32:
p.xaxis.major_label_orientation = math.pi / 2
p.yaxis.axis_label = "frequency"
if show:
_show(p)
else:
save(p, filename=filepath)
return p
0
Source : NeoPredViz.py
with GNU Lesser General Public License v3.0
from MathOnco
with GNU Lesser General Public License v3.0
from MathOnco
def SummaryBarChart(self):
self.summaryData.sort_values(by=['Total'], inplace=True)
self.summaryData.reset_index(drop=True, inplace=True)
# Get factors for each Sample
factors = []
shared = []
clonal = []
subclonal = []
self.summaryData.rename(index=self.summaryData.Sample, inplace=True)
for sam in self.summaryData.Sample:
factors.append( (sam,"Total") )
clonal.append(self.summaryData.loc[sam,'Clonal'])
subclonal.append(self.summaryData.loc[sam,'Subclonal'])
shared.append(self.summaryData.loc[sam,'Shared'])
factors.append( (sam,"WB") )
clonal.append(self.summaryData.loc[sam,'Clonal_WB'])
subclonal.append(self.summaryData.loc[sam,'Subclonal_WB'])
shared.append(self.summaryData.loc[sam,'Shared_WB'])
factors.append( (sam,"SB") )
clonal.append(self.summaryData.loc[sam,'Clonal_SB'])
subclonal.append(self.summaryData.loc[sam,'Subclonal_SB'])
shared.append(self.summaryData.loc[sam,'Shared_SB'])
clonality = ['clonal','subclonal','shared']
source = ColumnDataSource(data=dict(
x=factors,
clonal=clonal,
subclonal=subclonal,
shared=shared
))
TOOLTIPS = [('Clonal', '@clonal'), ('Subclonal', '@subclonal'), ('Shared', '@shared')]
p = figure(x_range=FactorRange(*factors), tooltips=TOOLTIPS, height=400)
clonalityColors = ["#00a4ed","#ef4f25","#ede614"]
p.vbar_stack(clonality, x='x',width=0.9,color=clonalityColors, source=source, legend=[value(x) for x in clonality])
p.xaxis.major_label_orientation = np.pi / 2
p.xaxis.group_label_orientation = np.pi / 2
p.legend.orientation = "horizontal"
p.legend.location = "top_center"
p.xgrid.grid_line_color = None
p.ygrid.grid_line_color = None
p.xaxis.major_tick_line_color = None
p.yaxis.axis_label="Neoantigens"
p.x_range.range_padding = 0.1
return(p)
def ChordDiagram(self):
0
Source : draw_utils.py
with Apache License 2.0
from modernatx
with Apache License 2.0
from modernatx
def view_alignment(
aligned,
fontsize="9pt",
show_N=100,
colorscheme=aa_chemistry_simple,
boxwidth=9,
boxheight=15,
label_width=None,
show_descriptions=False,
show_grouping=False,
):
"""Bokeh sequence alignment view for protein and nucleic acid sequences
:sa: https://dmnfarrell.github.io/bioinformatics/bokeh-sequence-aligner
:param aligned: MultipleSeqAlignment object
:param fontsize: font size for text labels
:param show_N: size of sequence window (in number of sequence letters)
:param colorscheme: a weblogo ColorScheme object
:param boxwidth: column width of alignment
:param boxheight: row height of alignment
:param label_width: maximum length of row label; if None, extend to maximum label length
:param show_descriptions: if True, show SeqRecord description for each row
:param show_grouping: if True, highlight changes from reference in red against green background,
instead of using the residue colorscheme
:returns: A Bokeh plot of the Multiple Sequence Alignment.
"""
def get_colors(seqs, color_scheme):
"""make colors for letters in sequence
:param seqs: A string sequence.
:param color_scheme: A string.
:returns: a sequence of colors for each letter in seqs.
"""
# get colors
color_dict = convert_colorscheme_to_color_map(color_scheme, color_format="hex")
# assign colors to sequences
text = [i for s in list(seqs) for i in s]
return [color_dict[a] for a in text]
def get_colors_for_matching(seqs):
"""match/mismatch color scheme for show_grouping
:param seqs: Sequences for which colors need to be matched.
:returns: a list of colors (strings)
"""
refseq = seqs[0]
colors = list()
for seq in list(seqs):
for xs, ref_s in zip(seq, refseq):
colors.append(apply_matching_colorscheme(xs, ref_s, color_format="hex"))
return colors
# make sequence and id lists from the aligned object
seqs = [rec.seq for rec in (aligned)]
if show_descriptions:
labels = [f"{row} - {rec.description} ({rec.id})" for (row, rec) in enumerate(aligned)]
else:
labels = [f"{row} - {rec.id}" for (row, rec) in enumerate(aligned)]
if label_width:
labels = [label[:label_width] for label in labels]
else:
label_width = max(len(label) for label in labels)
text = [i for s in list(seqs) for i in s]
if show_grouping:
colors = get_colors_for_matching(seqs)
else:
colors = get_colors(seqs, colorscheme)
N = len(seqs[0])
S = len(seqs)
x = np.arange(1, N + 1)
# need to reverse y so that sequences are plotted top-to-bottom
y = np.arange(S - 1, -1, -1)
# creates a 2D grid of coords from the 1D arrays
xx, yy = np.meshgrid(x, y)
# flattens the arrays
gx = xx.ravel()
gy = yy.flatten()
# use recty for rect coords with an offset
recty = gy + 0.5
# now we can create the ColumnDataSource with all the arrays
source = bk.models.ColumnDataSource(dict(x=gx, y=gy, recty=recty, text=text, colors=colors))
plot_height = len(seqs) * boxheight + 50
x_range = bk.models.Range1d(0, N + 1, bounds="auto")
viewlen = min(show_N, N)
# view_range is for the close up view
view_range = (0, viewlen)
tools = "xpan,xwheel_zoom,reset,save"
# plot_width combines length of text labels and number of letters in sequence view window
# note: this part requires additional tuning; 5 pixel average width of y-axis labels is a guess
plot_width = int(5 * label_width) + boxwidth * viewlen + 40
# entire sequence view (no text, with zoom)
p = figure(
title=None,
plot_width=plot_width,
plot_height=50,
x_range=x_range,
y_range=(0, S),
tools=tools,
min_border=0,
toolbar_location="below",
)
rects = bk.models.glyphs.Rect(
x="x",
y="recty",
width=1,
height=1,
fill_color="colors",
line_color=None,
fill_alpha=0.6,
)
p.add_glyph(source, rects)
p.yaxis.visible = False
p.grid.visible = False
# sequence text view with ability to scroll along x axis
p1 = figure(
title=None,
plot_width=plot_width,
plot_height=plot_height,
x_range=view_range,
y_range=labels[::-1],
tools="xpan,reset,save",
min_border=0,
toolbar_location="below",
) # , lod_factor=1)
glyph = bk.models.glyphs.Text(
x="x",
y="y",
text="text",
text_align="center",
text_color="black",
text_font=value("monospace"),
text_font_size=fontsize,
)
rects = bk.models.glyphs.Rect(
x="x",
y="recty",
width=1,
height=1,
fill_color="colors",
line_color=None,
fill_alpha=0.4,
)
p1.add_glyph(source, glyph)
p1.add_glyph(source, rects)
p1.grid.visible = False
p1.xaxis.major_label_text_font_style = "bold"
p1.yaxis.minor_tick_line_width = 0
p1.yaxis.major_tick_line_width = 0
p = bk.layouts.gridplot([[p], [p1]], toolbar_location="below")
show(p)
return p
0
Source : bokeh_crossplot.py
with Apache License 2.0
from OpendTect
with Apache License 2.0
from OpendTect
def set_regression(self, selectedonly=False):
xlognm = self.xplotfig.xaxis.axis_label
ylognm = self.xplotfig.yaxis.axis_label
xs = None
ys = None
if selectedonly and len(self.well.logdata.selected.indices)>0:
xs = np.array(self.well.logdata.data.get(xlognm))[self.well.logdata.selected.indices]
ys = np.array(self.well.logdata.data.get(ylognm))[self.well.logdata.selected.indices]
else:
xs = np.array(self.well.logdata.data.get(xlognm))[self.well.logdataviewidx]
ys = np.array(self.well.logdata.data.get(ylognm))[self.well.logdataviewidx]
idx = np.logical_and(np.isfinite(xs), np.isfinite(ys))
xuse = xs[idx]
yuse = ys[idx]
lr = linear_model.LinearRegression()
X = xuse.reshape(-1,1)
lr.fit(X, yuse)
lbl = 'Standard: {} = {} * {:.4f} + {:.4f} (R\u00B2: {:.2f})'.format(ylognm, xlognm, lr.coef_[0],
lr.intercept_, lr.score(X, yuse))
self.legend.items[0].label = value(lbl)
xpl = np.array([np.nanmin(xs), np.nanmax(xs)])
ylr = xpl * lr.coef_[0] + lr.intercept_
rs = linear_model.RANSACRegressor(min_samples=0.9)
rs.fit(X, yuse)
yrs = xpl * rs.estimator_.coef_[0] + rs.estimator_.intercept_
self.regression['Source'].update(data={'x': xpl, 'ylr':ylr, 'yrs': yrs})
lbl = 'Robust: {} = {} * {:.4f} + {:.4f} (R\u00B2: {:.2f})'.format(ylognm, xlognm, rs.estimator_.coef_[0],
rs.estimator_.intercept_, rs.score(X,yuse))
self.legend.items[1].label = value(lbl)
def update_xlog(attr, old, new, track, controls, xplot):
0
Source : test_figure.py
with MIT License
from rthorst
with MIT License
from rthorst
def Test_figure_legends(obejct):
def test_glyph_label_is_legend_if_column_in_datasource_is_added_as_legend(self, p, source):
p.circle(x='x', y='y', legend='label', source=source)
legends = p.select(Legend)
assert len(legends) == 1
assert legends[0].items[0].label == {'field': 'label'}
def test_glyph_label_is_value_if_column_not_in_datasource_is_added_as_legend(self, p, source):
p.circle(x='x', y='y', legend='milk', source=source)
legends = p.select(Legend)
assert len(legends) == 1
assert legends[0].items[0].label == {'value': 'milk'}
def test_glyph_label_is_legend_if_column_in_df_datasource_is_added_as_legend(self, p, pd):
source = pd.DataFrame(data=dict(x=[1, 2, 3], y=[1, 2, 3], label=['a', 'b', 'c']))
p.circle(x='x', y='y', legend='label', source=source)
legends = p.select(Legend)
assert len(legends) == 1
assert legends[0].items[0].label == {'field': 'label'}
def test_glyph_label_is_value_if_column_not_in_df_datasource_is_added_as_legend(self, p, pd):
source = pd.DataFrame(data=dict(x=[1, 2, 3], y=[1, 2, 3], label=['a', 'b', 'c']))
p.circle(x='x', y='y', legend='milk', source=source)
legends = p.select(Legend)
assert len(legends) == 1
assert legends[0].items[0].label == {'value': 'milk'}
def test_glyph_label_is_just_added_directly_if_not_string(self, p, source):
p.circle(x='x', y='y', legend={'field': 'milk'}, source=source)
legends = p.select(Legend)
assert len(legends) == 1
assert legends[0].items[0].label == {'field': 'milk'}
def test_no_legend_if_legend_is_none(self, p, source):
p.circle(x='x', y='y', legend=None, source=source)
legends = p.select(Legend)
assert len(legends) == 0
def test_legend_added_when_legend_set(self, p, source):
renderer = p.circle(x='x', y='y', legend='label', source=source)
legends = p.select(Legend)
assert len(legends) == 1
assert legends[0].items[0].renderers == [renderer]
def test_legend_not_added_when_no_legend(self, p, source):
p.circle(x='x', y='y', source=source)
legends = p.select(Legend)
assert len(legends) == 0
def test_adding_legend_doesnt_work_when_legends_already_added(self, p, source):
p.add_layout(Legend())
p.add_layout(Legend())
with pytest.raises(RuntimeError):
p.circle(x='x', y='y', legend='label', source=source)
def test_multiple_renderers_correctly_added_to_legend(self, p, source):
square = p.square(x='x', y='y', legend='square', source=source)
circle = p.circle(x='x', y='y', legend='circle', source=source)
legends = p.select(Legend)
assert len(legends) == 1
assert legends[0].items[0].renderers == [square]
assert legends[0].items[0].label == value('square')
assert legends[0].items[1].renderers == [circle]
assert legends[0].items[1].label == value('circle')
def test_compound_legend_behavior_initiated_if_labels_are_same_on_multiple_renderers(self, p, source):
# 'compound legend string' is just a value
square = p.square(x='x', y='y', legend='compound legend string')
circle = p.circle(x='x', y='y', legend='compound legend string')
legends = p.select(Legend)
assert len(legends) == 1
assert legends[0].items[0].renderers == [square, circle]
assert legends[0].items[0].label == {'value': 'compound legend string'}
def test_compound_legend_behavior_initiated_if_labels_are_same_on_multiple_renderers_and_are_field(self, p, source):
# label is a field
square = p.square(x='x', y='y', legend='label', source=source)
circle = p.circle(x='x', y='y', legend='label', source=source)
legends = p.select(Legend)
assert len(legends) == 1
assert legends[0].items[0].renderers == [square, circle]
assert legends[0].items[0].label == {'field': 'label'}
# XXX (bev) this doesn't work yet because compound behaviour depends on renderer sources
# matching, but passing a df means every renderer gets its own new source
# def test_compound_legend_behavior_initiated_if_labels_are_same_on_multiple_renderers_and_are_field_with_df_source(self, p, pd):
# source = pd.DataFrame(data=dict(x=[1, 2, 3], y=[1, 2, 3], label=['a', 'b', 'c']))
# # label is a field
# square = p.square(x='x', y='y', legend='label', source=source)
# circle = p.circle(x='x', y='y', legend='label', source=source)
# legends = p.select(Legend)
# assert len(legends) == 1
# print(legends[0].items[0].renderers)
# assert legends[0].items[0].renderers == [square, circle]
# assert legends[0].items[0].label == {'field': 'label'}
#-----------------------------------------------------------------------------
# Dev API
#-----------------------------------------------------------------------------
@pytest.fixture
0
Source : plot.py
with Apache License 2.0
from spotify
with Apache License 2.0
from spotify
def scatter(self,
data_frame,
categorical_columns,
numeric_column,
size_column=None,
color_column=None,
color_order=None,
categorical_order_by='count',
categorical_order_ascending=False,
alpha=1.0,
marker='circle'):
"""Scatter chart.
Note:
To change the orientation set x_axis_type or y_axis_type
argument of the Chart object.
Args:
data_frame (pandas.DataFrame): Data source for the plot.
categorical_columns (str or list): Column name to plot on
the categorical axis.
numeric_column (str): Column name to plot on the numerical axis.
size_column (str, optional): Column name of numerical values
to plot on the size dimension.
color_column (str, optional): Column name to group by on
the color dimension.
color_order (list, optional):
List of values within the 'color_column' for
specific color sort.
categorical_order_by (str or array-like, optional):
Dimension for ordering the categorical axis. Default 'count'.
- 'count': Order categorical axis by the count of values.
- 'labels': Order categorical axis by the categorical labels.
- array-like object (list, tuple, np.array): New labels
to conform the categorical axis to.
categorical_order_ascending (bool, optional):
Sort order of the categorical axis. Default False.
alpha (float): Alpha value.
marker (str): marker type. Valid types:
'asterisk', 'circle', 'circle_cross', 'circle_x', 'cross',
'diamond', 'diamond_cross', 'hex', 'inverted_triangle',
'square', 'square_x', 'square_cross', 'triangle',
'x', '*', '+', 'o', 'ox', 'o+'
"""
vertical = self._chart.axes._vertical
if size_column is None:
size_column = 15
axis_factors = data_frame.groupby(categorical_columns).size()
order_length = getattr(categorical_order_by, "__len__", None)
if categorical_order_by == 'labels':
axis_factors = axis_factors.sort_index(
ascending=categorical_order_ascending).index
elif categorical_order_by == 'count':
axis_factors = axis_factors.sort_values(
ascending=categorical_order_ascending).index
# User-specified order.
elif order_length is not None:
axis_factors = categorical_order_by
else:
raise ValueError(
"""Must be 'count', 'labels', or a list of values.""")
colors, color_values = self._get_color_and_order(
data_frame, color_column, color_order)
# Apply factors to the axis.
self._set_categorical_axis_default_factors(vertical, axis_factors)
for color_value, color in zip(color_values, colors):
if color_column is None: # Single series
color_value = numeric_column
legend = None
sliced_data = data_frame
else:
legend = bokeh.core.properties.value(str(color_value))
sliced_data = data_frame[data_frame[color_column] ==
color_value]
# Filter to only relevant columns.
data_factors = sliced_data.set_index(categorical_columns).index
sliced_data = (
sliced_data[
[col for col in sliced_data.columns
if col in (
numeric_column, size_column)]])
source = self._named_column_data_source(
sliced_data, series_name=color_value)
source.add(data_factors, 'factors')
if vertical:
x_value, y_value = 'factors', numeric_column
else:
y_value, x_value = 'factors', numeric_column
self._plot_with_legend(
self._chart.figure.scatter,
legend_label=legend,
x=x_value,
y=y_value,
size=size_column,
fill_color=color,
line_color=color,
source=source,
marker=marker,
alpha=alpha
)
# Set legend defaults if there are multiple series.
if color_column is not None:
self._chart.style._apply_settings('legend')
return self._chart