python bokeh

Bokeh prides itself on being a library for interactive data visualization.

Bokeh以成为交互式数据可视化的库而自豪。

Unlike popular counterparts in the Python visualization space, like Matplotlib and Seaborn, Bokeh renders its graphics using HTML and JavaScript. This makes it a great candidate for building web-based dashboards and applications. However, it’s an equally powerful tool for exploring and understanding your data or creating beautiful custom charts for a project or report.

与Python可视化领域的流行同行(例如Matplotlib和Seaborn)不同,Bokeh使用HTML和JavaScript渲染其图形。 这使其非常适合构建基于Web的仪表板和应用程序。 但是,它是用于浏览和理解数据或为项目或报告创建漂亮的自定义图表的功能同样强大的工具。

Using a number of examples on a real-world dataset, the goal of this tutorial is to get you up and running with Bokeh.

通过使用真实数据集上的许多示例,本教程的目标是使您开始使用Bokeh。

You’ll learn how to:

您将学习如何:

  • Transform your data into visualizations, using Bokeh
  • Customize and organize your visualizations
  • Add interactivity to your visualizations
  • 使用Bokeh 将数据转换为可视化
  • 自定义和组织可视化
  • 为可视化添加交互性

So let’s jump in.

因此,让我们进入。

Free Bonus: Click here to get access to a chapter from Python Tricks: The Book that shows you Python’s best practices with simple examples you can apply instantly to write more beautiful + Pythonic code.

免费红利: 单击此处可访问Python技巧的一章:该书通过简单的示例向您展示了Python的最佳实践,您可以立即应用这些示例编写更精美的Pythonic代码。

从数据到可视化 (From Data to Visualization)

Building a visualization with Bokeh involves the following steps:

使用Bokeh构建可视化过程涉及以下步骤:

  • Prepare the data
  • Determine where the visualization will be rendered
  • Set up the figure(s)
  • Connect to and draw your data
  • Organize the layout
  • Preview and save your beautiful data creation
  • 准备数据
  • 确定可视化将在哪里呈现
  • 设置数字
  • 连接并绘制数据
  • 整理布局
  • 预览并保存您创建的漂亮数据

Let’s explore each step in more detail.

让我们更详细地探索每个步骤。

准备数据 (Prepare the Data)

Any good data visualization starts with—you guessed it—data. If you need a quick refresher on handling data in Python, definitely check out the growing number of excellent Real Python tutorials on the subject.

任何好的数据可视化都始于(您猜对了)数据。 如果您需要快速处理Python中的数据,请一定要查看有关该主题的越来越多的出色Real Python教程 。

This step commonly involves data handling libraries like Pandas and Numpy and is all about taking the required steps to transform it into a form that is best suited for your intended visualization.

此步骤通常涉及诸如Pandas和Numpy之类的数据处理库,并且全部涉及采取必要步骤将其转换为最适合您的预期可视化的形式。

确定可视化将在哪里渲染 (Determine Where the Visualization Will Be Rendered)

At this step, you’ll determine how you want to generate and ultimately view your visualization. In this tutorial, you’ll learn about two common options that Bokeh provides: generating a static HTML file and rendering your visualization inline in a Jupyter Notebook.

在这一步,您将确定如何生成并最终查看可视化效果。 在本教程中,您将了解Bokeh提供的两个常用选项:生成静态HTML文件以及在Jupyter Notebook中内嵌呈现可视化效果。

设置图 (Set up the Figure(s))

From here, you’ll assemble your figure, preparing the canvas for your visualization. In this step, you can customize everything from the titles to the tick marks. You can also set up a suite of tools that can enable various user interactions with your visualization.

在这里,您将组装图形,为可视化准备画布。 在此步骤中,您可以自定义从标题到刻度线的所有内容。 您还可以设置一套工具,以实现与可视化的各种用户交互。

连接并绘制数据 (Connect to and Draw Your Data)

Next, you’ll use Bokeh’s multitude of renderers to give shape to your data. Here, you have the flexibility to draw your data from scratch using the many available marker and shape options, all of which are easily customizable. This functionality gives you incredible creative freedom in representing your data.

接下来,您将使用Bokeh的大量渲染器来使数据成形。 在这里,您可以使用许多可用的标记和形状选项灵活地从头开始绘制数据,所有这些都可以轻松自定义。 此功能为您提供了令人难以置信的创作自由,可以代表您的数据。

Additionally, Bokeh has some built-in functionality for building things like stacked bar charts and plenty of examples for creating more advanced visualizations like network graphs and maps.

此外,Bokeh具有一些内置功能,可用于构建诸如堆积的条形图之类的东西,以及用于创建更高级的可视化效果(如网络图和地图)的大量示例。

整理布局 (Organize the Layout)

If you need more than one figure to express your data, Bokeh’s got you covered. Not only does Bokeh offer the standard grid-like layout options, but it also allows you to easily organize your visualizations into a tabbed layout in just a few lines of code.

如果您需要一个以上的数字来表达您的数据,那么Bokeh就可以满足您的要求。 Bokeh不仅提供标准的类似于网格的布局选项,而且还使您可以轻松地用几行代码将可视化内容组织到选项卡式布局中。

In addition, your plots can be quickly linked together, so a selection on one will be reflected on any combination of the others.

此外,您的地块可以快速链接在一起,因此一个地块的选择将反映在其他地块的任何组合上。

预览并保存您创建的漂亮数据 (Preview and Save Your Beautiful Data Creation)

Finally, it’s time to see what you created.

最后,是时候看看您创建的内容了。

Whether you’re viewing your visualization in a browser or notebook, you’ll be able to explore your visualization, examine your customizations, and play with any interactions that were added.

无论您是在浏览器中还是在笔记本电脑中查看可视化,您都可以浏览可视化,检查自定义设置并进行添加的交互。

If you like what you see, you can save your visualization to an image file. Otherwise, you can revisit the steps above as needed to bring your data vision to reality.

如果您喜欢所看到的内容,则可以将可视化文件保存到图像文件中。 否则,您可以根据需要重新查看上述步骤,以实现数据愿景。

That’s it! Those six steps are the building blocks for a tidy, flexible template that can be used to take your data from the table to the big screen:

而已! 这六个步骤是一个整洁,灵活的模板的构建块,可用于将数据从表移至大屏幕:

 """Bokeh Visualization Template"""Bokeh Visualization TemplateThis template is a general outline for turning your data into a
This template is a general outline for turning your data into a
visualization using Bokeh.
visualization using Bokeh.
"""
"""
# Data handling
# Data handling
import import pandas pandas as as pd
pd
import import numpy numpy as as npnp# Bokeh libraries
# Bokeh libraries
from from bokeh.io bokeh.io import import output_fileoutput_file , , output_notebook
output_notebook
from from bokeh.plotting bokeh.plotting import import figurefigure , , show
show
from from bokeh.models bokeh.models import import ColumnDataSource
ColumnDataSource
from from bokeh.layouts bokeh.layouts import import rowrow , , columncolumn , , gridplot
gridplot
from from bokeh.models.widgets bokeh.models.widgets import import TabsTabs , , PanelPanel# Prepare the data# Prepare the data# Determine where the visualization will be rendered
# Determine where the visualization will be rendered
output_fileoutput_file (( 'filename.html''filename.html' )  )  # Render to static HTML, or
# Render to static HTML, or
output_notebookoutput_notebook ()  ()  # Render inline in a Jupyter Notebook# Render inline in a Jupyter Notebook# Set up the figure(s)
# Set up the figure(s)
fig fig = = figurefigure ()  ()  # Instantiate a figure() object# Instantiate a figure() object# Connect to and draw the data# Connect to and draw the data# Organize the layout# Organize the layout# Preview and save
# Preview and save
showshow (( figfig )  )  # See what I made, and save if I like it
# See what I made, and save if I like it

Some common code snippets that are found in each step are previewed above, and you’ll see how to fill out the rest as you move through the rest of the tutorial!

上面已预览了每个步骤中发现的一些常见代码段,在本教程的其余部分中,您将看到如何填写其余部分!

产生你的第一个数字 (Generating Your First Figure)

There are multiple ways to output your visualization in Bokeh. In this tutorial, you’ll see these two options:

有多种方法可以在Bokeh中输出可视化效果 。 在本教程中,您将看到以下两个选项:

  • output_file('filename.html') will write the visualization to a static HTML file.
  • output_notebook() will render your visualization directly in a Jupyter Notebook.
  • output_file('filename.html')会将可视化内容写入静态HTML文件。
  • output_notebook()将直接在Jupyter Notebook中呈现可视化效果。

It’s important to note that neither function will actually show you the visualization. That doesn’t happen until show() is called. However, they will ensure that, when show() is called, the visualization appears where you intend it to.

重要的是要注意,这两个功能实际上都不会为您显示可视化效果。 在调用show()之前不会发生这种情况。 但是,它们将确保在调用show()时,可视化内容将显示在您想要的位置。

By calling both output_file() and output_notebook() in the same execution, the visualization will be rendered both to a static HTML file and inline in the notebook. However, if for whatever reason you run multiple output_file() commands in the same execution, only the last one will be used for rendering.

通过在同一执行中同时调用output_file()output_notebook() ,可视化文件将呈现为静态HTML文件并在笔记本中内联。 但是,如果出于某种原因在同一执行中运行多个output_file()命令,则仅使用最后一个命令进行渲染。

This is a great opportunity to give you your first glimpse at a default Bokeh figure() using output_file():

这是一个很好的机会,可以使用output_file()默认的Bokeh figure() output_file()

As you can see, a new browser window opened with a tab called Empty Bokeh Figure and an empty figure. Not shown is the file generated with the name output_file_test.html in your current working directory.

如您所见,将打开一个新的浏览器窗口,其中包含一个名为Empty Bokeh Figure和一个空图的选项卡。 在当前工作目录中未显示名称为output_file_test.html的文件。

If you were to run the same code snippet with output_notebook() in place of output_file(), assuming you have a Jupyter Notebook fired up and ready to go, you will get the following:

如果要使用output_notebook()代替output_file()运行相同的代码段,并假设已启动Jupyter Notebook并准备就绪,则将获得以下内容:

 # Bokeh Libraries
# Bokeh Libraries
from from bokeh.io bokeh.io import import output_notebook
output_notebook
from from bokeh.plotting bokeh.plotting import import figurefigure , , showshow# The figure will be right in my Jupyter Notebook
# The figure will be right in my Jupyter Notebook
output_notebookoutput_notebook ()()# Set up a generic figure() object
# Set up a generic figure() object
fig fig = = figurefigure ()()# See what it looks like
# See what it looks like
showshow (( figfig )
)

