7.3 交互式图形 (与Bokeh, Plotly等库结合)


文档摘要

7.3 交互式图形 (与Bokeh, Plotly等库结合) 第七章:Seaborn高级应用领域 - 7.3 交互式图形 (与Bokeh, Plotly等库结合) 详解 Seaborn 作为 Python 中强大的数据可视化库,以其简洁的语法和美观的默认样式深受数据科学家和分析师的喜爱。然而,Seaborn 本身主要生成静态图形,在面对需要深入探索数据、动态展示结果或与用户进行交互式沟通的场景时,其能力略显不足。 为了弥补这一缺憾,我们可以将 Seaborn 与其他专注于交互式图形的库,如 Bokeh 和 Plotly 结合使用。这些库能够赋予 Seaborn 图形动态性,例如缩放、平移、悬停提示、数据选择等功能,极大地提升了数据探索和展示的效率和深度。 7.3.

7.3 交互式图形 (与Bokeh, Plotly等库结合)

第七章:Seaborn高级应用领域 - 7.3 交互式图形 (与Bokeh, Plotly等库结合) 详解

Seaborn 作为 Python 中强大的数据可视化库,以其简洁的语法和美观的默认样式深受数据科学家和分析师的喜爱。然而,Seaborn 本身主要生成静态图形,在面对需要深入探索数据、动态展示结果或与用户进行交互式沟通的场景时,其能力略显不足。

为了弥补这一缺憾,我们可以将 Seaborn 与其他专注于交互式图形的库,如 Bokeh 和 Plotly 结合使用。这些库能够赋予 Seaborn 图形动态性,例如缩放、平移、悬停提示、数据选择等功能,极大地提升了数据探索和展示的效率和深度。

7.3.1 交互式图形的价值与应用场景

在深入代码实践之前,我们首先需要理解交互式图形的价值以及其适用的场景。

交互式图形的价值:

  • 更深入的数据探索: 交互功能允许用户自由地缩放、平移、旋转图形,并查看特定数据点的详细信息。这使得用户能够从不同角度审视数据,发现隐藏的模式和异常值。

  • 更强大的数据洞察力: 通过交互操作,用户可以动态地过滤数据、调整参数,并即时观察结果的变化。这种即时反馈机制有助于用户更快地理解数据背后的含义,并产生更深刻的洞察。

  • 更有效的沟通与展示: 交互式图形能够更生动、更引人入胜地展示数据故事。用户可以通过自身的操作参与到数据探索过程中,从而更好地理解和记住数据信息。

  • 定制化的用户体验: 交互式图形可以根据用户的需求进行定制,例如添加特定的交互工具、调整图形布局等,提供更个性化的数据分析体验。

交互式图形的应用场景:

  • 数据科学探索性分析 (EDA): 在 EDA 阶段,交互式图形能够帮助数据科学家快速浏览数据,发现潜在的特征关系、异常值和数据质量问题。

  • 仪表盘与监控系统: 交互式仪表盘能够实时展示关键指标,并允许用户通过交互操作深入查看细节数据,进行故障排查和性能监控。

  • Web 应用与报告: 将交互式图形嵌入到 Web 应用或报告中,可以提升用户体验,让用户能够更主动地参与到数据分析过程中。

  • 科学研究与数据可视化: 在科学研究领域,交互式图形可以帮助研究人员更有效地分析实验数据,发现科学规律,并将研究成果以更直观的方式呈现。

  • 教育与培训: 交互式图形可以作为教学工具,帮助学生更直观地理解抽象概念,并进行实践操作,提升学习效果。

7.3.2 Seaborn 与 Bokeh 的结合

Bokeh 是一个专注于现代 Web 浏览器的交互式可视化库。它能够生成美观、流畅、高性能的交互式图形,并支持多种交互工具,例如缩放、平移、选择、工具提示等。

将 Seaborn 与 Bokeh 结合,我们可以利用 Seaborn 强大的绘图功能生成基础图形,然后使用 Bokeh 将其转化为交互式图形。

