Python交互圖表可視化Bokeh:5 柱狀圖| 堆疊圖| 直方圖


柱狀圖/堆疊圖/直方圖

① 單系列柱狀圖
② 多系列柱狀圖
③ 堆疊圖
④ 直方圖

 1.單系列柱狀圖

import numpy as np
import pandas as pd
import matplotlib.pyplot as plt
% matplotlib inline

import warnings
warnings.filterwarnings('ignore') 
# 不發出警告

from bokeh.io import output_notebook
output_notebook()
# 導入notebook繪圖模塊

from bokeh.plotting import figure,show
from bokeh.models import ColumnDataSource
# 導入圖表繪制、圖標展示模塊
# 導入ColumnDataSource模塊

p.vbar() p.hbar()
p.vbar(x=[1, 2, 3], width=0.5, bottom=0,top=[1.2, 2.5, 3.7], #color = ['red','blue','green'], alpha = 0.8 
line_width = 1,line_alpha = 0.8,line_color = 'black', line_dash = [5,2],fill_color = 'red',fill_alpha = 0.6 )
# 1、單系列柱狀圖
# vbar
df = pd.Series(np.random.randint(0,100,30))
#print(df.head())

p = figure(plot_width=400, plot_height=400)
p.vbar(x=[1, 2, 3], width=0.5, bottom=0,top=[1.2, 2.5, 3.7],  # x:橫軸坐標,width:寬度,bottom:底高度,top:頂高度 ; bottom=[1,2,3]
       #color = ['red','blue','green'], alpha = 0.8   # 整體顏色設置,也可單獨設置 → color="firebrick"
       line_width = 1,line_alpha = 0.8,line_color = 'black', line_dash = [5,2],    # 單獨設置線參數
       fill_color = 'red',fill_alpha = 0.6    # 單獨設置填充顏色參數
      )
# 繪制豎向柱狀圖
# p.vbar(x=df.index, width=0.5, bottom=0,top=df.values,  # x:橫軸坐標,width:寬度,bottom:底高度,top:頂高度 ; bottom=[1,2,3]
#        #color = ['red','blue','green'], alpha = 0.8   # 整體顏色設置,也可單獨設置 → color="firebrick"
#        line_width = 1,line_alpha = 0.8,line_color = 'black', line_dash = [5,2],    # 單獨設置線參數
#        fill_color = 'red',fill_alpha = 0.6    # 單獨設置填充顏色參數
#       )

show(p)

# 1、單系列柱狀圖
# hbar
# df = pd.DataFrame({'value':np.random.randn(100)*10,
#                   'color':np.random.choice(['red', 'blue', 'green'], 100)})
# print(df.head())
p = figure(plot_width=400, plot_height=400)
p.hbar(y=[1, 2, 3], height=0.5, left=0,right=[1.2, 2.5, 3.7],  # y:縱軸坐標,height:厚度,left:左邊最小值,right:右邊最大值
       color = ['red','blue','green'])
# 繪制豎向柱狀圖

# p.hbar(y=df.index, height=0.5, left=0,right=df['value'],  # y:縱軸坐標,height:厚度,left:左邊最小值,right:右邊最大值
#        color = df['color'])

show(p)

分類標簽的設置

p.vbar(x='fruits', top='counts', source=source, width=0.9, alpha = 0.8,color = factor_cmap('fruits', palette=Spectral6, factors=fruits), legend="fruits")
# 1、單系列柱狀圖 - 分類設置標簽
# ColumnDataSource

from bokeh.palettes import Spectral6
from bokeh.transform import factor_cmap
# 導入相關模塊

fruits = ['Apples', 'Pears', 'Nectarines', 'Plums', 'Grapes', 'Strawberries']
counts = [5, 3, 4, 2, 4, 6]
source = ColumnDataSource(data=dict(fruits=fruits, counts=counts))
colors = [ "salmon", "olive", "darkred", "goldenrod", "skyblue", "orange"]
# 創建一個包含標簽的data,對象類型為ColumnDataSource