As you can see, the result is the same, just rendered in a different location.

如您所见,结果是相同的,只是在不同的位置呈现。

More information about both output_file() and output_notebook() can be found in the Bokeh official docs.

可以在Bokeh官方文档中找到有关output_file()output_notebook()更多信息。

Note: Sometimes, when rendering multiple visualizations sequentially, you’ll see that past renders are not being cleared with each execution. If you experience this, import and run the following between executions:

注意:有时,当顺序渲染多个可视化对象时,您会看到每次执行都不会清除过去的渲染。 如果遇到这种情况,请在两次执行之间导入并运行以下命令:

Before moving on, you may have noticed that the default Bokeh figure comes pre-loaded with a toolbar. This is an important sneak preview into the interactive elements of Bokeh that come right out of the box. You’ll find out more about the toolbar and how to configure it in the Adding Interaction section at the end of this tutorial.

在继续之前,您可能已经注意到默认的Bokeh图形已预装了工具栏。 这是开箱即用的Bokeh交互元素的重要预览。 您将在本教程结尾的“ 添加交互”部分中找到有关工具栏以及如何配置它的更多信息。

为数据做好准备 (Getting Your Figure Ready for Data)

Now that you know how to create and view a generic Bokeh figure either in a browser or Jupyter Notebook, it’s time to learn more about how to configure the figure() object.

既然您知道如何在浏览器或Jupyter Notebook中创建和查看通用的Bokeh人物,是时候了解有关如何配置fig figure()对象的更多信息了。

The figure() object is not only the foundation of your data visualization but also the object that unlocks all of Bokeh’s available tools for visualizing data. The Bokeh figure is a subclass of the Bokeh Plot object, which provides many of the parameters that make it possible to configure the aesthetic elements of your figure.

figure()对象不仅是数据可视化的基础,而且是解锁Bokeh可用的用于可视化数据的所有工具的对象。 散景图是“ 散景图”对象的子类,该对象提供许多参数,这些参数使您可以配置图形的美学元素。

To show you just a glimpse into the customization options available, let’s create the ugliest figure ever:

为了让您了解可用的自定义选项,让我们创建有史以来最丑陋的人物:

 # Bokeh Libraries
# Bokeh Libraries
from from bokeh.io bokeh.io import import output_notebook
output_notebook
from from bokeh.plotting bokeh.plotting import import figurefigure , , showshow# The figure will be rendered inline in my Jupyter Notebook
# The figure will be rendered inline in my Jupyter Notebook
output_notebookoutput_notebook ()()# Example figure
# Example figure
fig fig = = figurefigure (( background_fill_colorbackground_fill_color == 'gray''gray' ,,background_fill_alphabackground_fill_alpha == 0.50.5 ,,border_fill_colorborder_fill_color == 'blue''blue' ,,border_fill_alphaborder_fill_alpha == 0.250.25 ,,plot_heightplot_height == 300300 ,,plot_widthplot_width == 500500 ,,h_symmetryh_symmetry == TrueTrue ,,x_axis_labelx_axis_label == 'X Label''X Label' ,,x_axis_typex_axis_type == 'datetime''datetime' ,,x_axis_locationx_axis_location == 'above''above' ,,x_rangex_range == (( '2018-01-01''2018-01-01' , , '2018-06-30''2018-06-30' ),),y_axis_labely_axis_label == 'Y Label''Y Label' ,,y_axis_typey_axis_type == 'linear''linear' ,,y_axis_locationy_axis_location == 'left''left' ,,y_rangey_range == (( 00 , , 100100 ),),titletitle == 'Example Figure''Example Figure' ,,title_locationtitle_location == 'right''right' ,,toolbar_locationtoolbar_location == 'below''below' ,,toolstools == 'save''save' ))# See what it looks like
# See what it looks like
showshow (( figfig )
)

Once the figure() object is instantiated, you can still configure it after the fact. Let’s say you want to get rid of the gridlines:

实例化fig figure()对象后,您仍然可以在配置之后进行配置。 假设您要摆脱网格线:

The gridline properties are accessible via the figure’s grid attribute. In this case, setting grid_line_color to None effectively removes the gridlines altogether. More details about figure attributes can be found below the fold in the Plot class documentation.

可通过图形的grid属性访问gridline属性。 在这种情况下,将grid_line_color设置为None可以完全删除网格线。 有关图形属性的更多详细信息,可以在Plot类文档的首屏下面找到。

Note: If you’re working in a notebook or IDE with auto-complete functionality, this feature can definitely be your friend! With so many customizable elements, it can be very helpful in discovering the available options:

注意:如果您使用的是具有自动完成功能的笔记本电脑或IDE,那么此功能绝对可以成为您的朋友! 有这么多可定制的元素,在发现可用选项时会非常有帮助:

Otherwise, doing a quick web search, with the keyword bokeh and what you are trying to do, will generally point you in the right direction.

否则,使用关键字bokeh和您要尝试的操作进行快速的网络搜索通常会为您指明正确的方向。

There is tons more I could touch on here, but don’t feel like you’re missing out. I’ll make sure to introduce different figure tweaks as the tutorial progresses. Here are some other helpful links on the topic:

在这里,我还有很多其他可以触及的地方,但不要觉得您错过了。 随着教程的进行,我将确保引入不同的图形调整。 这是有关此主题的其他一些有用的链接:

  • The Bokeh Plot Class is the superclass of the figure() object, from which figures inherit a lot of their attributes.
  • The Figure Class documentation is a good place to find more detail about the arguments of the figure() object.
  • 散景图类fig figure()对象的超类, figure()从中继承许多属性。
  • Figure Class文档是查找关于figure()对象的参数的更多详细信息的好地方。

Here are a few specific customization options worth checking out:

以下是一些值得一试的自定义选项:

  • Text Properties covers all the attributes related to changing font styles, sizes, colors, and so forth.
  • TickFormatters are built-in objects specifically for formatting your axes using Python-like string formatting syntax.
  • 文本属性涵盖与更改字体样式,大小,颜色等有关的所有属性。
  • TickFormatters是内置对象,专门用于使用类似Python的字符串格式语法来格式化轴。

Sometimes, it isn’t clear how your figure needs to be customized until it actually has some data visualized in it, so next you’ll learn how to make that happen.

有时,在实际显示一些数据之前,还不清楚如何对您的图形进行自定义,因此接下来您将学习如何实现这一目标。

使用字形绘制数据 (Drawing Data With Glyphs)

An empty figure isn’t all that exciting, so let’s look at glyphs: the building blocks of Bokeh visualizations. A glyph is a vectorized graphical shape or marker that is used to represent your data, like a circle or square. More examples can be found in the Bokeh gallery. After you create your figure, you are given access to a bevy of configurable glyph methods.

一个空虚的图形并不是那么令人兴奋,所以让我们看一下字形:Bokeh可视化的基础。 字形是矢量化的图形形状或标记,用于表示您的数据,例如圆形或正方形。 可以在Bokeh画廊中找到更多示例。 创建图形之后,您就可以访问一系列可配置的字形方法 。

Let’s start with a very basic example, drawing some points on an x-y coordinate grid:

让我们从一个非常基本的示例开始,在xy坐标网格上绘制一些点:

 # Bokeh Libraries
# Bokeh Libraries
from from bokeh.io bokeh.io import import output_file
output_file
from from bokeh.plotting bokeh.plotting import import figurefigure , , showshow# My x-y coordinate data
# My x-y coordinate data
x x = = [[ 11 , , 22 , , 11 ]
]
y y = = [[ 11 , , 11 , , 22 ]]# Output the visualization directly in the notebook
# Output the visualization directly in the notebook
output_fileoutput_file (( 'first_glyphs.html''first_glyphs.html' , , titletitle == 'First Glyphs''First Glyphs' ))# Create a figure with no toolbar and axis ranges of [0,3]
# Create a figure with no toolbar and axis ranges of [0,3]
fig fig = = figurefigure (( titletitle == 'My Coordinates''My Coordinates' ,,plot_heightplot_height == 300300 , , plot_widthplot_width == 300300 ,,x_rangex_range == (( 00 , , 33 ), ), y_rangey_range == (( 00 , , 33 ),),toolbar_locationtoolbar_location == NoneNone ))# Draw the coordinates as circles
# Draw the coordinates as circles
figfig .. circlecircle (( xx == xx , , yy == yy ,,colorcolor == 'green''green' , , sizesize == 1010 , , alphaalpha == 0.50.5 ))# Show plot
# Show plot
showshow (( figfig )
)

Once your figure is instantiated, you can see how it can be used to draw the x-y coordinate data using customized circle glyphs.

实例化图形后,您将看到如何使用它使用定制的circle字形来绘制xy坐标数据。

Here are a few categories of glyphs:

以下是字形的一些类别:

  • Marker includes shapes like circles, diamonds, squares, and triangles and is effective for creating visualizations like scatter and bubble charts.

  • Line covers things like single, step, and multi-line shapes that can be used to build line charts.

  • Bar/Rectangle shapes can be used to create traditional or stacked bar (hbar) and column (vbar) charts as well as waterfall or gantt charts.

  • 标记包括圆形,菱形,正方形和三角形等形状,对于创建散点图和气泡图等可视化效果非常有效。

  • 折线涵盖可以用于构建折线图的单线,阶梯和多线形状。

  • 条形/矩形形状可用于创建传统的或堆叠的条形图( hbar )和柱形图( vbar )以及瀑布图或甘特图。

Information about the glyphs above, as well as others, can be found in Bokeh’s Reference Guide.

有关上述字形以及其他字形的信息,可以在Bokeh的参考指南中找到 。

These glyphs can be combined as needed to fit your visualization needs. Let’s say I want to create a visualization that shows how many words I wrote per day to make this tutorial, with an overlaid trend line of the cumulative word count:

这些字形可以根据需要进行组合,以满足您的可视化需求。 假设我想创建一个可视化效果,以显示我每天编写多少个单词来制作本教程,并使用累积单词数的叠加趋势线进行显示:

To combine the columns and lines on the figure, they are simply created using the same figure() object.

要组合图形上的列和线,只需使用相同的figure()对象即可创建它们。

Additionally, you can see above how seamlessly a legend can be created by setting the legend property for each glyph. The legend was then moved to the upper left corner of the plot by assigning 'top_left' to fig.legend.location.

此外,您可以在上方看到通过设置每个字形的legend属性如何无缝创建legend 。 然后通过为fig.legend.location分配'top_left' ,将'top_left'移至图的fig.legend.location

