Bokeh的绘图数据

2020年06月29日 8点热度 0人点赞 0条评论

Bokeh的绘图数据可以直接使用Python中的list、dict,也可以使用Numpy中的Array以及Pandas中的DataFrame数据类型。绘制较复杂的图形时,也可以使用Bokeh独有的ColumnDataSource定义绘图数据,以便在绘图方法中直接调用列名进行绘图。当需要在原始数据中更新、筛选部分数据时,Bokeh提供了一些专属方法,这些方法在进行较复杂的动态交互时会经常用到。

# 导入库
from bokeh.plotting import figure, output_notebook, show
output_notebook()  # 在notebook中显示

Python List

x=[1, 2, 3, 4, 5]
y=[3, 7, 8, 5, 1]
# 其中x,y数据列表长度相同,即坐标对应关系
p = figure(plot_width=400, plot_height=400)
p.circle(x, y, size=20)
show(p)
from bokeh.models import ColumnDataSource
source = ColumnDataSource(data={
    'x' : [1, 2, 3, 4, 5],
    'y' : [3, 7, 8, 5, 1],
})  # 其中数据列表长度相同,即坐标对应关系
p = figure(plot_width=400, plot_height=400)
p.circle('x', 'y', size=20, source=source)
show(p)

Python Dict

import numpy as np
from bokeh.transform import linear_cmap
# 调色盘参见 https://bokeh.pydata.org/en/latest/docs/reference/palettes.html
N = 4000
data = dict(x=np.random.random(size=N) * 100,
            y=np.random.random(size=N) * 100,
            r=np.random.random(size=N) * 1.5)
p = figure(plot_width=400, plot_height=400)
p.circle('x', 'y', radius='r', source=data, fill_alpha=0.6,
         # 基于x数值对'Viridis256'进行线性映射,结果为一个色值列表
         color=linear_cmap('x', 'Viridis256', 0, 100))
show(p) 

NumPy Arrays

import numpy as np
import random
# 使用NumPy创建数组
x_red = np.array([1,2,3,4,5])
y_red = np.array([5,6,7,8,9])
x_blue = np.array([10,11,12,13])
y_blue = np.array([14,15,16,17])
# 画布
plot = figure()
# 绘图
plot.circle(x_red, y_red, size = 9, color = 'red', alpha = 0.8)
plot.circle(x_blue, y_blue, size = 9, color = 'blue', alpha = 0.8)
# 显示
show(plot)

Pandas DataFrame

from bokeh.sampledata.iris import flowers as df  # 从数据集获取的数据为DataFrame格式
# source = ColumnDataSource(df)  # 直接转换
p = figure(plot_width=400, plot_height=400)
p.circle('petal_length', 'petal_width', source=df)
show(p)
from bokeh.sampledata.iris import flowers as df  # 从数据集获取的数据为DataFrame格式
source = ColumnDataSource(df)  # 直接转换
p = figure(plot_width=400, plot_height=400)
p.circle('petal_length', 'petal_width', source=source)
show(p)
df.head()

Bokeh ColumnDataSource

from bokeh.models import ColumnDataSource
from bokeh.sampledata.iris import flowers as df
p = figure(plot_width=400, plot_height=400)
p.circle('petal_length', 'petal_width', source=ColumnDataSource(df), color='green')
# p.circle('petal_length', 'petal_width', source=df, color='green')
show(p)

数据更新、筛选

from bokeh.models import ColumnDataSource
from bokeh.layouts import gridplot
import numpy as np
import pandas as pd
data1 = {'x_values': [1, 2, 9, 4, 5],
        'y_values': [6, 7, 2, 3, 6]}
source = ColumnDataSource(data=data1)
p1 = figure(plot_width=300, plot_height=300, title= 'origin data')
p1.circle(x='x_values', y='y_values', source=source, size=20)
show(p1)#原始数据
new_data = {'x_values':  [6, 7, 2, 3, 6],
        'y_values': [1, 2, 9, 4, 5]}
# 2.在已有数据基础上添加新的数据 (append)
source.stream(new_data)
p2 = figure(plot_width=300, plot_height=300,title= 'append data with stream')
p2.circle(x='x_values', y='y_values', source=source, size=20)
show(p2) # 添加数据
# 3.更新单个数据
# {column:(index, new_value) }
source.patch({'x_values':[(0,15)]})
p3 = figure(plot_width=300, plot_height=300,title= 'revise single value with patch')
p3.circle(x='x_values', y='y_values', source=source, size=20)
show(p3)
# 4.更新多个数据
# {column:(slice, new_values) }
s = slice(2,4)
source.patch({'x_values':[(s,[20,15])]})
p4 = figure(plot_width=300, plot_height=300,title= 'revise multiple values with patch')
p4.circle(x='x_values', y='y_values', source=source, size=20)
show(p4)

数据格式转换

from math import pi
import pandas as pd
from bokeh.palettes import Category20c
from bokeh.transform import cumsum
# 数据
x = { 'United States': 157, 'United Kingdom': 93, 'Japan': 89, 'China': 63,
      'Germany': 44, 'India': 42, 'Italy': 40, 'Australia': 35, 'Brazil': 32,
      'France': 31, 'Spain': 29 }
data = pd.Series(x).reset_index(name='value').rename(columns={'index':'country'}) # 将上述字典转换为DataFrame格式
data['color'] = Category20c[len(x)]
# angle = value / total * 2pi,计算每组角度
data['angle'] = data['value']/data['value'].sum() * 2*pi
p = figure(plot_height=350, title="Pie Chart", 
#            toolbar_location=None,
           tools="hover,save", tooltips="国家@country: 数值@value")  # 已支持中文,鼠标悬停饼图显示数据
p.wedge(x=0, y=1, radius=0.4, # 圆心位置及半径
        # 每组起始角度
        start_angle=cumsum('angle', include_zero=True), end_angle=cumsum('angle'),
        line_color="white", fill_color='color', legend='country', source=data)
# 与直角坐标系相关参数隐藏,自行注释掉查看效果
p.axis.axis_label=None
p.axis.visible=False
p.grid.grid_line_color = None
show(p)
?cumsum
p = figure(plot_height=350, title="Donut Chart", 
#            toolbar_location=None,
           tools="hover,save", tooltips="国家@country: 数值@value")  # 已支持中文,鼠标悬停饼图显示数据
p.annular_wedge(x=0, y=1, outer_radius=0.4,inner_radius=0.3, 
        # use cumsum to cumulatively sum the values for start and end angles
        start_angle=cumsum('angle', include_zero=True), end_angle=cumsum('angle'),
        line_color="white", fill_color='color', legend='country', source=data)
p.annular_wedge(x=0, y=1, outer_radius=0.3,inner_radius=0, 
        # use cumsum to cumulatively sum the values for start and end angles
        start_angle=cumsum('angle', include_zero=True), end_angle=cumsum('angle'),
        line_color="white", fill_color= 'white', legend='country', source=data)
p.axis.axis_label=None
p.axis.visible=False
p.grid.grid_line_color = None
show(p)
未经允许不得转载!Bokeh的绘图数据

update

纸上得来终觉浅, 绝知此事须躬行。