基本思路:

  1. 使用 Seaborn 绘制静态图形: 首先,使用 Seaborn 像往常一样绘制你需要的图形,例如散点图、直方图、箱线图等。

  2. 提取 Seaborn 图形的数据: Seaborn 图形底层是 Matplotlib 对象。我们需要从 Matplotlib 对象中提取绘图所需的数据(例如 x 轴数据、y 轴数据、颜色、大小等)。

  3. 使用 Bokeh 绘制交互式图形: 将提取的数据传递给 Bokeh,并使用 Bokeh 的绘图函数(例如 figure, scatter, line 等)重新绘制图形,并添加交互工具。

代码实践:散点图的交互化

我们以一个简单的散点图为例,演示如何使用 Seaborn 绘制散点图,并使用 Bokeh 将其转化为交互式散点图。

import seaborn as sns import matplotlib.pyplot as plt from bokeh.plotting import figure, show from bokeh.models import HoverTool # 1. 使用 Seaborn 绘制静态散点图 tips = sns.load_dataset('tips') plt.figure(figsize=(8, 6)) sns.scatterplot(x='total_bill', y='tip', data=tips, hue='smoker', size='size', sizes=(20, 200)) plt.title('Seaborn Static Scatter Plot') plt.show() # 2. 提取 Seaborn 图形的数据 (实际上 Seaborn 已经处理好数据,我们直接用 pandas DataFrame) # 数据已经存储在 'tips' DataFrame 中 # 3. 使用 Bokeh 绘制交互式散点图 p = figure( title='Bokeh Interactive Scatter Plot', x_axis_label='Total Bill', y_axis_label='Tip', tools="pan,wheel_zoom,box_zoom,reset,hover,save" # 添加交互工具 ) # 颜色映射,与 Seaborn 的 hue 参数对应 smoker_colors = {'Yes': 'red', 'No': 'blue'} # 大小映射,与 Seaborn 的 size 参数对应 size_scaler = 5 # 调整大小比例 for smoker_status in tips['smoker'].unique(): subset = tips[tips['smoker'] == smoker_status] p.scatter( x=subset['total_bill'], y=subset['tip'], legend_label=smoker_status, color=[smoker_colors[status] for status in subset['smoker']], # 使用颜色映射 size=subset['size'] * size_scaler, # 使用大小映射 alpha=0.6 # 设置透明度 ) # 配置 HoverTool,显示悬停提示信息 hover = p.select(dict(type=HoverTool)) hover.tooltips = [ ("Total Bill", "$x"), ("Tip", "$y"), ("Smoker", "@legend_label"), ("Size", "@size") ] show(p)

代码详解:

  • 导入库: 导入必要的库,包括 seaborn, matplotlib.pyplot, bokeh.plotting, bokeh.models

  • 绘制 Seaborn 静态散点图: 使用 sns.scatterplot 绘制静态散点图,作为对比和数据来源。

  • 提取数据 (直接使用 DataFrame): 由于 Seaborn 基于 Pandas DataFrame 工作,数据已经整理好,我们可以直接使用 tips DataFrame。

  • 创建 Bokeh Figure: 使用 figure() 函数创建一个 Bokeh 图形对象,设置标题、轴标签和交互工具。

    • tools="pan,wheel_zoom,box_zoom,reset,hover,save": 定义了图形的交互工具栏,包括平移、滚轮缩放、框选缩放、重置、悬停提示和保存。
  • 循环绘制散点: 为了实现 Seaborn 的 huesize 参数效果,我们循环遍历 smoker 列的唯一值,为每种 smoker 状态绘制一组散点。

    • p.scatter(...): 使用 p.scatter() 函数绘制散点。

      • x=subset['total_bill'], y=subset['tip']: 设置 x 轴和 y 轴数据。

      • legend_label=smoker_status: 设置图例标签。

      • color=[smoker_colors[status] for status in subset['smoker']]: 使用颜色映射,根据 smoker 状态设置颜色。

      • size=subset['size'] * size_scaler: 使用大小映射,根据 size 列设置散点大小,并乘以 size_scaler 调整大小比例。

      • alpha=0.6: 设置散点透明度,使重叠的点更容易区分。

  • 配置 HoverTool: 使用 HoverTool 添加悬停提示信息。

    • hover = p.select(dict(type=HoverTool)): 选择图形中的 HoverTool 对象。

    • hover.tooltips = [...]: 设置悬停提示内容,使用 "$x", "$y", "@legend_label", "@size" 等占位符引用数据。

  • 显示图形: 使用 show(p) 函数在浏览器中显示交互式图形。