p = figure(x_range=fruits, y_range=(0,9), plot_height=350, title="Fruit Counts",tools="") #x_range一開始就要設置成一個字符串的列表;要一一對應

p.vbar(x='fruits', top='counts', source=source,    # 加載數據另一個方式
       width=0.9, alpha = 0.8,
       color = factor_cmap('fruits', palette=Spectral6, factors=fruits),    # 設置顏色
       legend="fruits")
# 繪制柱狀圖,橫軸直接顯示標簽
# factor_cmap(field_name, palette, factors, start=0, end=None, nan_color='gray'):顏色轉換模塊,生成一個顏色轉換對象
# field_name:分類名稱
# palette:調色盤
# factors:用於在調色盤中分顏色的參數
# 參考文檔:http://bokeh.pydata.org/en/latest/docs/reference/transform.html

p.xgrid.grid_line_color = None
p.legend.orientation = "horizontal"
p.legend.location = "top_center"
# 其他參數設置
#cmd -->> conda install bokeh  ;  conda install json
show(p)

 

 2. 多系列柱狀圖

p.vbar(x=dodge('index', -0.25, range=p.x_range), top='2015', width=0.2, source=source,color="#c9d9d3", legend=value("2015")) #用dodge的方法把3個柱狀圖拼到了一起
p.vbar(x=dodge('index',  0.0,  range=p.x_range), top='2016', width=0.2, source=source,color="#718dbf", legend=value("2016"))
p.vbar(x=dodge('index',  0.25, range=p.x_range), top='2017', width=0.2, source=source,color="#e84d60", legend=value("2017"))
# 2、多系列柱狀圖
# vbar

from bokeh.transform import dodge
from bokeh.core.properties import value
# 導入dodge、value模塊

df = pd.DataFrame({'2015':[2, 1, 4, 3, 2, 4],'2016':[5, 3, 3, 2, 4, 6], '2017':[3, 2, 4, 4, 5, 3]},
                 index = ['Apples', 'Pears', 'Nectarines', 'Plums', 'Grapes', 'Strawberries'])
# 創建數據
print(df)
fruits = df.index.tolist()   # 橫坐標
years = df.columns.tolist()   # 系列名
data = {'index':fruits} for year in years:
    data[year] = df[year].tolist()
print(data) 
# 生成數據,數據格式為dict; 專門把dataframe轉換為字典,然后再轉換為ColumnDataSource;可以把這些步驟給都省了,也可以的。

source = ColumnDataSource(data=data)  #把上面轉換字典步驟直接去掉也是可以的,這時把 data = df
# 將數據轉化為ColumnDataSource對象


p = figure(x_range=fruits, y_range=(0, 10), plot_height=350, title="Fruit Counts by Year",tools="")

p.vbar(x=dodge('index', -0.25, range=p.x_range), top='2015', width=0.2, source=source,color="#c9d9d3", legend=value("2015")) #用dodge的方法把3個柱狀圖拼到了一起
p.vbar(x=dodge('index',  0.0,  range=p.x_range), top='2016', width=0.2, source=source,color="#718dbf", legend=value("2016"))
p.vbar(x=dodge('index',  0.25, range=p.x_range), top='2017', width=0.2, source=source,color="#e84d60", legend=value("2017"))
# 繪制多系列柱狀圖       0.25和width=0.2是柱狀圖之間的空隙間隔,都是0.2了就沒有空隙了
# dodge(field_name, value, range=None) → 轉換成一個可分組的對象,value為元素的位置(配合width設置)
# value(val, transform=None) → 按照年份分為dict

p.xgrid.grid_line_color = None
p.legend.location = "top_left"
p.legend.orientation = "horizontal"
# 其他參數設置

show(p)

官方示例很多情況是用的列表的形式,bokeh本身不是基於pandas構建的可視化工具,所以它基本上是用的python自己的數據結構字典、列表;我們做數據分析肯定是基於pandas,以上就是做了一個模擬,如果數據結構是DataFrame,怎么把它變成一個字典,再把它變成一個ColumnDataSource,同樣的也可以直接用dataframe來創建

