当散景条形图上的缩放级别发生变化时,是否可以保持相同数量的 x 轴刻度标签可见?

Tri*_*ril 5 python django bar-chart bokeh

我正在使用 Django 并使用数据库中的数据生成散景条形图。我在下面放了一个基本的代码示例。我正在从日期时间变量生成 x 轴刻度标签,以使用日期时间格式的字符串在每小时获取一个刻度。这会导致所有刻度标签始终可见。放大时很好,但缩小时不漂亮,因为标签彼此重叠。

有没有办法让散景自动调整哪些刻度标签可见,因为缩放级别发生变化以保持恒定数量的刻度标签可见?

视图.py:

# -*- coding: utf-8 -*-
from django.shortcuts import render

from bokeh.plotting import *
from bokeh.resources import CDN
from bokeh.embed import components
from bokeh.charts import Bar
from bokeh.models import Range1d

from collections import OrderedDict
import datetime

def plot_1_bar(data, y, y_lab, title, xlab, ylab, yrange, palette):
    x0_list_str = []

    y_list = []

    # x_axis_type == "datetime":
    i_x = 'x1'
    i_y = y[0]
    for idx, val in enumerate(data):
        x0_list_str.append(val[i_x].strftime("%Y-%m-%d %H h"))
        y_list.append(val[i_y])

    data_x = x0_list_str    
    data_y = OrderedDict()
    data_y[y_lab[0]] = y_list

    plot = Bar(data_y, data_x, title=title, xlabel=xlab, 
               ylabel=ylab, stacked=True, continuous_range=yrange, 
               palette=palette, legend=True, height=400)
    return components(plot, CDN)

def plot1(request):

    script_bokeh = ""
    div_bokeh = ""

    data = []
    data.append({'x1': datetime.datetime(2015,1,1,8,0,0,0),'y1': 0})
    data.append({'x1': datetime.datetime(2015,1,1,9,0,0,0),'y1': 0})
    data.append({'x1': datetime.datetime(2015,1,1,10,0,0,0),'y1': 0})
    data.append({'x1': datetime.datetime(2015,1,1,11,0,0,0),'y1': 0})
    data.append({'x1': datetime.datetime(2015,1,1,12,0,0,0),'y1':8})
    data.append({'x1': datetime.datetime(2015,1,1,13,0,0,0),'y1':12})
    data.append({'x1': datetime.datetime(2015,1,1,14,0,0,0),'y1':0})
    data.append({'x1': datetime.datetime(2015,1,1,15,0,0,0),'y1':0})
    data.append({'x1': datetime.datetime(2015,1,1,16,0,0,0),'y1':0})
    data.append({'x1': datetime.datetime(2015,1,1,17,0,0,0),'y1':0})
    data.append({'x1': datetime.datetime(2015,1,1,18,0,0,0),'y1':2})
    data.append({'x1': datetime.datetime(2015,1,1,19,0,0,0),'y1':6})
    data.append({'x1': datetime.datetime(2015,1,1,20,0,0,0),'y1':4})
    data.append({'x1': datetime.datetime(2015,1,1,21,0,0,0),'y1':22})
    data.append({'x1': datetime.datetime(2015,1,1,22,0,0,0),'y1':36})
    data.append({'x1': datetime.datetime(2015,1,1,23,0,0,0),'y1':32})
    data.append({'x1': datetime.datetime(2015,1,2,0,0,0,0),'y1':21})
    data.append({'x1': datetime.datetime(2015,1,2,1,0,0,0),'y1':15})
    data.append({'x1': datetime.datetime(2015,1,2,2,0,0,0),'y1':4})
    data.append({'x1': datetime.datetime(2015,1,2,3,0,0,0),'y1':0})
    data.append({'x1': datetime.datetime(2015,1,2,4,0,0,0),'y1':0})
    data.append({'x1': datetime.datetime(2015,1,2,5,0,0,0),'y1':0})
    data.append({'x1': datetime.datetime(2015,1,2,6,0,0,0),'y1':45})
    data.append({'x1': datetime.datetime(2015,1,2,7,0,0,0),'y1':47})
    data.append({'x1': datetime.datetime(2015,1,2,8,0,0,0),'y1':52})
    data.append({'x1': datetime.datetime(2015,1,2,9,0,0,0),'y1':44})
    data.append({'x1': datetime.datetime(2015,1,2,10,0,0,0),'y1':0})
    data.append({'x1': datetime.datetime(2015,1,2,11,0,0,0),'y1':0})
    data.append({'x1': datetime.datetime(2015,1,2,12,0,0,0),'y1':0})
    data.append({'x1': datetime.datetime(2015,1,2,13,0,0,0),'y1':0})

    script_bokeh, div_bokeh = plot_1_bar(data, 
                                         ['y1'],
                                         ['y legend label'],
                                         "",
                                         'x label',
                                         'y label',
                                         Range1d(0, 70),
                                         ['red'])

    return render(request, 
                  'tests/plot1.html', 
                  {'script_bokeh': script_bokeh, 
                   'div_bokeh': div_bokeh})