You can check out much more info about styling legends. Teaser: they will show up again later in the tutorial when we start digging into interactive elements of the visualization.

您可以查看有关样式图例的更多信息 。 预告片:当我们开始深入研究可视化的交互元素时,它们将在本教程的稍后部分再次显示。

快速了解数据 (A Quick Aside About Data)

Anytime you are exploring a new visualization library, it’s a good idea to start with some data in a domain you are familiar with. The beauty of Bokeh is that nearly any idea you have should be possible. It’s just a matter of how you want to leverage the available tools to do so.

每当您探索新的可视化库时,最好从熟悉的域中的一些数据开始。 散景的魅力在于,您几乎可以拥有任何想法。 只是您要如何利用可用工具来这样做。

The remaining examples will use publicly available data from Kaggle, which has information about the National Basketball Association’s (NBA) 2017-18 season, specifically:

其余示例将使用Kaggle的公开数据,该数据包含有关美国国家篮球协会(NBA)2017-18赛季的信息 ,尤其是:

  • 2017-18_playerBoxScore.csv: game-by-game snapshots of player statistics
  • 2017-18_teamBoxScore.csv: game-by-game snapshots of team statistics
  • 2017-18_standings.csv: daily team standings and rankings
  • 2017-18_playerBoxScore.csv :玩家统计数据的逐个游戏快照
  • 2017-18_teamBoxScore.csv :团队统计数据的逐场快照
  • 2017-18_standings.csv :每日团队排名和排名

This data has nothing to do with what I do for work, but I love basketball and enjoy thinking about ways to visualize the ever-growing amount of data associated with it.

这些数据与我的工作无关,但我喜欢篮球,喜欢思考如何可视化与之相关的不断增长的数据量。

If you don’t have data to play with from school or work, think about something you’re interested in and try to find some data related to that. It will go a long way in making both the learning and the creative process faster and more enjoyable!

如果您没有从学校或工作中获得的数据,请考虑您感兴趣的事情,并尝试查找与此相关的数据。 这将使学习和创作过程更快,更有趣,这将大有帮助!

To follow along with the examples in the tutorial, you can download the datasets from the links above and read them into a Pandas DataFrame using the following commands:

要遵循本教程中的示例,您可以从上面的链接下载数据集,并使用以下命令将其读取到Pandas DataFrame

 import import pandas pandas as as pdpd# Read the csv files
# Read the csv files
player_stats player_stats = = pdpd .. read_csvread_csv (( '2017-18_playerBoxScore.csv''2017-18_playerBoxScore.csv' , , parse_datesparse_dates == [[ 'gmDate''gmDate' ])
])
team_stats team_stats = = pdpd .. read_csvread_csv (( '2017-18_teamBoxScore.csv''2017-18_teamBoxScore.csv' , , parse_datesparse_dates == [[ 'gmDate''gmDate' ])
])
standings standings = = pdpd .. read_csvread_csv (( '2017-18_standings.csv''2017-18_standings.csv' , , parse_datesparse_dates == [[ 'stDate''stDate' ])
])

This code snippet reads the data from the three CSV files and automatically interprets the date columns as datetime objects.

此代码段从三个CSV文件中读取数据,并将日期列自动解释为datetime对象 。

It’s now time to get your hands on some real data.

现在是时候掌握一些真实数据了。

使用ColumnDataSource对象 (Using the ColumnDataSource Object)

The examples above used Python lists and Numpy arrays to represent the data, and Bokeh is well equipped to handle these datatypes. However, when it comes to data in Python, you are most likely going to come across Python dictionaries and Pandas DataFrames, especially if you’re reading in data from a file or external data source.

上面的示例使用Python列表和Numpy数组表示数据,并且Bokeh具备处理这些数据类型的能力。 但是,当涉及到Python中的数据时,您很可能会遇到Python字典和Pandas DataFrames ,尤其是当您从文件或外部数据源中读取数据时。

Bokeh is well equipped to work with these more complex data structures and even has built-in functionality to handle them, namely the ColumnDataSource.

Bokeh能够很好地处理这些更复杂的数据结构,甚至具有处理它们的内置功能,即ColumnDataSource

You may be asking yourself, “Why use a ColumnDataSource when Bokeh can interface with other data types directly?”

您可能会问自己:“当Bokeh可直接与其他数据类型接口时,为什么要使用ColumnDataSource ?”

For one, whether you reference a list, array, dictionary, or DataFrame directly, Bokeh is going to turn it into a ColumnDataSource behind the scenes anyway. More importantly, the ColumnDataSource makes it much easier to implement Bokeh’s interactive affordances.

首先,无论您直接引用列表,数组,字典还是DataFrame,Bokeh都会将其变成幕后的ColumnDataSource 。 更重要的是, ColumnDataSource使实现Bokeh的交互式功能更加容易。

The ColumnDataSource is foundational in passing the data to the glyphs you are using to visualize. Its primary functionality is to map names to the columns of your data. This makes it easier for you to reference elements of your data when building your visualization. It also makes it easier for Bokeh to do the same when building your visualization.

ColumnDataSource是将数据传递到用于可视化的字形的基础。 它的主要功能是将名称映射到数据的列。 这使您在建立可视化文件时更容易引用数据元素。 这也使Bokeh在构建可视化文件时更容易执行相同的操作。

The ColumnDataSource can interpret three types of data objects:

ColumnDataSource可以解释三种类型的数据对象:

  • Python dict: The keys are names associated with the respective value sequences (lists, arrays, and so forth).

  • Pandas DataFrame: The columns of the DataFrame become the reference names for the ColumnDataSource.

  • Pandas groupby: The columns of the ColumnDataSource reference the columns as seen by calling groupby.describe().

  • Python dict :键是与各个值序列(列表,数组等)关联的名称。

  • 熊猫DataFrame :对的列DataFrame成为参考名称ColumnDataSource

  • Pandas groupbyColumnDataSource的列引用通过调用groupby.describe()看到的列。

Let’s start by visualizing the race for first place in the NBA’s Western Conference in 2017-18 between the defending champion Golden State Warriors and the challenger Houston Rockets. The daily win-loss records of these two teams is stored in a DataFrame named west_top_2:

首先让我们想象一下卫冕冠军金州勇士队和挑战者休斯顿火箭队之间在2017-18赛季NBA西部决赛中的第一场比赛。 这两个团队的每日输赢记录存储在一个名为west_top_2

>>>
>>>

 >>>  west_top_2 = ( standings [( standings [ 'teamAbbr' ] == 'HOU' ) | ( standings [ 'teamAbbr' ] == 'GS' )]
...               . loc [:, [ 'stDate' , 'teamAbbr' , 'gameWon' ]]
...               . sort_values ([ 'teamAbbr' , 'stDate' ]))
>>>  west_top_2 . head ()stDate teamAbbr  gameWon
9   2017-10-17       GS        0
39  2017-10-18       GS        0
69  2017-10-19       GS        0
99  2017-10-20       GS        1
129 2017-10-21       GS        1

From here, you can load this DataFrame into two ColumnDataSource objects and visualize the race:

从这里,您可以将此DataFrame加载到两个ColumnDataSource对象中,并可视化种族:

Notice how the respective ColumnDataSource objects are referenced when creating the two lines. You simply pass the original column names as input parameters and specify which ColumnDataSource to use via the source property.

请注意,创建这两行时,如何分别引用ColumnDataSource对象。 您只需将原始列名作为输入参数传递,然后通过source属性指定要使用的ColumnDataSource

The visualization shows the tight race throughout the season, with the Warriors building a pretty big cushion around the middle of the season. However, a bit of a late-season slide allowed the Rockets to catch up and ultimately surpass the defending champs to finish the season as the Western Conference number-one seed.

可视化显示了整个赛季的紧张比赛,勇士在整个赛季中期建立了相当大的缓冲。 然而,季后赛的一些下滑让火箭得以追赶,并最终超越了卫冕冠军,成为了西部联盟的头号种子。

Note: In Bokeh, you can specify colors either by name, hex value, or RGB color code.

注意:在散景中,您可以按名称,十六进制值或RGB颜色代码指定颜色。

For the visualization above, a color is being specified for the respective lines representing the two teams. Instead of using CSS color names like 'red' for the Rockets and 'blue' for the Warriors, you might have wanted to add a nice visual touch by using the official team colors in the form of hex color codes. Alternatively, you could have used tuples representing RGB color codes: (206, 17, 65) for the Rockets, (0, 107, 182) for the Warriors.