mermaid graph TD 图示数据流:

图示解释:

  1. 首先,我们使用 Seaborn 绘制静态图形,但这步主要是为了对比和理解数据结构。

  2. 关键在于我们从 Seaborn 使用的 Pandas DataFrame 中获取数据。

  3. 然后,我们将这些数据传递给 Bokeh 的 figure 对象,作为绘制交互式图形的基础。

  4. 最终,Bokeh 基于这些数据和我们设置的交互工具,生成交互式图形。

更复杂的例子:箱线图的交互化

除了散点图,我们还可以将其他 Seaborn 图形交互化,例如箱线图。

import seaborn as sns import matplotlib.pyplot as plt from bokeh.plotting import figure, show from bokeh.models import ColumnDataSource, HoverTool # 1. 使用 Seaborn 绘制静态箱线图 tips = sns.load_dataset('tips') plt.figure(figsize=(8, 6)) sns.boxplot(x='day', y='total_bill', data=tips, hue='smoker') plt.title('Seaborn Static Boxplot') plt.show() # 2. 提取 Seaborn 图形的数据 (需要手动计算箱线图的统计信息) # Seaborn 的箱线图底层使用 matplotlib 的 boxplot 函数,我们需要手动计算箱线图的统计信息 # 这里为了简化,我们直接使用 pandas groupby 计算均值和标准差作为示例,实际箱线图需要更复杂的计算 grouped_tips = tips.groupby('day')['total_bill'].agg(['mean', 'std']).reset_index() source = ColumnDataSource(grouped_tips) # 将数据转换为 Bokeh ColumnDataSource # 3. 使用 Bokeh 绘制交互式箱线图 (简化版,仅展示均值和标准差) p = figure( title='Bokeh Interactive Boxplot (Simplified)', x_axis_label='Day', y_axis_label='Total Bill (Mean and Std)', x_range=grouped_tips['day'].unique().tolist(), # 设置 x 轴范围 tools="pan,wheel_zoom,box_zoom,reset,hover,save" ) # 绘制均值点 p.circle( x='day', y='mean', source=source, size=10, color='blue', legend_label='Mean' ) # 绘制标准差线段 (简化表示) p.segment( x0='day', y0='mean', x1='day', y1='mean + std', source=source, color='red', legend_label='Std Dev' ) p.segment( x0='day', y0='mean', x1='day', y1='mean - std', source=source, color='red' ) # 配置 HoverTool hover = p.select(dict(type=HoverTool)) hover.tooltips = [ ("Day", "@day"), ("Mean Total Bill", "@mean{(0.2f)}"), # 格式化浮点数 ("Std Dev", "@std{(0.2f)}") ] show(p)

代码详解 (箱线图):

  • 数据处理 (简化版): 由于箱线图的绘制需要更复杂的统计信息,这里为了简化示例,我们使用 groupby 计算每天 total_bill 的均值和标准差,作为箱线图的简化表示。

  • ColumnDataSource: Bokeh 使用 ColumnDataSource 对象来管理数据,我们需要将 Pandas DataFrame 转换为 ColumnDataSource

  • 绘制均值点和标准差线段: 使用 p.circle() 绘制均值点,使用 p.segment() 绘制标准差线段 (简化箱线图的箱体和须)。

  • HoverTool 配置: 配置 HoverTool 显示每天的均值和标准差信息。

注意: 上述箱线图示例是简化的,真实的交互式箱线图需要更复杂的计算和绘制逻辑,才能完全复现 Seaborn 的箱线图效果。但这个例子已经展示了将 Seaborn 的数据和概念迁移到 Bokeh 进行交互化的基本思路。

7.3.3 Seaborn 与 Plotly 的结合

Plotly 也是一个流行的交互式可视化库,它支持 Python, JavaScript, R 等多种语言,并能够生成各种类型的交互式图形,包括 2D 图形、3D 图形、地图等。 Plotly 的优势在于其强大的功能和美观的默认样式,以及对在线和离线模式的支持。

与 Bokeh 类似,我们可以将 Seaborn 与 Plotly 结合,利用 Seaborn 的绘图能力和 Plotly 的交互特性。

