使用Bokeh区域图绘制分类轴

4

问题

目前是否可以在bokeh Area 图表中使用分类轴?

细节

我正在尝试使用高级的bokeh.charts API,绘制一个具有分类x轴的面积图。

示例

如果设置了bokeh和如下数据框:

import numpy
import pandas
from bokeh import charts, plotting, models
plotting.output_notebook()

_, blue, _, green = bokeh.palettes.Paired4

datalist = [
    {'month': 'Oct', 'rain': 107., 'snow': 0.0, 'wy_month': 0},
    {'month': 'Nov', 'rain': 23.6, 'snow': 0.8, 'wy_month': 1},
    {'month': 'Dec', 'rain': 31.9, 'snow': 30.5, 'wy_month': 2},
    {'month': 'Jan', 'rain': 44.6, 'snow': 31.1, 'wy_month': 3},
    {'month': 'Feb', 'rain': 49.6, 'snow': 31.7, 'wy_month': 4},
    {'month': 'Mar', 'rain': 13.6, 'snow': 4.2, 'wy_month': 5},
    {'month': 'Apr', 'rain': 107.2, 'snow': 1.6, 'wy_month': 6},
    {'month': 'May', 'rain': 77.0, 'snow': 0.0, 'wy_month': 7},
    {'month': 'Jun', 'rain': 108., 'snow': 0.0, 'wy_month': 8},
    {'month': 'Jul', 'rain': 216., 'snow': 0.0, 'wy_month': 9},
    {'month': 'Aug', 'rain': 76.8, 'snow': 0.0, 'wy_month': 10},
    {'month': 'Sep', 'rain': 76.4, 'snow': 0.0, 'wy_month': 11},
]

data = pandas.DataFrame(datalist)

我可以做到:
bar = charts.Bar(data=data, values='rain', label='month',
               color=[blue], width=600, height=300)
plotting.show(bar)

scatter = charts.Scatter(data=data, x='month', y='rain',
                         color=[blue], width=600, height=300)
plotting.show(scatter)

我得到的结果是:

bars

scatter

我的尝试

但如果我使用面积图表进行相同操作:

area = charts.Area(data=data, y='rain', x='month', stack=True,
                   color=blue, width=600, height=300)
plotting.show(area)

我得到:

enter image description here

其他尝试

删除对x的明确定义可以显示出区域,但是有一个数值轴(0-12)。

area = charts.Area(data=data, y='rain', stack=True,
                   color=blue, width=600, height=300)

指定一个列表或bokeh.models.ranges.FactorRange作为x_range似乎没有任何影响(无论是否使用x='month')。

1个回答

2

一种选择是为您的轴制作自定义刻度标签。从这里的答案进行修改-如何在Bokeh中使用自定义标签进行刻度?

首先,我们导入必要的内容并创建一个字典来存储我们修改后的标签(使用Jupyter笔记本):

import numpy
import pandas
from bokeh import charts, plotting, models
import bokeh
from bokeh.models.formatters import TickFormatter, String, List, Dict, Int
from bokeh.models import FixedTicker
plotting.output_notebook()

_, blue, _, green = ['#a6cee3', '#1f78b4', '#b2df8a', '#33a02c']

datalist = [
    {'month': 'Oct', 'rain': 107., 'snow': 0.0, 'wy_month': 0},
    {'month': 'Nov', 'rain': 23.6, 'snow': 0.8, 'wy_month': 1},
    {'month': 'Dec', 'rain': 31.9, 'snow': 30.5, 'wy_month': 2},
    {'month': 'Jan', 'rain': 44.6, 'snow': 31.1, 'wy_month': 3},
    {'month': 'Feb', 'rain': 49.6, 'snow': 31.7, 'wy_month': 4},
    {'month': 'Mar', 'rain': 13.6, 'snow': 4.2, 'wy_month': 5},
    {'month': 'Apr', 'rain': 107.2, 'snow': 1.6, 'wy_month': 6},
    {'month': 'May', 'rain': 77.0, 'snow': 0.0, 'wy_month': 7},
    {'month': 'Jun', 'rain': 108., 'snow': 0.0, 'wy_month': 8},
    {'month': 'Jul', 'rain': 216., 'snow': 0.0, 'wy_month': 9},
    {'month': 'Aug', 'rain': 76.8, 'snow': 0.0, 'wy_month': 10},
    {'month': 'Sep', 'rain': 76.4, 'snow': 0.0, 'wy_month': 11},

]

data = pandas.DataFrame(datalist)
label_data = {x['wy_month']:x['month'] for x in datalist}

现在我们定义我们的自定义标签类(以及相关的JS代码):
JS_CODE =  """
        _ = require "underscore"
        Model = require "model"
        p = require "core/properties"
        class FixedTickFormatter extends Model
          type: 'FixedTickFormatter'
          doFormat: (ticks) ->
            labels = @get("labels")
            return (labels[tick] ? "" for tick in ticks)
          @define {
            labels: [ p.Any ]
          }
        module.exports =
          Model: FixedTickFormatter
    """

class FixedTickFormatter(TickFormatter):

    labels = Dict(Int, String, help="""
    A mapping of integer ticks values to their labels.
    """)

    __implementation__ = JS_CODE

并使用修改后的轴绘制图表:

area = charts.Area(data=data, y='rain', x='wy_month', stack=True,
                   color=blue, width=600, height=300)
area.xaxis[0].formatter = FixedTickFormatter(labels=label_data)
area.xaxis[0].ticker = FixedTicker(ticks=sorted(label_data.keys()))
plotting.show(area)

这是我得到的最终图表: Bokeh area plot

谢谢回答。看起来这样会有用,但我会再把问题保持一段时间。此外,你对如何让散点图上显示所有月份有何想法? - Paul H
没问题。我会更新我的答案,包括一个自定义的刻度尺,这样你可以看到所有的月份(没有月份之间的中间刻度)。 - Andrew Guy

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接