from bokeh.transform import dodge
from bokeh.core.properties import value
# 導入dodge、value模塊

df = pd.DataFrame({'2015':[2, 1, 4, 3, 2, 4],'2016':[5, 3, 3, 2, 4, 6], '2017':[3, 2, 4, 4, 5, 3]},
                 index = ['Apples', 'Pears', 'Nectarines', 'Plums', 'Grapes', 'Strawberries'])
# # 創建數據
# print(df)

source = ColumnDataSource(data=df) # 將數據轉化為ColumnDataSource對象

p = figure(x_range=fruits, y_range=(0, 10), plot_height=350, title="Fruit Counts by Year",tools="")

p.vbar(x=dodge('index', -0.25, range=p.x_range), top='2015', width=0.2, source=source,color="#c9d9d3", legend=value("2015")) #用dodge的方法把3個柱狀圖拼到了一起
p.vbar(x=dodge('index',  0.0,  range=p.x_range), top='2016', width=0.2, source=source,color="#718dbf", legend=value("2016"))
p.vbar(x=dodge('index',  0.25, range=p.x_range), top='2017', width=0.2, source=source,color="#e84d60", legend=value("2017"))
# 繪制多系列柱狀圖       0.25和width=0.2是柱狀圖之間的空隙間隔,都是0.2了就沒有空隙了
# dodge(field_name, value, range=None) → 轉換成一個可分組的對象,value為元素的位置(配合width設置)
# value(val, transform=None) → 按照年份分為dict

p.xgrid.grid_line_color = None
p.legend.location = "top_left"
p.legend.orientation = "horizontal"
# 其他參數設置

show(p)

    df---->>     data---->>

3. 堆疊圖

p.vbar_stack(["2015", "2016", "2017"], # 設置堆疊值,這里source中包含了不同年份的值
                         x='fruits',     # 設置x坐標
                         source=source, #包含了2015/2016/2017的數據的;
                         width=0.9, color=colors,
                         legend=[value(x) for x in years], name=years) #對整個數據做一個分組集合變成一個列表
# 3、堆疊圖

from bokeh.core.properties import value
# 導入value模塊

fruits = ['Apples', 'Pears', 'Nectarines', 'Plums', 'Grapes', 'Strawberries']
years = ["2015", "2016", "2017"]
colors = ["#c9d9d3", "#718dbf", "#e84d60"]
data = {'fruits' : fruits,
        '2015'   : [2, 1, 4, 3, 2, 4],
        '2016'   : [5, 3, 4, 2, 4, 6],
        '2017'   : [3, 2, 4, 4, 5, 3]}
# df = pd.DataFrame(data)
# print(df)
# source = ColumnDataSource(data = df) #也可以使用DataFrame 
source = ColumnDataSource(data=data)


# 創建數據

p = figure(x_range=fruits, plot_height=350, title="Fruit Counts by Year",tools="")
renderers = p.vbar_stack(["2015", "2016", "2017"], #可以用years代替,就是上邊設置的變量 # 設置堆疊值,這里source中包含了不同年份的值,years變量用於識別不同堆疊層
                         x='fruits',     # 設置x坐標
                         source=source, #包含了2015/2016/2017的數據的;  主要設置的就是這3個參數 
                         width=0.9, color=colors,
                         legend=[value(x) for x in years], name=years) #對整個數據做一個分組集合變成一個列表
# 繪制堆疊圖
# 注意第一個參數需要放years

p.xgrid.grid_line_color = None
p.axis.minor_tick_line_color = None
p.outline_line_color = None
p.legend.location = "top_left"
p.legend.orientation = "horizontal"
# 設置其他參數

show(p)
[value(x) for x in years]

[{'value': '2015'}, {'value': '2016'}, {'value': '2017'}]

 

# 3、堆疊圖

from bokeh.palettes import GnBu3, OrRd3
# 導入顏色模塊