基本思路与 Bokeh 类似:

  1. 使用 Seaborn 绘制静态图形: 首先使用 Seaborn 绘制基础图形。

  2. 提取 Seaborn 图形的数据: 从 Seaborn 图形或 underlying DataFrame 中提取数据。

  3. 使用 Plotly 绘制交互式图形: 使用 Plotly 的绘图函数(例如 plotly.graph_objects.Scatter, plotly.express.scatter 等)重新绘制图形,并添加交互功能。

代码实践:散点图的交互化 (Plotly)

我们继续以散点图为例,展示如何使用 Plotly 将 Seaborn 散点图交互化。

import seaborn as sns import plotly.express as px import plotly.graph_objects as go # 1. 使用 Seaborn 绘制静态散点图 (已经展示过,此处省略) # 2. 提取 Seaborn 图形的数据 (直接使用 DataFrame) tips = sns.load_dataset('tips') # 3. 使用 Plotly Express 绘制交互式散点图 (更简洁的方式) fig_express = px.scatter( tips, x='total_bill', y='tip', color='smoker', size='size', hover_data=['day', 'time'], # 添加额外的悬停信息 title='Plotly Express Interactive Scatter Plot' ) fig_express.show() # 4. 使用 Plotly Graph Objects 绘制交互式散点图 (更灵活的方式) fig_go = go.Figure() for smoker_status in tips['smoker'].unique(): subset = tips[tips['smoker'] == smoker_status] fig_go.add_trace(go.Scatter( x=subset['total_bill'], y=subset['tip'], mode='markers', # 设置为散点模式 marker=dict( size=subset['size'] * 5, # 调整大小比例 opacity=0.6 ), name=smoker_status, # 设置图例标签 text=subset['day'] + ', ' + subset['time'], # 设置悬停文本 hoverinfo='text+x+y' # 设置悬停信息显示内容 )) fig_go.update_layout( title='Plotly Graph Objects Interactive Scatter Plot', xaxis_title='Total Bill', yaxis_title='Tip' ) fig_go.show()

代码详解 (Plotly 散点图):

  • 导入库: 导入 seaborn, plotly.express, plotly.graph_objects

    • plotly.express (px): Plotly Express 提供了更简洁的 API,适用于快速创建常见的图形。

    • plotly.graph_objects (go): Plotly Graph Objects 提供了更底层的 API,更加灵活,可以定制更复杂的图形。

  • Plotly Express 方式:

    • px.scatter(...): 使用 px.scatter() 函数快速创建散点图。

      • 参数与 Seaborn 类似,例如 x, y, color, size 等。

      • hover_data=['day', 'time']: 添加额外的悬停信息,除了 x, y, color, size 之外,还显示 daytime 列的信息。

  • Plotly Graph Objects 方式:

    • go.Figure(): 创建 Plotly Figure 对象。

    • fig_go.add_trace(go.Scatter(...)): 使用 add_trace() 添加散点轨迹 (trace)。

      • mode='markers': 设置为散点模式。

      • marker=dict(...): 设置散点标记的样式,例如大小 size, 透明度 opacity

      • name=smoker_status: 设置图例标签。

      • text=subset['day'] + ', ' + subset['time']: 设置悬停文本内容,将 daytime 列拼接成字符串。

      • hoverinfo='text+x+y': 设置悬停信息显示内容,包括 text (悬停文本), x, y 坐标。

    • fig_go.update_layout(...): 更新图形布局,设置标题、轴标签等。

  • 显示图形: 使用 fig_express.show()fig_go.show() 显示交互式图形。

mermaid graph TD 图示数据流 (Plotly):

图示解释:

数据流与 Bokeh 类似,Seaborn 静态图形作为参考,关键是从 Pandas DataFrame 中提取数据,然后使用 Plotly 的 Figure 对象 (可以使用更简洁的 Express API 或更灵活的 Graph Objects API) 基于数据和交互配置生成 Plotly 交互式图形。

更复杂的例子:直方图的交互化 (Plotly)

