首页 > 解决方案 > Jupyter 交互未导出到 html 中

问题描述

我最近开始编码,现在正在对开源 Corona 数据进行数据分析。我在 Jupyter Notebook 中使用 Python3 构建了一个交互式图表。唯一的事情是,我建立了一个交互,但它只显示在 Notebook 内部,而不是在导出到 html 时显示。有人可以告诉我这是为什么吗?提前谢谢了。

代码:

# Import the necessary packages

import pandas as pd
import numpy as np 
import requests
import io

from bokeh.io import push_notebook,output_file
from bokeh.io import show, curdoc
from bokeh.plotting import figure, output_notebook
from bokeh.models import HoverTool, ColumnDataSource, Select
from bokeh.layouts import row
from bokeh.models.tickers import FixedTicker
from bokeh.models.callbacks import CustomJS

from ipywidgets import interact

output_notebook()

#---------------------------------------------------------------------------------------------------   
# Import the data
#---------------------------------------------------------------------------------------------------

url = 'https://data.humdata.org/hxlproxy/api/data-preview.csv?url=https%3A%2F%2Fraw.githubusercontent.com%2FCSSEGISandData%2FCOVID-19%2Fmaster%2Fcsse_covid_19_data%2Fcsse_covid_19_time_series%2Ftime_series_covid19_confirmed_global.csv&filename=time_series_covid19_confirmed_global.csv'
s=requests.get(url).content

url2 = 'https://data.humdata.org/hxlproxy/api/data-preview.csv?url=https%3A%2F%2Fraw.githubusercontent.com%2FCSSEGISandData%2FCOVID-19%2Fmaster%2Fcsse_covid_19_data%2Fcsse_covid_19_time_series%2Ftime_series_covid19_deaths_global.csv&filename=time_series_covid19_deaths_global.csv'
s2 =requests.get(url2).content

df = pd.read_csv(io.StringIO(s.decode('utf-8')))
df = df.fillna("")

df2 = pd.read_csv(io.StringIO(s2.decode('utf-8')))
df2 = df2.fillna("")

#--------------------------------------------------------------------------------------------------- 
# Number of reported Corona cases
#---------------------------------------------------------------------------------------------------

Numb_cases = df.iloc[:,0:2].merge(df.iloc[:,4:],how='inner',right_index=True,left_index=True).fillna("")
Numb_cases.iloc[:,1] = Numb_cases.iloc[:,1]+ " : " + Numb_cases.iloc[:,0]
Numb_cases = Numb_cases.iloc[:,1:]
Numb_cases = Numb_cases.transpose()
Numb_cases.columns = Numb_cases.iloc[0,:]
Numb_cases = Numb_cases.iloc[1:,:]
Numb_cases.index = pd.to_datetime(Numb_cases.index)


#---------------------------------------------------------------------------------------------------
# Number of reported Corona deaths
#---------------------------------------------------------------------------------------------------

Numb_deaths = df2.iloc[:,0:2].merge(df2.iloc[:,4:],how='inner',right_index=True,left_index=True).fillna("")
Numb_deaths.iloc[:,1] = Numb_deaths.iloc[:,1]+ " : " + Numb_deaths.iloc[:,0]
Numb_deaths = Numb_deaths.iloc[:,1:]
Numb_deaths = Numb_deaths.transpose()
Numb_deaths.columns = Numb_deaths.iloc[0,:]
Numb_deaths = Numb_deaths.iloc[1:,:]

dates = pd.DataFrame(Numb_deaths.index)

Numb_deaths.index = pd.to_datetime(Numb_deaths.index)

#---------------------------------------------------------------------------------------------------
# Create the interactive graphs
#---------------------------------------------------------------------------------------------------

x = Numb_deaths.index
countries = list(Numb_cases.columns)

#plot1
source = ColumnDataSource(data={
'x' : Numb_cases.index,
'y' : Numb_cases
})

p = figure(x_axis_type="datetime", plot_width=400, plot_height=400, tools="box_zoom,reset")

p.yaxis.axis_label = "Total Number of Cases"
p.xaxis.axis_label = "Date"

countries = list(Numb_cases.columns)

# Create a HoverTool: hover
hover = HoverTool(tooltips = [('Numb cases:', '@y'),('Date :','$x{%F}')],formatters={'$x': 'datetime'},mode='mouse')

# Add the hover tool to the figure p
p.add_tools(hover)


#Plot2
source2 = ColumnDataSource(data={
'x' : Numb_deaths.index,
'y' : Numb_deaths
})

p2 = figure(x_axis_type="datetime", plot_width=400, plot_height=400,tools="box_zoom,reset")

p2.yaxis.axis_label = "Total Number of Deaths"
p2.xaxis.axis_label = "Date"


countries = list(Numb_deaths.columns)

# Create a HoverTool: hover
hover = HoverTool(tooltips = [('Numb deaths:', '@y'),('Date :','$x{%F}')],formatters={'$x': 'datetime'},mode='mouse')

# Add the hover tool to the figure p
p2.add_tools(hover)

# Define a callback function: update_plot
def update(Country):
source.data = {
        'x' : x,
        'y' : Numb_cases.loc[:,Country]
    }
p.circle('x', 'y',source=source ,size=10,
     fill_color='grey', alpha=0.40, line_color='grey',
     hover_fill_color='firebrick', hover_alpha=0.90,
     hover_line_color='white')
source2.data = {
        'x' : x,
        'y' : Numb_deaths.loc[:,Country]
    }
p2.circle('x', 'y',source=source2 ,size=10,
     fill_color='grey', alpha=0.40, line_color=None,
     hover_fill_color='firebrick', hover_alpha=0.90, 
     hover_line_color='white')
push_notebook()

interact(update, Country=countries)

show(row(p,p2),notebook_handle=True)

Jupyter Notebook 内部的图表

导出的 html 内的图形

标签: pythonhtmljupyterbokeh

解决方案


当您使用笔记本时,您会在某个地方运行一个服务器,该服务器在update函数内部运行该 Python 代码。但是当你只有一个静态的 HTML 页面时,你没有任何运行 Python 的东西——这就是该函数不起作用的原因。

您要么需要继续使用笔记本电脑,要么使用bokeh serve. 也可以将 Bokeh 嵌入到一些现有的服务器中,例如 Flask 或 Django。最后一个选项是update用 JavaScript 重写函数,以便它可以嵌入到 HTML 中。


推荐阅读