Run Code Online (Sandbox Code Playgroud)

plot1.html :

<!DOCTYPE html>
<html lang="en">
    <head>
        <title>bokeh bar plot</title>
        <link rel="stylesheet" type="text/css" href="/static/tests/css/bokeh-0.9.2.min.css" />
        <script src="/static/tests/js/bokeh-0.9.2.min.js" type="text/javascript"></script>
    </head>
    <body>
        <h1>Bokeh bar plot</h1>
        <div id="div_graph">{{div_bokeh|safe}}{{script_bokeh|safe}}</div>
    </body>
</html>
Run Code Online (Sandbox Code Playgroud)

x 轴放大

x 轴缩小

big*_*dot 1

首先,该bokeh.chartsAPI(包括Bar)已于 2017 年弃用并删除,不应再使用。稳定且受支持的bokeh.plottingAPI 现在可用于创建多种分类图和条形图,并且比bokeh.charts以往任何时候都更强大。请参阅用户指南的处理分类数据一章,了解许多带有完整代码的实例


没有内置的股票代码可以配置来执行此操作,而且CustomJSTicker现在也没有任何内置代码,因此,现在要做这样的事情,您将不得不求助于 自定义扩展。此外,您将需要CustomJS范围内的回调,以便根据您想要的策略配置自定义代码。这是一个完整的脚本,显示了一种可能的方法(此代码使用 Bokeh 进行了测试0.12.16):

from bokeh.core.properties import Int
from bokeh.models import  CategoricalTicker, CustomJS
from bokeh.io import show
from bokeh.plotting import figure

class MyTicker(CategoricalTicker):
    __implementation__ = """
    import {CategoricalTicker} from "models/tickers/categorical_ticker"
    import * as p from "core/properties"

    export class MyTicker extends CategoricalTicker
      type: "MyTicker"

      @define {
        nth: [ p.Int, 1 ]
      }

      get_ticks: (start, end, range, cross_loc) ->
        ticks = super(start, end, range, cross_loc)
        ticks.major = ticks.major.filter((element, index) => index % this.nth == 0)
        return ticks

    """

    nth = Int(default=1)

fruits = ['Apples', 'Pears', 'Nectarines', 'Plums', 'Grapes', 'Strawberries']

p = figure(x_range=fruits, plot_height=250, title="Fruit Counts",
           tools="xwheel_zoom")

p.vbar(x=fruits, top=[5, 3, 4, 2, 4, 6], width=0.9)

p.xgrid.grid_line_color = None
p.y_range.start = 0

p.xaxis.ticker = MyTicker(nth=1)

cb = CustomJS(args=dict(ticker=p.xaxis[0].ticker), code="""
    if (Math.abs(cb_obj.start-cb_obj.end) > 8) {
        ticker.nth = 2
    } else {
        ticker.nth = 1
    }
""")
p.x_range.js_on_change('start', cb)
p.x_range.js_on_change('end', cb)

show(p)
Run Code Online (Sandbox Code Playgroud)

在此输入图像描述