对于上面的可视化,正在为代表两个团队的相应行指定颜色。 与其使用CSS颜色名称(例如,火箭使用'red'和勇士使用'blue' ,您可能不希望通过使用十六进制颜色代码形式的官方团队颜色来添加良好的视觉效果。 表示RGB颜色代码或者,可以在已使用的元组: (206, 17, 65)为火箭, (0, 107, 182)为勇士。

Bokeh provides a helpful list of CSS color names categorized by their general hue. Also, htmlcolorcodes.com is a great site for finding CSS, hex, and RGB color codes.

散景提供了有用CSS颜色名称列表,并按其一般色调进行了分类 。 另外, htmlcolorcodes.com是查找CSS,十六进制和RGB颜色代码的好网站。

ColumnDataSource objects can do more than just serve as an easy way to reference DataFrame columns. The ColumnDataSource object has three built-in filters that can be used to create views on your data using a CDSView object:

ColumnDataSource对象不仅可以作为引用DataFrame列的简便方法,还可以做更多的事情。 ColumnDataSource对象具有三个内置过滤器,可用于使用CDSView对象在数据上创建视图:

  • GroupFilter selects rows from a ColumnDataSource based on a categorical reference value
  • IndexFilter filters the ColumnDataSource via a list of integer indices
  • BooleanFilter allows you to use a list of boolean values, with True rows being selected
  • GroupFilter根据分类参考值从ColumnDataSource选择行
  • IndexFilter通过整数索引列表过滤ColumnDataSource
  • BooleanFilter允许您使用boolean值列表,并选择True

In the previous example, two ColumnDataSource objects were created, one each from a subset of the west_top_2 DataFrame. The next example will recreate the same output from one ColumnDataSource based on all of west_top_2 using a GroupFilter that creates a view on the data:

在前面的示例中,创建了两个ColumnDataSource对象,每个对象来自west_top_2 DataFrame的子集。 下一个示例将使用GroupFilter来创建基于数据的视图,基于所有west_top_2从一个ColumnDataSource重新创建相同的输出:

 # Bokeh libraries
# Bokeh libraries
from from bokeh.plotting bokeh.plotting import import figurefigure , , show
show
from from bokeh.io bokeh.io import import output_file
output_file
from from bokeh.models bokeh.models import import ColumnDataSourceColumnDataSource , , CDSViewCDSView , , GroupFilterGroupFilter# Output to file
# Output to file
output_fileoutput_file (( 'west-top-2-standings-race.html''west-top-2-standings-race.html' , , titletitle == 'Western Conference Top 2 Teams Wins Race''Western Conference Top 2 Teams Wins Race' ))# Create a ColumnDataSource
# Create a ColumnDataSource
west_cds west_cds = = ColumnDataSourceColumnDataSource (( west_top_2west_top_2 ))# Create views for each team
# Create views for each team
rockets_view rockets_view = = CDSViewCDSView (( sourcesource == west_cdswest_cds ,,filtersfilters == [[ GroupFilterGroupFilter (( column_namecolumn_name == 'teamAbbr''teamAbbr' , , groupgroup == 'HOU''HOU' )])
)])
warriors_view warriors_view = = CDSViewCDSView (( sourcesource == west_cdswest_cds ,,filtersfilters == [[ GroupFilterGroupFilter (( column_namecolumn_name == 'teamAbbr''teamAbbr' , , groupgroup == 'GS''GS' )]))])# Create and configure the figure
# Create and configure the figure
west_fig west_fig = = figurefigure (( x_axis_typex_axis_type == 'datetime''datetime' ,,plot_heightplot_height == 300300 , , plot_widthplot_width == 600600 ,,titletitle == 'Western Conference Top 2 Teams Wins Race, 2017-18''Western Conference Top 2 Teams Wins Race, 2017-18' ,,x_axis_labelx_axis_label == 'Date''Date' , , y_axis_labely_axis_label == 'Wins''Wins' ,,toolbar_locationtoolbar_location == NoneNone ))# Render the race as step lines
# Render the race as step lines
west_figwest_fig .. stepstep (( 'stDate''stDate' , , 'gameWon''gameWon' ,,sourcesource == west_cdswest_cds , , viewview == rockets_viewrockets_view ,,colorcolor == '#CE1141''#CE1141' , , legendlegend == 'Rockets''Rockets' )
)
west_figwest_fig .. stepstep (( 'stDate''stDate' , , 'gameWon''gameWon' ,,sourcesource == west_cdswest_cds , , viewview == warriors_viewwarriors_view ,,colorcolor == '#006BB6''#006BB6' , , legendlegend == 'Warriors''Warriors' ))# Move the legend to the upper left corner
# Move the legend to the upper left corner
west_figwest_fig .. legendlegend .. location location = = 'top_left''top_left'# Show the plot
# Show the plot
showshow (( west_figwest_fig )
)

Notice how the GroupFilter is passed to CDSView in a list. This allows you to combine multiple filters together to isolate the data you need from the ColumnDataSource as needed.

注意如何将GroupFilter传递到列表中的CDSView 。 这使您可以将多个过滤器组合在一起,以根据需要将所需的数据与ColumnDataSource隔离开。

For information about integrating data sources, check out the Bokeh user guide’s post on the ColumnDataSource and other source objects available.

有关集成数据源的信息,请查阅ColumnDataSource和其他可用源对象上的Bokeh用户指南。

The Western Conference ended up being an exciting race, but say you want to see if the Eastern Conference was just as tight. Not only that, but you’d like to view them in a single visualization. This is a perfect segue to the next topic: layouts.

西部会议最终是一场激动人心的比赛,但您要说一下东部会议是否同样紧张。 不仅如此,您还想在一个可视化视图中查看它们。 这是下一个主题的完美选择:布局。

使用布局组织多个可视化 (Organizing Multiple Visualizations With Layouts)

The Eastern Conference standings came down to two rivals in the Atlantic Division: the Boston Celtics and the Toronto Raptors. Before replicating the steps used to create west_top_2, let’s try to put the ColumnDataSource to the test one more time using what you learned above.

东部联盟的排名下降到了大西洋赛区的两个对手:波士顿凯尔特人队和多伦多猛龙队。 在复制用于创建west_top_2的步骤之前,让我们尝试使用上面学到的方法west_top_2 ColumnDataSource进行测试。

In this example, you’ll see how to feed an entire DataFrame into a ColumnDataSource and create views to isolate the relevant data:

在此示例中,您将看到如何将整个DataFrame馈入ColumnDataSource并创建视图以隔离相关数据:

The ColumnDataSource was able to isolate the relevant data within a 5,040-by-39 DataFrame without breaking a sweat, saving a few lines of Pandas code in the process.

ColumnDataSource能够在5,040×39的DataFrame隔离相关数据,而不会费力,在此过程中节省了几行Pandas代码。

Looking at the visualization, you can see that the Eastern Conference race was no slouch. After the Celtics roared out of the gate, the Raptors clawed all the way back to overtake their division rival and finish the regular season with five more wins.

通过可视化,您可以看到东部会议竞赛没有懈怠。 凯尔特人大吼一声后,猛龙队一路追回,超越了自己的分区对手,并在常规赛中再赢了五场胜利。

With our two visualizations ready, it’s time to put them together.

准备好我们的两个可视化之后,是时候将它们放在一起了。

Similar to the functionality of Matplotlib’s subplot, Bokeh offers the column, row, and gridplot functions in its bokeh.layouts module. These functions can more generally be classified as layouts.

与Matplotlib subplot的功能相似,Bokeh在其bokeh.layouts模块中提供了columnrowgridplot功能。 这些功能通常可以归类为布局

The usage is very straightforward. If you want to put two visualizations in a vertical configuration, you can do so with the following:

用法非常简单。 如果要垂直放置两个可视化文件,可以使用以下方法:

 # Bokeh library
# Bokeh library
from from bokeh.plotting bokeh.plotting import import figurefigure , , show
show
from from bokeh.io bokeh.io import import output_file
output_file
from from bokeh.layouts bokeh.layouts import import columncolumn# Output to file
# Output to file
output_fileoutput_file (( 'east-west-top-2-standings-race.html''east-west-top-2-standings-race.html' , , titletitle == 'Conference Top 2 Teams Wins Race''Conference Top 2 Teams Wins Race' ))# Plot the two visualizations in a vertical configuration
# Plot the two visualizations in a vertical configuration
showshow (( columncolumn (( west_figwest_fig , , east_figeast_fig ))
))

I’ll save you the two lines of code, but rest assured that swapping column for row in the snippet above will similarly configure the two plots in a horizontal configuration.

我将为您节省两行代码,但是请放心,上面代码段中的columnrow类似地将两个图配置为水平配置。

Note: If you’re trying out the code snippets as you go through the tutorial, I want to take a quick detour to address an error you may see accessing west_fig and east_fig in the following examples. In doing so, you may receive an error like this:

注意:如果您在遍历本教程时正在尝试代码段,那么我想快速绕过一个错误,以解决在以下示例中访问west_figeast_fig的错误。 这样做时,您可能会收到如下错误:

This is one of many errors that are part of Bokeh’s validation module, where w-1004 in particular is warning about the re-use of west_fig and east_fig in a new layout.

这是Bokeh 验证模块中的许多错误之一,其中w-1004特别警告有关在新布局中重新使用west_figeast_fig警告。

To avoid this error as you test the examples, preface the code snippet illustrating each layout with the following:

为了避免在测试示例时出现此错误,请在代码段前添加说明每个布局的代码:

 # Bokeh libraries
# Bokeh libraries
from from bokeh.plotting bokeh.plotting import import figurefigure , , show
show
from from bokeh.models bokeh.models import import ColumnDataSourceColumnDataSource , , CDSViewCDSView , , GroupFilterGroupFilter# Create a ColumnDataSource
# Create a ColumnDataSource
standings_cds standings_cds = = ColumnDataSourceColumnDataSource (( standingsstandings ))# Create the views for each team
# Create the views for each team
celtics_view celtics_view = = CDSViewCDSView (( sourcesource == standings_cdsstandings_cds ,,filtersfilters == [[ GroupFilterGroupFilter (( column_namecolumn_name == 'teamAbbr''teamAbbr' , , groupgroup == 'BOS''BOS' )]))])raptors_view raptors_view = = CDSViewCDSView (( sourcesource == standings_cdsstandings_cds ,,filtersfilters == [[ GroupFilterGroupFilter (( column_namecolumn_name == 'teamAbbr''teamAbbr' , , groupgroup == 'TOR''TOR' )]))])rockets_view rockets_view = = CDSViewCDSView (( sourcesource == standings_cdsstandings_cds ,,filtersfilters == [[ GroupFilterGroupFilter (( column_namecolumn_name == 'teamAbbr''teamAbbr' , , groupgroup == 'HOU''HOU' )])
)])
warriors_view warriors_view = = CDSViewCDSView (( sourcesource == standings_cdsstandings_cds ,,filtersfilters == [[ GroupFilterGroupFilter (( column_namecolumn_name == 'teamAbbr''teamAbbr' , , groupgroup == 'GS''GS' )]))])# Create and configure the figure
# Create and configure the figure
east_fig east_fig = = figurefigure (( x_axis_typex_axis_type == 'datetime''datetime' ,,plot_heightplot_height == 300300 ,,x_axis_labelx_axis_label == 'Date''Date' ,,y_axis_labely_axis_label == 'Wins''Wins' ,,toolbar_locationtoolbar_location == NoneNone ))west_fig west_fig = = figurefigure (( x_axis_typex_axis_type == 'datetime''datetime' ,,plot_heightplot_height == 300300 ,,x_axis_labelx_axis_label == 'Date''Date' ,,y_axis_labely_axis_label == 'Wins''Wins' ,,toolbar_locationtoolbar_location == NoneNone ))# Configure the figures for each conference
# Configure the figures for each conference
east_figeast_fig .. stepstep (( 'stDate''stDate' , , 'gameWon''gameWon' , , colorcolor == '#007A33''#007A33' , , legendlegend == 'Celtics''Celtics' ,,sourcesource == standings_cdsstandings_cds , , viewview == celtics_viewceltics_view )
)
east_figeast_fig .. stepstep (( 'stDate''stDate' , , 'gameWon''gameWon' , , colorcolor == '#CE1141''#CE1141' , , legendlegend == 'Raptors''Raptors' ,,sourcesource == standings_cdsstandings_cds , , viewview == raptors_viewraptors_view ))west_figwest_fig .. stepstep (( 'stDate''stDate' , , 'gameWon''gameWon' , , colorcolor == '#CE1141''#CE1141' , , legendlegend == 'Rockets''Rockets' ,,sourcesource == standings_cdsstandings_cds , , viewview == rockets_viewrockets_view )
)
west_figwest_fig .. stepstep (( 'stDate''stDate' , , 'gameWon''gameWon' , , colorcolor == '#006BB6''#006BB6' , , legendlegend == 'Warriors''Warriors' ,,sourcesource == standings_cdsstandings_cds , , viewview == warriors_viewwarriors_view ))# Move the legend to the upper left corner
# Move the legend to the upper left corner
east_figeast_fig .. legendlegend .. location location = = 'top_left'
'top_left'
west_figwest_fig .. legendlegend .. location location = = 'top_left''top_left'# Layout code snippet goes here!
# Layout code snippet goes here!

Doing so will renew the relevant components to render the visualization, ensuring that no warning is needed.

这样做将更新相关组件以呈现可视化效果,从而确保不需要警告。

Instead of using column or row, you may want to use a gridplot instead.

除了使用columnrow ,您可能还想使用gridplot

One key difference of gridplot is that it will automatically consolidate the toolbar across all of its children figures. The two visualizations above do not have a toolbar, but if they did, then each figure would have its own when using column or row. With that, it also has its own toolbar_location property, seen below set to 'right'.

gridplot一个主要区别是它将自动合并其所有子图中的工具栏。 上面的两个可视化没有工具栏,但是如果有的话,那么当使用columnrow时,每个图形都将具有自己的图形。 这样,它还具有自己的工具toolbar_location属性,下面将其设置为'right'

Syntactically, you’ll also notice below that gridplot differs in that, instead of being passed a tuple as input, it requires a list of lists, where each sub-list represents a row in the grid:

语法上,您还会在下面注意到gridplot不同之处在于,它不需要传递元组作为输入,而是需要一个列表列表,其中每个子列表代表网格中的一行:

Lastly, gridplot allows the passing of None values, which are interpreted as blank subplots. Therefore, if you wanted to leave a placeholder for two additional plots, then you could do something like this:

最后, gridplot允许传递None值,这些值被解释为空白子图。 因此,如果您想为两个额外的图块保留一个占位符,则可以执行以下操作:

 # Bokeh libraries
# Bokeh libraries
from from bokeh.io bokeh.io import import output_file
output_file
from from bokeh.layouts bokeh.layouts import import gridplotgridplot# Output to file
# Output to file
output_fileoutput_file (( 'east-west-top-2-gridplot.html''east-west-top-2-gridplot.html' , , titletitle == 'Conference Top 2 Teams Wins Race''Conference Top 2 Teams Wins Race' ))# Reduce the width of both figures
# Reduce the width of both figures
east_figeast_fig .. plot_width plot_width = = west_figwest_fig .. plot_width plot_width = = 300300# Edit the titles
# Edit the titles
east_figeast_fig .. titletitle .. text text = = 'Eastern Conference'
'Eastern Conference'
west_figwest_fig .. titletitle .. text text = = 'Western Conference''Western Conference'# Plot the two visualizations with placeholders
# Plot the two visualizations with placeholders
east_west_gridplot east_west_gridplot = = gridplotgridplot ([[([[ west_figwest_fig , , NoneNone ], ], [[ NoneNone , , east_figeast_fig ]], ]], toolbar_locationtoolbar_location == 'right''right' ))# Plot the two visualizations in a horizontal configuration
# Plot the two visualizations in a horizontal configuration
showshow (( east_west_gridploteast_west_gridplot )
)

If you’d rather toggle between both visualizations at their full size without having to squash them down to fit next to or on top of each other, a good option is a tabbed layout.

如果您希望在两个可视化文件之间进行全尺寸切换,而不必将它们压缩到彼此相邻或重叠的位置,则选项卡式布局是一个不错的选择。

A tabbed layout consists of two Bokeh widget functions: Tab() and Panel() from the bokeh.models.widgets sub-module. Like using gridplot(), making a tabbed layout is pretty straightforward:

一个选项卡式布局包含两个Bokeh小部件功能: bokeh.models.widgets子模块中的Tab()Panel() 。 就像使用gridplot() ,制作选项卡式布局非常简单:

The first step is to create a Panel() for each tab. That may sound a little confusing, but think of the Tabs() function as the mechanism that organizes the individual tabs created with Panel().

第一步是为每个选项卡创建一个Panel() 。 这听起来可能有些混乱,但是可以将Tabs()函数视为一种组织由Panel()创建的单个选项卡的机制。

Each Panel() takes as input a child, which can either be a single figure() or a layout. (Remember that a layout is a general name for a column, row, or gridplot.) Once your panels are assembled, they can be passed as input to Tabs() in a list.

每个Panel()将一个孩子作为输入,该孩子可以是一个figure()或一个布局。 (请记住,布局是columnrowgridplot的通用名称。)组装面板后,可以将其作为输入传递到列表中的Tabs()

Now that you understand how to access, draw, and organize your data, it’s time to move on to the real magic of Bokeh: interaction! As always, check out Bokeh’s User Guide for more information on layouts.

现在您已经了解了如何访问,绘制和组织数据,现在该继续学习Bokeh的真正魔力:交互! 与往常一样,请查阅《 Bokeh用户指南》以获取有关布局的更多信息。

增加互动 (Adding Interaction)

The feature that sets Bokeh apart is its ability to easily implement interactivity in your visualization. Bokeh even goes as far as describing itself as an interactive visualization library:

使Bokeh与众不同的功能是可以轻松实现可视化交互性的功能。 Bokeh甚至将自己描述为一个交互式可视化库

Bokeh is an interactive visualization library that targets modern web browsers for presentation. (Source)

Bokeh是一个交互式可视化库,面向现代Web浏览器进行演示。 ( 来源 )

In this section, we’ll touch on five ways that you can add interactivity:

在本节中,我们将介绍添加交互性的五种方法:

  • Configuring the toolbar
  • Selecting data points
  • Adding hover actions
  • Linking axes and selections
  • Highlighting data using the legend
  • 配置工具栏
  • 选择数据点
  • 添加悬停动作
  • 链接轴和选择
  • 使用图例突出显示数据

Implementing these interactive elements open up possibilities for exploring your data that static visualizations just can’t do by themselves.

实施这些交互式元素将为探索数据提供了可能性,而静态可视化本身是无法做到的。

配置工具栏 (Configuring the Toolbar)

As you saw all the way back in Generating Your First Figure, the default Bokeh figure() comes with a toolbar right out of the box. The default toolbar comes with the following tools (from left to right):

正如您在“ 生成第一个图形”中所看到的一样,默认的Bokeh figure()带有一个现成的工具栏。 默认工具栏带有以下工具(从左到右):

  • Pan
  • Box Zoom
  • Wheel Zoom
  • Save
  • Reset
  • A link to Bokeh’s user guide for Configuring Plot Tools
  • A link to the Bokeh homepage
  • 框缩放
  • 车轮变焦
  • 保存
  • 重启
  • Bokeh的用户指南的链接, 用于配置绘图工具
  • 散景首页的链接

The toolbar can be removed by passing toolbar_location=None when instantiating a figure() object, or relocated by passing any of 'above', 'below', 'left', or 'right'.

可以在实例化figure()对象时通过传递toolbar_location=None来删除工具栏,或者通过传递'above''below''left''right'任何一个来重新定位工具栏。

Additionally, the toolbar can be configured to include any combination of tools you desire. Bokeh offers 18 specific tools across five categories:

此外,工具栏可以配置为包括所需工具的任何组合。 散景提供五个类别的18种特定工具:

  • Pan/Drag: box_select, box_zoom, lasso_select, pan, xpan, ypan, resize_select
  • Click/Tap: poly_select, tap
  • Scroll/Pinch: wheel_zoom, xwheel_zoom, ywheel_zoom
  • Actions: undo, redo, reset, save
  • Inspectors: crosshair, hover
  • 平移/拖动box_selectbox_zoomlasso_selectpanxpanypanresize_select
  • 点击/点击poly_selecttap
  • 滚动/ wheel_zoomwheel_zoomxwheel_zoomywheel_zoom
  • 操作undoredoresetsave
  • 检查员crosshairhover

To geek out on tools , make sure to visit Specifying Tools. Otherwise, they’ll be illustrated in covering the various interactions covered herein.

要了解各种工具,请确保访问“ 指定工具” 。 否则,将在涵盖本文涵盖的各种交互中进行说明。

选择数据点 (Selecting Data Points)

Implementing selection behavior is as easy as adding a few specific keywords when declaring your glyphs.

声明字形时,实现选择行为就像添加几个特定的​​关键字一样容易。

The next example will create a scatter plot that relates a player’s total number of three-point shot attempts to the percentage made (for players with at least 100 three-point shot attempts).

下一个示例将创建一个散点图,该散点图将玩家的三分球尝试总数与所做出的百分比相关联(对于至少进行100次三分球尝试的玩家)。

The data can be aggregated from the player_stats DataFrame:

数据可以从player_stats DataFrame中汇总:

 # Find players who took at least 1 three-point shot during the season
# Find players who took at least 1 three-point shot during the season
three_takers three_takers = = player_statsplayer_stats [[ player_statsplayer_stats [[ 'play3PA''play3PA' ] ] > > 00 ]]# Clean up the player names, placing them in a single column
# Clean up the player names, placing them in a single column
three_takersthree_takers [[ 'name''name' ] ] = = [[ ff '' {p["playFNm"]}{p["playFNm"]}    {p["playLNm"]}{p["playLNm"]} ' ' for for __ , , p p in in three_takersthree_takers .. iterrowsiterrows ()]()]# Aggregate the total three-point attempts and makes for each player
# Aggregate the total three-point attempts and makes for each player
three_takers three_takers = = (( three_takersthree_takers .. groupbygroupby (( 'name''name' )).. sumsum ()().. locloc [:,[[:,[ 'play3PA''play3PA' , , 'play3PM''play3PM' ]]]].. sort_valuessort_values (( 'play3PA''play3PA' , , ascendingascending == FalseFalse ))))# Filter out anyone who didn't take at least 100 three-point shots
# Filter out anyone who didn't take at least 100 three-point shots
three_takers three_takers = = three_takersthree_takers [[ three_takersthree_takers [[ 'play3PA''play3PA' ] ] >= >= 100100 ]] .. reset_indexreset_index ()()# Add a column with a calculated three-point percentage (made/attempted)
# Add a column with a calculated three-point percentage (made/attempted)
three_takersthree_takers [[ 'pct3PM''pct3PM' ] ] = = three_takersthree_takers [[ 'play3PM''play3PM' ] ] / / three_takersthree_takers [[ 'play3PA''play3PA' ]
]

Here’s a sample of the resulting DataFrame:

这是生成的DataFrame的示例:

>>>
>>>

 >>>  three_takers . sample ( 5 )name  play3PA  play3PM    pct3PM
229        Corey Brewer      110       31  0.281818
78           Marc Gasol      320      109  0.340625
126      Raymond Felton      230       81  0.352174
127  Kristaps Porziņģis      229       90  0.393013
66      Josh Richardson      336      127  0.377976

Let’s say you want to select a groups of players in the distribution, and in doing so mute the color of the glyphs representing the non-selected players:

假设您要选择分布中的一组玩家,并以此静音代表未选中玩家的字形的颜色:

First, specify the selection tools you want to make available. In the example above, 'box_select', 'lasso_select', 'poly_select', and 'tap' (plus a reset button) were specified in a list called select_tools. When the figure is instantiated, the toolbar is positioned 'below' the plot, and the list is passed to tools to make the tools selected above available.

首先,指定要使用的选择工具。 在上面的示例中,在名为select_tools的列表中指定了'box_select''lasso_select''poly_select''tap' (加上复位按钮)。 实例化图形后,工具栏将位于图形的'below' ,并且列表将传递给tools以使上面选择的工具可用。

Each player is initially represented by a royal blue square glyph, but the following configurations are set for when a player or group of players is selected:

每个玩家最初都由宝蓝色方块字形表示,但是在选择一个或多个玩家组时会设置以下配置:

  • Turn the selected player(s) to deepskyblue
  • Change all non-selected players’ glyphs to a lightgray color with 0.3 opacity
  • 将选定的播放器变成deepskyblue
  • 将所有未选择的玩家的图示符号更改0.3不透明0.3lightgray灰色

That’s it! With just a few quick additions, the visualization now looks like this:

而已! 只需快速添加几下,可视化现在看起来像这样:

For even more information about what you can do upon selection, check out Selected and Unselected Glyphs.

有关选择时可以执行的操作的更多信息,请查看选定和未选定字形 。

添加悬停动作 (Adding Hover Actions)

So the ability to select specific player data points that seem of interest in my scatter plot is implemented, but what if you want to quickly see what individual players a glyph represents? One option is to use Bokeh’s HoverTool() to show a tooltip when the cursor crosses paths with a glyph. All you need to do is append the following to the code snippet above:

因此,实现了选择散点图中似乎感兴趣的特定玩家数据点的功能,但是如果您想快速查看一个字形代表的是哪个玩家,该怎么办? 一种选择是使用Bokeh的HoverTool()在光标带有字形的路径上显示工具提示。 您需要做的就是将以下内容添加到上面的代码片段中:

 # Bokeh Library
# Bokeh Library
from from bokeh.models bokeh.models import import HoverToolHoverTool# Format the tooltip
# Format the tooltip
tooltips tooltips = = [[(( 'Player''Player' ,, '@name''@name' ),),(( 'Three-Pointers Made''Three-Pointers Made' , , '@play3PM''@play3PM' ),),(( 'Three-Pointers Attempted''Three-Pointers Attempted' , , '@play3PA''@play3PA' ),),(( 'Three-Point Percentage''Three-Point Percentage' ,, '@pct3PM{00.0%}''@pct3PM{00.0%}' ),),]]# Add the HoverTool to the figure
# Add the HoverTool to the figure
figfig .. add_toolsadd_tools (( HoverToolHoverTool (( tooltipstooltips == tooltipstooltips ))))# Visualize
# Visualize
showshow (( figfig )
)

The HoverTool() is slightly different than the selection tools you saw above in that it has properties, specifically tooltips.

HoverTool()与上面的选择工具略有不同,因为它具有属性,特别是tooltips

First, you can configure a formatted tooltip by creating a list of tuples containing a description and reference to the ColumnDataSource. This list was passed as input to the HoverTool() and then simply added to the figure using add_tools(). Here’s what happened:

首先,您可以通过创建包含描述和对ColumnDataSource引用的元组列表来配置格式化的工具提示。 该列表作为输入传递到HoverTool() ,然后使用add_tools()简单地添加到图中。 这是发生了什么:

Notice the addition of the Hover button to the toolbar, which can be toggled on and off.

请注意,在工具栏上添加了“悬停”按钮,可以将其打开和关闭。

If you want to even further emphasize the players on hover, Bokeh makes that possible with hover inspections. Here is a slightly modified version of the code snippet that added the tooltip:

如果您想在悬停上进一步强调玩家,Bokeh可以通过悬停检查来实现这一点。 这是添加了工具提示的代码片段的稍作修改的版本:

This is done by creating a completely new glyph, in this case circles instead of squares, and assigning it to hover_glyph. Note that the initial opacity is set to zero so that it is invisible until the cursor is touching it. The properties that appear upon hover are captured by setting hover_alpha to 0.5 along with the hover_fill_color.

这是通过创建一个全新的字形(在这种情况下为圆形而不是正方形)并将其分配给hover_glyphhover_glyph 。 请注意,初始不透明度设置为零,以便直到光标触摸它时才可见。 出现在悬停的属性由设置捕获hover_alpha0.5与沿hover_fill_color

Now you will see a small black circle appear over the original square when hovering over the various markers:

现在,将鼠标悬停在各种标记上时,您会看到一个小的黑色圆圈出现在原始正方形上:

To further explore the capabilities of the HoverTool(), see the HoverTool and Hover Inspections guides.

要进一步探索HoverTool() ,请参阅HoverTool和Hover检查指南。

链接轴和选择 (Linking Axes and Selections)

Linking is the process of syncing elements of different visualizations within a layout. For instance, maybe you want to link the axes of multiple plots to ensure that if you zoom in on one it is reflected on another. Let’s see how it is done.

链接是同步布局中不同可视化元素的过程。 例如,也许您想链接多个图的轴,以确保如果放大一个图,它会反映在另一个图上。 让我们看看它是如何完成的。

For this example, the visualization will be able to pan to different segments of a team’s schedule and examine various game stats. Each stat will be represented by its own plot in a two-by-two gridplot() .

对于此示例,可视化将能够平移团队进度表的不同部分并检查各种游戏统计信息。 每个stat将由其自己的图以2 x 2 gridplot()

The data can be collected from the team_stats DataFrame, selecting the Philadelphia 76ers as the team of interest:

可以从team_stats DataFrame收集数据,选择费城76人队作为关注的球队:

 # Isolate relevant data
# Isolate relevant data
phi_gm_stats phi_gm_stats = = (( team_statsteam_stats [([( team_statsteam_stats [[ 'teamAbbr''teamAbbr' ] ] == == 'PHI''PHI' ) ) & & (( team_statsteam_stats [[ 'seasTyp''seasTyp' ] ] == == 'Regular''Regular' )])].. locloc [:, [:, [[ 'gmDate''gmDate' , , 'teamPTS''teamPTS' , , 'teamTRB''teamTRB' , , 'teamAST''teamAST' , , 'teamTO''teamTO' , , 'opptPTS''opptPTS' ,]],]].. sort_valuessort_values (( 'gmDate''gmDate' ))))# Add game number
# Add game number
phi_gm_statsphi_gm_stats [[ 'game_num''game_num' ] ] = = rangerange (( 11 , , lenlen (( phi_gm_statsphi_gm_stats )) ++ 11 ))# Derive a win_loss column
# Derive a win_loss column
win_loss win_loss = = []
[]
for for __ , , row row in in phi_gm_statsphi_gm_stats .. iterrowsiterrows ():():# If the 76ers score more points, it's a win# If the 76ers score more points, it's a winif if rowrow [[ 'teamPTS''teamPTS' ] ] > > rowrow [[ 'opptPTS''opptPTS' ]:]:win_losswin_loss .. appendappend (( 'W''W' ))elseelse ::win_losswin_loss .. appendappend (( 'L''L' ))# Add the win_loss data to the DataFrame
# Add the win_loss data to the DataFrame
phi_gm_statsphi_gm_stats [[ 'winLoss''winLoss' ] ] = = win_loss
win_loss

Here are the results of the 76ers’ first 5 games:

以下是76人队前5场比赛的结果:

>>>
>>>

 >>>  phi_gm_stats . head ()gmDate  teamPTS  teamTRB  teamAST  teamTO  opptPTS  game_num winLoss
10  2017-10-18      115       48       25      17      120         1       L
39  2017-10-20       92       47       20      17      102         2       L
52  2017-10-21       94       41       18      20      128         3       L
80  2017-10-23       97       49       25      21       86         4       W
113 2017-10-25      104       43       29      16      105         5       L

Start by importing the necessary Bokeh libraries, specifying the output parameters, and reading the data into a ColumnDataSource:

首先导入必要的Bokeh库,指定输出参数,然后将数据读取到ColumnDataSource

Each game is represented by a column, and will be colored green if the result was a win and red for a loss. To accomplish this, Bokeh’s CategoricalColorMapper can be used to map the data values to specified colors:

每个游戏都由一列表示,如果结果是获胜,则将颜色涂成绿色,而将失败的颜色涂成红色。 为此,可以使用Bokeh的CategoricalColorMapper将数据值映射到指定的颜色:

 # Create a CategoricalColorMapper that assigns a color to wins and losses
# Create a CategoricalColorMapper that assigns a color to wins and losses
win_loss_mapper win_loss_mapper = = CategoricalColorMapperCategoricalColorMapper (( factors factors = = [[ 'W''W' , , 'L''L' ], ], palettepalette == [[ 'green''green' , , 'red''red' ])
])

For this use case, a list specifying the categorical data values to be mapped is passed to factors and a list with the intended colors to palette. For more on the CategoricalColorMapper, see the Colors section of Handling Categorical Data on Bokeh’s User Guide.

对于此用例,将指定要映射的分类数据值的列表传递给factors ,将具有预期颜色的列表传递给palette 。 有关CategoricalColorMapper更多信息,请参阅《 Bokeh用户指南》中的“ 处理分类数据”的“ 颜色”部分。

There are four stats to visualize in the two-by-two gridplot: points, assists, rebounds, and turnovers. In creating the four figures and configuring their respective charts, there is a lot of redundancy in the properties. So to streamline the code a for loop can be used:

在2 x 2的gridplot可以看到四个统计数据:得分,助攻,篮板和失误。 在创建四个图形并配置它们各自的图表时,属性中存在很多冗余。 因此,为了简化代码for可以使用for循环:

As you can see, the only parameters that needed to be adjusted were the y-axis-label of the figure and the data that will dictate top in the vbar. These values were easily stored in a dict that was iterated through to create the figures for each stat.

如您所见,唯一需要调整的参数是图形的y-axis-label和指示vbar topvbar 。 这些值可以轻松地存储在dict ,并对其进行迭代以创建每个统计数据。

You can also see the implementation of the CategoricalColorMapper in the configuration of the vbar glyph. The color property is passed a dict with the field in the ColumnDataSource to be mapped and the name of the CategoricalColorMapper created above.

您还可以在vbar字形的配置中看到CategoricalColorMapper的实现。 的color属性被传递一个dict与在该领域ColumnDataSource映射和名称CategoricalColorMapper上面创建。

The initial view will only show the first 10 games of the 76ers’ season, so there needs to be a way to pan horizontally to navigate through the rest of the games in the season. Thus configuring the toolbar to have an xpan tool allows panning throughout the plot without having to worry about accidentally skewing the view along the vertical axis.

初始视图仅显示76ers赛季的前10场比赛,因此需要有一种水平移动以浏览本赛季其余比赛的方法。 因此,将工具栏配置为具有xpan工具可以平移整个图,而不必担心会意外地沿垂直轴倾斜视图。

Now that the figures are created, gridplot can be setup by referencing the figures from the dict created above:

现在已经创建了图,可以通过参考上面创建的dict的图来设置gridplot

 # Create layout
# Create layout
grid grid = = gridplotgridplot ([[([[ stat_figsstat_figs [[ 'Points''Points' ], ], stat_figsstat_figs [[ 'Assists''Assists' ]], ]], [[ stat_figsstat_figs [[ 'Rebounds''Rebounds' ], ], stat_figsstat_figs [[ 'Turnovers''Turnovers' ]]])
]]])

Linking the axes of the four plots is as simple as setting the x_range of each figure equal to one another:

链接四个图的轴非常简单, x_range将每个图形的x_range设置为彼此相等即可:

To add a title bar to the visualization, you could have tried to do this on the points figure, but it would have been limited to the space of that figure. Therefore, a nice trick is to use Bokeh’s ability to interpret HTML to insert a Div element that contains the title information. Once that is created, simply combine that with the gridplot() in a column layout:

要将标题栏添加到可视化中,您可以尝试在点图上执行此操作,但仅限于该图的空间。 因此,一个不错的技巧是使用Bokeh的解释HTML的功能来插入包含标题信息的Div元素。 创建后,只需将其与gridplot()column布局即可:

 # Add a title for the entire visualization using Div
# Add a title for the entire visualization using Div
html html = = """<h3>Philadelphia 76ers Game Log</h3>
"""<h3>Philadelphia 76ers Game Log</h3>
<b><i>2017-18 Regular Season</i>
<b><i>2017-18 Regular Season</i>
<br>
<br>
</b><i>Wins in green, losses in red</i>
</b><i>Wins in green, losses in red</i>
"""
"""
sup_title sup_title = = DivDiv (( texttext == htmlhtml ))# Visualize
# Visualize
showshow (( columncolumn (( sup_titlesup_title , , gridgrid ))
))

Putting all the pieces together results in the following:

将所有部分放在一起将得到以下结果:

Similarly you can easily implement linked selections, where a selection on one plot will be reflected on others.

同样,您可以轻松实现链接的选择,其中一个图上的选择将反映在其他图上。

To see how this works, the next visualization will contain two scatter plots: one that shows the 76ers’ two-point versus three-point field goal percentage and the other showing the 76ers’ team points versus opponent points on a game-by-game basis.

若要查看其工作原理,下一个可视化将包含两个散点图:一个显示76ers的两分球命中率与三分球的投篮命中率百分比,另一个显示每个游戏中76ers的队得分与对手分的比率基础。

The goal is to be able to select data points on the left-side scatter plot and quickly be able to recognize if the corresponding datapoint on the right scatter plot is a win or loss.

目的是能够在左侧散点图上选择数据点,并能够快速识别右侧散点图上的相应数据点是赢还是输。

The DataFrame for this visualization is very similar to that from the first example:

此可视化的DataFrame与第一个示例非常相似:

Here’s what the data looks like:

数据如下所示:

>>>

>>> phi_gm_stats_2.head()
        gmDate  team2P%  team3P%  teamPTS  opptPTS  game_num winLoss
10  2017-10-18   0.4746   0.4286      115      120         1       L
39  2017-10-20   0.4167   0.3125       92      102         2       L
52  2017-10-21   0.4138   0.3333       94      128         3       L
80  2017-10-23   0.5098   0.3750       97       86         4       W
113 2017-10-25   0.5082   0.3333      104      105         5       L

>>>

The code to create the visualization is as follows:

创建可视化的代码如下:

 # Bokeh Libraries
# Bokeh Libraries
from from bokeh.plotting bokeh.plotting import import figurefigure , , show
show
from from bokeh.io bokeh.io import import output_file
output_file
from from bokeh.models bokeh.models import import ColumnDataSourceColumnDataSource , , CategoricalColorMapperCategoricalColorMapper , , NumeralTickFormatter
NumeralTickFormatter
from from bokeh.layouts bokeh.layouts import import gridplotgridplot# Output inline in the notebook
# Output inline in the notebook
output_fileoutput_file (( 'phi-gm-linked-selections.html''phi-gm-linked-selections.html' ,,titletitle == '76ers Percentages vs. Win-Loss''76ers Percentages vs. Win-Loss' ))# Store the data in a ColumnDataSource
# Store the data in a ColumnDataSource
gm_stats_cds gm_stats_cds = = ColumnDataSourceColumnDataSource (( phi_gm_stats_2phi_gm_stats_2 ))# Create a CategoricalColorMapper that assigns specific colors to wins and losses
# Create a CategoricalColorMapper that assigns specific colors to wins and losses
win_loss_mapper win_loss_mapper = = CategoricalColorMapperCategoricalColorMapper (( factors factors = = [[ 'W''W' , , 'L''L' ], ], palettepalette == [[ 'Green''Green' , , 'Red''Red' ])])# Specify the tools
# Specify the tools
toolList toolList = = [[ 'lasso_select''lasso_select' , , 'tap''tap' , , 'reset''reset' , , 'save''save' ]]# Create a figure relating the percentages
# Create a figure relating the percentages
pctFig pctFig = = figurefigure (( titletitle == '2PT FG % vs 3PT FG %, 2017-18 Regular Season''2PT FG % vs 3PT FG %, 2017-18 Regular Season' ,,plot_heightplot_height == 400400 , , plot_widthplot_width == 400400 , , toolstools == toolListtoolList ,,x_axis_labelx_axis_label == '2PT FG%''2PT FG%' , , y_axis_labely_axis_label == '3PT FG%''3PT FG%' ))# Draw with circle markers
# Draw with circle markers
pctFigpctFig .. circlecircle (( xx == 'team2P%''team2P%' , , yy == 'team3P%''team3P%' , , sourcesource == gm_stats_cdsgm_stats_cds , , sizesize == 1212 , , colorcolor == 'black''black' ))# Format the y-axis tick labels as percenages
# Format the y-axis tick labels as percenages
pctFigpctFig .. xaxisxaxis [[ 00 ]] .. formatter formatter = = NumeralTickFormatterNumeralTickFormatter (( formatformat == '00.0%''00.0%' )
)
pctFigpctFig .. yaxisyaxis [[ 00 ]] .. formatter formatter = = NumeralTickFormatterNumeralTickFormatter (( formatformat == '00.0%''00.0%' ))# Create a figure relating the totals
# Create a figure relating the totals
totFig totFig = = figurefigure (( titletitle == 'Team Points vs Opponent Points, 2017-18 Regular Season''Team Points vs Opponent Points, 2017-18 Regular Season' ,,plot_heightplot_height == 400400 , , plot_widthplot_width == 400400 , , toolstools == toolListtoolList ,,x_axis_labelx_axis_label == 'Team Points''Team Points' , , y_axis_labely_axis_label == 'Opponent Points''Opponent Points' ))# Draw with square markers
# Draw with square markers
totFigtotFig .. squaresquare (( xx == 'teamPTS''teamPTS' , , yy == 'opptPTS''opptPTS' , , sourcesource == gm_stats_cdsgm_stats_cds , , sizesize == 1010 ,,colorcolor == dictdict (( fieldfield == 'winLoss''winLoss' , , transformtransform == win_loss_mapperwin_loss_mapper ))))# Create layout
# Create layout
grid grid = = gridplotgridplot ([[([[ pctFigpctFig , , totFigtotFig ]])]])# Visualize
# Visualize
showshow (( gridgrid )
)

This is a great illustration of the power in using a ColumnDataSource. As long as the glyph renderers (in this case, the circle glyphs for the percentages, and square glyphs for the wins and losses) share the same ColumnDataSource, then the selections will be linked by default.

这很好地说明了使用ColumnDataSource的强大功能。 只要字形渲染器(在这种情况下,百分比的circle字形和获胜和损失的square字形)共享相同的ColumnDataSource ,则默认情况下将链接选择。

Here’s how it looks in action, where you can see selections made on either figure will be reflected on the other:

这是实际的外观,您可以看到在任一图上所做的选择都会反映在另一图上:

By selecting a random sample of data points in the upper right quadrant of the left scatter plot, those corresponding to both high two-point and three-point field goal percentage, the data points on the right scatter plot are highlighted.

通过在左散点图的右上象限中选择数据点的随机样本(对应于较高的两点和三点射门得分百分比),将突出显示右散点图上的数据点。

Similarly, selecting data points on the right scatter plot that correspond to losses tend to be further to the lower left, lower shooting percentages, on the left scatter plot.

同样,在右侧散点图上选择与损失相对应的数据点往往会更靠近左侧散点图上的左下,较低的射击百分比。

All the details on linking plots can be found at Linking Plots in the Bokeh User Guide.

有关链接图的所有详细信息,请参见《 Bokeh用户指南》中的“ 链接图 ”。

使用图例突出显示数据 (Highlighting Data Using the Legend)

That brings us to the final interactivity example in this tutorial: interactive legends.

这使我们进入了本教程中的最终交互性示例:交互式图例。

In the Drawing Data With Glyphs section, you saw how easy it is to implement a legend when creating your plot. With the legend in place, adding interactivity is merely a matter of assigning a click_policy. Using a single line of code, you can quickly add the ability to either hide or mute data using the legend.

在使用字形绘制数据部分中,您看到了在创建图形时实现图例很容易。 有了图例,添加交互性仅是分配click_policy 。 使用单行代码,您可以快速添加使用图例hidemute数据的功能。

In this example, you’ll see two identical scatter plots comparing the game-by-game points and rebounds of LeBron James and Kevin Durant. The only difference will be that one will use a hide as its click_policy, while the other uses mute.

在此示例中,您将看到两个相同的散点图,用于比较勒布朗·詹姆斯和凯文·杜randint的逐场得分和篮板。 唯一的区别将是一个会用一个hideclick_policy ,而其他用途mute

The first step is to configure the output and set up the data, creating a view for each player from the player_stats DataFrame:

第一步是配置输出并设置数据,从player_stats DataFrame为每个玩家创建一个视图:

Before creating the figures, the common parameters across the figure, markers, and data can be consolidated into dictionaries and reused. Not only does this save redundancy in the next step, but it provides an easy way to tweak these parameters later if need be:

在创建图形之前,可以将图形,标记和数据上的通用参数合并为字典并重新使用。 这不仅可以节省下一步的冗余,而且还提供了一种简便的方法,可以在以后需要时调整这些参数:

 # Consolidate the common keyword arguments in dicts
# Consolidate the common keyword arguments in dicts
common_figure_kwargs common_figure_kwargs = = {{'plot_width''plot_width' : : 400400 ,,'x_axis_label''x_axis_label' : : 'Points''Points' ,,'toolbar_location''toolbar_location' : : NoneNone ,
,
}
}
common_circle_kwargs common_circle_kwargs = = {{'x''x' : : 'playPTS''playPTS' ,,'y''y' : : 'playTRB''playTRB' ,,'source''source' : : player_gm_statsplayer_gm_stats ,,'size''size' : : 1212 ,,'alpha''alpha' : : 0.70.7 ,
,
}
}
common_lebron_kwargs common_lebron_kwargs = = {{'view''view' : : lebron_viewlebron_view ,,'color''color' : : '#002859''#002859' ,,'legend''legend' : : 'LeBron James'
'LeBron James'
}
}
common_durant_kwargs common_durant_kwargs = = {{'view''view' : : durant_viewdurant_view ,,'color''color' : : '#FFC324''#FFC324' ,,'legend''legend' : : 'Kevin Durant'
'Kevin Durant'
}
}

Now that the various properties are set, the two scatter plots can be built in a much more concise fashion:

现在已经设置了各种属性,可以以更加简洁的方式构建两个散点图:

Note that mute_fig has an extra parameter called muted_alpha. This parameter controls the opacity of the markers when mute is used as the click_policy.

请注意, mute_fig还有一个额外的参数,称为muted_alpha 。 该参数控制标记的不透明度时mute用作click_policy

Finally, the click_policy for each figure is set, and they are shown in a horizontal configuration:

最后,为每个图形设置click_policy ,它们以水平配置显示:

 # Add interactivity to the legend
# Add interactivity to the legend
hide_fighide_fig .. legendlegend .. click_policy click_policy = = 'hide'
'hide'
mute_figmute_fig .. legendlegend .. click_policy click_policy = = 'mute''mute'# Visualize
# Visualize
showshow (( rowrow (( hide_fighide_fig , , mute_figmute_fig ))
))

Once the legend is in place, all you have to do is assign either hide or mute to the figure’s click_policy property. This will automatically turn your basic legend into an interactive legend.

图例到位后,您所要做的就是为图形的click_policy属性分配hidemute 。 这将自动将您的基本图例变成交互式图例。

Also note that, specifically for mute, the additional property of muted_alpha was set in the respective circle glyphs for LeBron James and Kevin Durant. This dictates the visual effect driven by the legend interaction.

还要注意的是,专为mute ,附加属性muted_alpha在各自的设置circle字形的勒布朗-詹姆斯和凯文-杜randint。 这决定了图例交互驱动的视觉效果。

For more on all things interaction in Bokeh, Adding Interactions in the Bokeh User Guide is a great place to start.

有关Bokeh中所有交互的更多信息,《 Bokeh用户指南》中的“ 添加交互 ”是一个不错的起点。

摘要和后续步骤 (Summary and Next Steps)

Congratulations! You’ve made it to the end of this tutorial.

恭喜你! 您已经完成了本教程的结尾。

You should now have a great set of tools to start turning your data into beautiful interactive visualizations using Bokeh.

现在,您应该拥有大量的工具,可以开始使用Bokeh将数据转换为漂亮的交互式可视化图像。

You learned how to:

您学习了如何:

  • Configure your script to render to either a static HTML file or Jupyter Notebook
  • Instantiate and customize the figure() object
  • Build your visualization using glyphs
  • Access and filter your data with the ColumnDataSource
  • Organize multiple plots in grid and tabbed layouts
  • Add different forms of interaction, including selections, hover actions, linking, and interactive legends
  • 配置脚本以呈现为静态HTML文件或Jupyter Notebook
  • 实例化和自定义figure()对象
  • 使用字形构建可视化
  • 使用ColumnDataSource访问和过滤数据
  • 在网格和选项卡式布局中组织多个图
  • 添加不同形式的交互,包括选择,悬停动作,链接和交互图例

To explore even more of what Bokeh is capable of, the official Bokeh User Guide is an excellent place to dig into some more advanced topics. I’d also recommend checking out Bokeh’s Gallery for tons of examples and inspiration.

要进一步探究Bokeh的功能,官方的《 Bokeh用户指南》是探讨一些更高级主题的好地方。 我还建议您查看Bokeh的Gallery,以获取大量示例和灵感。

翻译自: https://www.pybloggers.com/2018/11/interactive-data-visualization-in-python-with-bokeh/

python bokeh

python bokeh_使用Bokeh在Python中进行交互式数据可视化相关推荐

  1. python动态交互图表_Python 调用 matplotlib 实现交互式数据可视化图表案例

    交互式的数据可视化图表是 New IT 新技术的一个应用方向,在过去,用户要在网页上查看数据,基本的实现方式就是在页面上显示一个表格出来,的而且确,用表格的方式来展示数据,显示的数据量会比较大,但是, ...

  2. python交互式和文件式区别_Python中的交互式数据可视化与Bokeh(系列五)

    使用图例突出显示数据 这将我们带到本教程中的最终交互性示例:交互式图例. 在" 使用字形绘制数据"部分中,您了解了在创建绘图时实现图例是多么容易.有了这个传奇,增加交互性只是分配一 ...

  3. 在R、Python和Julia中常用的数据可视化技术

    俗话说"一图胜千言".通过各种图片和图形化展示,我们可以更清晰地表达很多抽象概念.理论.数据模式或某些想法.在本章中,我们首先解释为什么应该关心数据可视化.然后,我们将讨论几种在R ...

  4. python筛选excel某一列中相同的数据

    求赞----求关注 python筛选excel某一列中相同的数据 1.需要cmd下载 pip install pandas  的模板 2.注意文件的路径问题不要出错 3.还有文件的编码格式 ----- ...

  5. python交互式数据可视化_python数据可视化工具

    熟知python的人都知道,python上常用的一款数据可视化工具是Matplotlib,但是Matplotlib是静态的.那么,Python中除了matplotlib外,还有哪些数据可视化工具呢?其 ...

  6. python基于web可视化_独家 | 基于Python实现交互式数据可视化的工具(用于Web)

    转自:数据派ID:datapi 作者:Alark Joshi 翻译:陈雨琳 校对:吴金笛 本文2200字,建议阅读8分钟. 本文将介绍实现数据可视化的软件包. 这学期(2018学年春季学期)我教授了一 ...

  7. python交互式数据可视化_基于Python实现交互式数据可视化的工具,你用过几种?...

    作者:Alark Joshi 翻译:陈雨琳 来源:数据派THU(ID:DatapiTHU) 我教授了一门关于数据可视化的数据科学硕士课程.我们的数据科学硕士项目是一个为期15个月的强化项目,这个项目已 ...

  8. python实现数据可视化软件_基于Python实现交互式数据可视化的工具

    作者:Alark Joshi 翻译:陈雨琳 校对:吴金笛 本文2200字,建议阅读8分钟. 本文将介绍实现数据可视化的软件包. 这学期(2018学年春季学期)我教授了一门关于数据可视化的数据科学硕士课 ...

  9. pythonweb数据可视化_独家 | 基于Python实现交互式数据可视化的工具(用于Web)

    翻译:陈雨琳 校对:吴金笛 本文2200字,建议阅读8分钟. 本文将介绍实现数据可视化的软件包. 这学期(2018学年春季学期)我教授了一门关于数据可视化的数据科学硕士课程.我们的数据科学硕士项目是一 ...

最新文章

  1. Oracle日常巡检
  2. python一年365天、初始水平值_2020年11月7日,20201107
  3. @EnableAutoConfiguration注解的实现原理
  4. 修复病毒破坏的文件关联并恢复程序图标
  5. 服务器win7internet协议议,主编细说win7系统internet协议在哪、添加TCPIP协议的操作方法...
  6. JAVA中向量类Vector
  7. 们--加强菲波那切数列
  8. linux中逻辑块大小为,Linux 文件系统相关的基本概念
  9. 2022上半年软件设计师历年真题
  10. HTML,CSS,font-family:中文字体的英文名称 (宋体 微软雅黑)
  11. 基于深度卷积神经网络的图像去噪方法
  12. Android 静默安装
  13. win10系统怎么查看密钥?
  14. 下载文件时报错:无法复制文件,无法读源文件或磁的解决方法
  15. Java实现 简体中文 与 阿拉伯数字 互转
  16. excel文件下载下来损坏 js_java – React excel文件下载损坏
  17. ios使用友盟分享到QQ/微信时时如何判断手机上是否安装了QQ以及微信的客户端
  18. oracle 字段别名
  19. 模式识别八--三层BP神经网络的设计与实现
  20. hellojs使用 推特登录/api nuxt vue

热门文章

  1. 安卓开发(6)-添加向上导航功能(顶部返回箭头)
  2. Object 和 object 的区别是什么?
  3. 东北大学计算机科学与工程学院张喆,毕远国 - 东北大学 - 计算机科学与工程学院...
  4. android双网卡,指定发包网卡。
  5. RK35XX系列(RK3568)移植 AP62XX (ap6256)wifi 蓝牙模块
  6. MAC安装向日葵软件后远程协助设置
  7. 黑马程序员C++笔记--第三阶段核心:【类和对象】
  8. 机器人--避障技术盘点
  9. 私域流量运营服务平台
  10. 创业兵法——网络营销让你的产品家喻户晓