fruits = ['Apples', 'Pears', 'Nectarines', 'Plums', 'Grapes', 'Strawberries']
years = ["2015", "2016", "2017"]
exports = {'fruits' : fruits,
           '2015'   : [2, 1, 4, 3, 2, 4],
           '2016'   : [5, 3, 4, 2, 4, 6],
           '2017'   : [3, 2, 4, 4, 5, 3]}
imports = {'fruits' : fruits,
           '2015'   : [-1, 0, -1, -3, -2, -1],
           '2016'   : [-2, -1, -3, -1, -2, -2],
           '2017'   : [-1, -2, -1, 0, -2, -2]}

p = figure(y_range=fruits, plot_height=350, x_range=(-16, 16), title="Fruit import/export, by year")

p.hbar_stack(years, y='fruits', height=0.9, color=GnBu3, source=ColumnDataSource(exports),
             legend=["%s exports" % x for x in years])      # 繪制出口數據堆疊圖

p.hbar_stack(years, y='fruits', height=0.9, color=OrRd3, source=ColumnDataSource(imports),
             legend=["%s imports" % x for x in years])      # 繪制進口數據堆疊圖,這里值為負值

p.y_range.range_padding = 0.2     # 調整邊界間隔
p.ygrid.grid_line_color = None   
p.legend.location = "top_left"
p.axis.minor_tick_line_color = None
p.outline_line_color = None
# 設置其他參數

show(p)

 

 4. 直方圖

hist, edges = np.histogram(df['value'],bins=20) 
p.quad(top=hist, bottom=0, left=edges[:-1], right=edges[1:],   # 分別代表每個柱子的四邊值,上下左右,top=hist計數的值,第一個箱子的左跟右就是第一個值+第二個值
        fill_color="#036564", line_color="#033649")
 
# 4、直方圖
# np.histogram + figure.quad()
# 不需要構建ColumnDataSource對象

df = pd.DataFrame({'value': np.random.randn(1000)*100})
df.index.name = 'index'
print(df.head())
# 創建數據

hist, edges = np.histogram(df['value'],bins=20) #把這1000個值拆分成20個箱子,整個箱子肯定會有一個value值的也就是它的個數
print(hist) #代表不同箱子的個數
print(edges) #把它分成不同箱子之后,每個箱子的位置坐標
# 將數據解析成直方圖統計格式
# 高階函數np.histogram(a, bins=10, range=None, weights=None, density=None) 
# a:數據
# bins:箱數
# range:最大最小值的范圍,如果不設定則為(a.min(), a.max())
# weights:權重
# density:為True則返回“頻率”,為False則返回“計數”
# 返回值1 - hist:每個箱子的統計值(top)
# 返回值2 - edges:每個箱子的位置坐標,這里n個bins將會有n+1個edges;假如有10個箱子,就會有10+1個位置

p = figure(title="HIST", tools="save",background_fill_color="#E8DDCB")
p.quad(top=hist, bottom=0, left=edges[:-1], right=edges[1:],   # 分別代表每個柱子的四邊值,上下左右,top=hist計數的值,第一個箱子的左跟右就是第一個值+第二個值
        fill_color="#036564", line_color="#033649")
# figure.quad繪制直方圖

show(p)

 

            value
index            
0      109.879109
1      -49.315234
2     -149.590185
3       83.290324
4      -16.367743
[  1   2   2   3  21  25  59  85 104 151 140 110 101  82  47  31  22   8   #這里1就是在-356.79345893到-323.021329之間有1個;在-323.021329到-289.2491919906之間有2個
   2   4]
[-356.79345893 -323.021329   -289.24919906 -255.47706913 -221.7049392
 -187.93280926 -154.16067933 -120.3885494   -86.61641947  -52.84428953
  -19.0721596    14.69997033   48.47210027   82.2442302   116.01636013
  149.78849006  183.56062     217.33274993  251.10487986  284.8770098
  318.64913973]
In [ ]:

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM