We are pleased to announce the release of Bokeh 1.3!
This point release contains some new features. Highlights include:
- Long asked-for
FileInput
widget is added.#6096
- A brand new
DataCube
widget affords groups and aggregations of tabular data.#8100
- The
TextInput
widget now has a new per-keystroke capability.#8676
- Bug fixes to
DataTable
andDatePicker
.#8015
,#8921
,#8923
,#8934
- A new User’s Guide section discussing securing Bokeh Server applications.
#8919
- Can now set
source.data
directly from DataFrames#9052
For full details, see the CHANGELOG and Release Notes. Additionally, examples for each release are uploaded to CDN. Click here to download.
If you are using Anaconda, Bokeh can most easily be installed by executing the command conda install -c bokeh bokeh
. Otherwise, use pip install bokeh
.
Before getting to the release itself, a few project announcements:
First, the next release will be the last release to support Python 2. After that, starting with Bokeh 2.0, Python 3.5 will be the minimum supported Python version. We will publish a blog post soon outlining all expected Bokeh 2.0 changes.
Earlier this month, Bokeh passed 10k stars on GitHub and is about to pass 10k followers on Twitter. Thanks to everyone for your support and interest!
The Bokeh project has assumed direct control over the CDN that publishes BokehJS resources. This includes making a new base URL of cdn.bokeh.org
the primary location going forward. All existing links to cdn.pydata.org
will continue to function indefinitely, but users are encouraged to use the new URL starting immediately.
As a reminder, the Bokeh project has recently launched two new sites:
- A new project front page at bokeh.org
- An improved support forum at discourse.bokeh.org
Both these sites are great resources for new and old users, please use and share them often!
We have also created a Project Bokeh page on LinkedIn. Anyone who has contributed to Bokeh may now list Bokeh on their own profile. There is not much content there yet, but we hope to ramp things up in the coming months.
As part of all this increased emphasis on outreach, we have had a sharp new logotype produced:
Please feel free to use this anytime you are sharing or writing about Bokeh.
Finally, the July Fundraiser is still ongoing! Although we have just recently met our original goal of 1000 USD, every bit helps offset operational costs (e.g. to keep the CDN running), so please donate if you can, or help spread the word:
Click to Donate to the Bokeh Project
THANK YOU to everyone who donates to Bokeh! We will make a wrap-up blog post about the July fundraising experience in the near future.
Now, on to new features!
New File Input Widget
Another old issue falls! With some inspiration from an existing Holoviews implementation,#6096
File Open Dialog was added. Some follow-on work by new contributor jbeanland helped improve and refine the initial version.
The FileInput
can be configured with the standard HTML "accept"
attribute, and reports back the base filename, mime type, and base64-encoded file contents:
file_input = FileInput(accept=".csv,.json,.txt")callback = CustomJS(args=dict(para=para, file_input=file_input), code="""
para.text = "<p><b>filename:</b> " + file_input.filename + \
"<p><b>number of lines:</b> " + atob(file_input.value).split('\\n').length
""")file_input.js_on_change('value', callback)
Data Cube Widget for Aggregation
Recent new contributor jburgy really knocked it out of the park with sizeable PR to implement#8100
Option to collapse DataRable rows. The final result was actually an entirely new widget, DataCube
. Consider that you are starting with data like this:
source = ColumnDataSource(data=dict(
d0=['A', 'E', 'E', 'E', 'J', 'L', 'M'],
d1=['B', 'D', 'D', 'H', 'K', 'L', 'N'],
d2=['C', 'F', 'G', 'H', 'K', 'L', 'O'],
px=[10, 20, 30, 40, 50, 60, 70 ],
))
Then the DataCube
can produce a table with nested groupings or sub-groupings that you specify. It can evenly automatically aggregate those groups if you choose. Here is a DataCube
based on the data above:
The code for the above example looks like this:
target = ColumnDataSource(data=dict(row_indices=[], labels=[]))formatter = StringFormatter(font_style='bold')columns = [
TableColumn(field='d2', title='Name', width=40, sortable=False, formatter=formatter),
TableColumn(field='px', title='Price', width=40, sortable=False),
]grouping = [
GroupingInfo(getter='d0', aggregators=[SumAggregator(field_='px')]),
GroupingInfo(getter='d1', aggregators=[SumAggregator(field_='px')])
]cube = DataCube(source=source, columns=columns, grouping=grouping, target=target)
Hover Highlight for Stacked Glyphs
The previous release saw the addition of some really useful new methods for stacking aligned areas. But a feature was missing: they did not work with a hover highlight! That deficiency has been corrected and now stacked areas can be hovered just like any other glyph:
p.varea_stack(names, x='index', source=df, color=brewer['Oranges'][N],
hover_alpha=1.0, hover_color=brewer['Blues'][N])
Fine-Grained Text Input
Last, but not least, another new contributor russellburdt dropped in to add some additional capability to the existing TextInput
widget. Now not only can you get the value
when a user hits , you can also get value_input
which is updated on every keystroke:
Many thanks to all the new contributors to helped make this great release!
As always, anyone interested in helping out should drop by the Dev Chat Channel and say hello!
Thanks,
Bryan Van de Ven
Originally published at https://blog.bokeh.org on July 23, 2019.