import seaborn as sns import plotly.express as px import plotly.graph_objects as go # 1. 使用 Seaborn 绘制静态直方图 tips = sns.load_dataset('tips') plt.figure(figsize=(8, 6)) sns.histplot(tips['total_bill'], kde=True) # 添加核密度估计曲线 plt.title('Seaborn Static Histogram') plt.show() # 2. 提取 Seaborn 图形的数据 (直接使用 DataFrame) # 数据已经存储在 'tips' DataFrame 中 # 3. 使用 Plotly Express 绘制交互式直方图 fig_hist_express = px.histogram( tips, x='total_bill', marginal='rug', # 添加边缘地毯图 title='Plotly Express Interactive Histogram' ) fig_hist_express.show() # 4. 使用 Plotly Graph Objects 绘制交互式直方图 (更灵活的方式) fig_hist_go = go.Figure(data=[go.Histogram(x=tips['total_bill'])]) # 创建直方图轨迹 fig_hist_go.update_layout( title='Plotly Graph Objects Interactive Histogram', xaxis_title='Total Bill', yaxis_title='Frequency' ) fig_hist_go.show()

代码详解 (Plotly 直方图):

  • Plotly Express 方式:

    • px.histogram(...): 使用 px.histogram() 函数快速创建直方图。

      • marginal='rug': 添加边缘地毯图,显示每个数据点的具体位置。
  • Plotly Graph Objects 方式:

    • go.Histogram(x=tips['total_bill']): 创建直方图轨迹,直接指定 x 轴数据。
  • 布局更新: 使用 fig_hist_go.update_layout(...) 更新标题和轴标签。

7.3.4 Bokeh vs. Plotly 的选择

Bokeh 和 Plotly 都是优秀的交互式可视化库,它们各有优缺点,适用于不同的场景。

Bokeh 的优势:

  • 专注于 Web 浏览器: Bokeh 专门为现代 Web 浏览器设计,生成的图形在 Web 环境中性能更优,渲染更流畅。

  • 流式数据支持: Bokeh 对流式数据有良好的支持,可以实时更新图形,适用于实时监控和动态数据展示场景。

  • 更细粒度的控制: Bokeh 提供了更底层的 API,允许用户对图形的各个方面进行更精细的控制和定制。

Plotly 的优势:

  • 功能更全面: Plotly 支持更广泛的图形类型,包括 3D 图形、地图、金融图表等。

  • 更美观的默认样式: Plotly 的默认样式更加现代美观,无需过多调整即可生成高质量的图形。

  • 易用性: Plotly Express 提供了更简洁的 API,上手更容易,适合快速创建交互式图形。

  • 在线和离线模式: Plotly 支持在线和离线模式,可以方便地将图形发布到 Plotly Cloud 或本地离线环境。

如何选择:

  • Web 应用和流式数据: 如果你的应用场景主要是在 Web 浏览器中展示交互式图形,并且需要处理流式数据,Bokeh 可能是更好的选择。

  • 功能丰富性和易用性: 如果你需要更广泛的图形类型,更美观的默认样式,或者更易于使用的 API,Plotly 可能是更好的选择。

  • 快速原型和探索性分析: Plotly Express 的简洁 API 非常适合快速原型开发和探索性数据分析。

  • 高级定制和底层控制: 如果需要对图形进行更精细的控制和定制,Bokeh 的底层 API 可能更适合。

在实际应用中,可以根据具体的项目需求和个人偏好选择合适的库。 很多时候,Bokeh 和 Plotly 都可以完成相同的任务,选择哪个库更多的是风格和习惯的问题。

7.3.5 总结

核心要点回顾:

  • 交互式图形的价值: 交互式图形能够提升数据探索深度、洞察力、沟通效率和用户体验。

  • Seaborn + Bokeh/Plotly 的思路: 使用 Seaborn 绘制静态图形作为基础,从 Seaborn 使用的 Pandas DataFrame 中提取数据,然后使用 Bokeh 或 Plotly 重新绘制交互式图形并添加交互功能。

  • 代码实践: 我们通过散点图和箱线图 (简化版) 的例子,演示了如何使用 Bokeh 和 Plotly 将 Seaborn 图形交互化。

  • Bokeh vs. Plotly 的选择: Bokeh 专注于 Web 浏览器和流式数据,更注重性能和底层控制; Plotly 功能更全面,默认样式美观,易用性更强。

掌握 Seaborn 与 Bokeh 或 Plotly 的结合技巧,将极大地扩展你的数据可视化能力,让你能够创建更具吸引力、更富洞察力、更实用的交互式数据可视化作品,更好地服务于数据分析、科学研究、Web 应用等多种场景。


发布者: 作者: 转发
评论区 (0)
U