gpt4 book ai didi

Bokeh Colorbar 颜色条右侧的垂直标题?

转载 作者:行者123 更新时间:2023-12-04 23:14:33 25 4
gpt4 key购买 nike

我正在尝试做一些我通常认为微不足道但在 Bokeh 中似乎非常困难的事情:将垂直颜色条添加到绘图中,然后将颜色条的标题(也就是颜色映射背后的变量)显示在一侧颜色条,但从水平方向顺时针旋转 90 度。

根据我对 Bokeh ColorBar() 界面的了解(查看文档并为此元素使用 python 解释器的 help() 函数),这是不可能的。无奈之下,我添加了自己的基于 Label() 的注释。这可行,但很笨拙,并且在 Bokeh 服务情况下部署时会显示奇怪的行为 - 图上数据窗口的宽度与标题颜色栏的标题字符串的长度成反比变化。

下面我包含了 Bokeh 服务器 mpg 示例的修改版本。为它的复杂性道歉,但我觉得这是使用 Bokeh 附带的基础设施/数据来说明问题的最佳方式。对于那些不熟悉 bokeh serve 的人,这个代码片段需要保存到一个名为 main.py 的文件中,该文件位于一个目录中——为了参数,假设是 CrossFilter2——并且在 CrossFilter2 的父目录中需要调用命令

bokeh serve --show CrossFilter2

然后,这将显示在浏览器窗口(localhost:5006/CrossFilter2)中,如果您使用颜色选择小部件,您会明白我的意思,即短变量名称(例如“hp”或“mpg”)会产生更广泛的数据显示窗口而不是更长的变量名称,例如“加速”或“重量”。我怀疑标签元素的大小可能存在错误 - 它们的 x 和 y 尺寸被交换 - 并且 Bokeh 不了解标签元素已被旋转。

我的问题是:
  • 我真的必须去这种麻烦来获得一个简单的颜色条标签功能,我可以在 matplotlib/plotly 中几乎没有问题吗?
  • 如果我必须经历您可以在我的示例代码中看到的麻烦,是否有其他方法可以避免数据窗口宽度问题?
    import numpy as np
    import pandas as pd

    from bokeh.layouts import row, widgetbox
    from bokeh.models import Select
    from bokeh.models import HoverTool, ColorBar, LinearColorMapper, Label
    from bokeh.palettes import Spectral5
    from bokeh.plotting import curdoc, figure, ColumnDataSource
    from bokeh.sampledata.autompg import autompg_clean as df

    df = df.copy()

    SIZES = list(range(6, 22, 3))
    COLORS = Spectral5

    # data cleanup
    df.cyl = df.cyl.astype(str)
    df.yr = df.yr.astype(str)
    columns = sorted(df.columns)

    discrete = [x for x in columns if df[x].dtype == object]
    continuous = [x for x in columns if x not in discrete]
    quantileable = [x for x in continuous if len(df[x].unique()) > 20]

    def create_figure():
    xs = df[x.value].tolist()
    ys = df[y.value].tolist()
    x_title = x.value.title()
    y_title = y.value.title()
    name = df['name'].tolist()

    kw = dict()
    if x.value in discrete:
    kw['x_range'] = sorted(set(xs))
    if y.value in discrete:
    kw['y_range'] = sorted(set(ys))
    kw['title'] = "%s vs %s" % (y_title, x_title)

    p = figure(plot_height=600, plot_width=800,
    tools='pan,box_zoom,wheel_zoom,lasso_select,reset,save',
    toolbar_location='above', **kw)

    p.xaxis.axis_label = x_title
    p.yaxis.axis_label = y_title

    if x.value in discrete:
    p.xaxis.major_label_orientation = pd.np.pi / 4

    if size.value != 'None':
    groups = pd.qcut(df[size.value].values, len(SIZES))
    sz = [SIZES[xx] for xx in groups.codes]
    else:
    sz = [9] * len(xs)

    if color.value != 'None':
    coloring = df[color.value].tolist()
    cv_95 = np.percentile(np.asarray(coloring), 95)
    mapper = LinearColorMapper(palette=Spectral5,
    low=cv_min, high=cv_95)
    mapper.low_color = 'blue'
    mapper.high_color = 'red'
    add_color_bar = True
    ninety_degrees = pd.np.pi / 2.
    color_bar = ColorBar(color_mapper=mapper, title='',
    #title=color.value.title(),
    title_text_font_style='bold',
    title_text_font_size='20px',
    title_text_align='center',
    orientation='vertical',
    major_label_text_font_size='16px',
    major_label_text_font_style='bold',
    label_standoff=8,
    major_tick_line_color='black',
    major_tick_line_width=3,
    major_tick_in=12,
    location=(0,0))
    else:
    c = ['#31AADE'] * len(xs)
    add_color_bar = False

    if add_color_bar:
    source = ColumnDataSource(data=dict(x=xs, y=ys,
    c=coloring, size=sz, name=name))
    else:
    source = ColumnDataSource(data=dict(x=xs, y=ys, color=c,
    size=sz, name=name))

    if add_color_bar:
    p.circle('x', 'y', fill_color={'field': 'c',
    'transform': mapper},
    line_color=None, size='size', source=source)
    else:
    p.circle('x', 'y', color='color', size='size', source=source)

    p.add_tools(HoverTool(tooltips=[('x', '@x'), ('y', '@y'),
    ('desc', '@name')]))

    if add_color_bar:
    color_bar_label = Label(text=color.value.title(),
    angle=ninety_degrees,
    text_color='black',
    text_font_style='bold',
    text_font_size='20px',
    x=25, y=300,
    x_units='screen', y_units='screen')
    p.add_layout(color_bar, 'right')
    p.add_layout(color_bar_label, 'right')


    return p


    def update(attr, old, new):
    layout.children[1] = create_figure()


    x = Select(title='X-Axis', value='mpg', options=columns)
    x.on_change('value', update)

    y = Select(title='Y-Axis', value='hp', options=columns)
    y.on_change('value', update)

    size = Select(title='Size', value='None',
    options=['None'] + quantileable)
    size.on_change('value', update)

    color = Select(title='Color', value='None',
    options=['None'] + quantileable)
    color.on_change('value', update)

    controls = widgetbox([x, y, color, size], width=200)
    layout = row(controls, create_figure())

    curdoc().add_root(layout)
    curdoc().title = "Crossfilter"
  • 最佳答案

    您可以通过在单独的轴上绘制垂直标签并向该轴添加标题来向颜色栏添加垂直标签。为了说明这一点,这里是 Bokeh 标准 Colorbar 示例的修改版本(找到 here):

    import numpy as np

    from bokeh.plotting import figure, output_file, show
    from bokeh.models import LogColorMapper, LogTicker, ColorBar
    from bokeh.layouts import row

    plot_height = 500
    plot_width = 500
    color_bar_height = plot_height + 11
    color_bar_width = 180

    output_file('color_bar.html')

    def normal2d(X, Y, sigx=1.0, sigy=1.0, mux=0.0, muy=0.0):
    z = (X-mux)**2 / sigx**2 + (Y-muy)**2 / sigy**2
    return np.exp(-z/2) / (2 * np.pi * sigx * sigy)

    X, Y = np.mgrid[-3:3:100j, -2:2:100j]
    Z = normal2d(X, Y, 0.1, 0.2, 1.0, 1.0) + 0.1*normal2d(X, Y, 1.0, 1.0)
    image = Z * 1e6

    color_mapper = LogColorMapper(palette="Viridis256", low=1, high=1e7)

    plot = figure(x_range=(0,1), y_range=(0,1), toolbar_location=None,
    width=plot_width, height=plot_height)
    plot.image(image=[image], color_mapper=color_mapper,
    dh=[1.0], dw=[1.0], x=[0], y=[0])

    现在,要制作颜色条,请创建一个单独的虚拟图,将颜色条添加到虚拟图并将其放在主图旁边。添加颜色条标签作为虚拟图的标题并将其适当居中。
    color_bar = ColorBar(color_mapper=color_mapper, ticker=LogTicker(),
    label_standoff=12, border_line_color=None, location=(0,0))

    color_bar_plot = figure(title="My color bar title", title_location="right",
    height=color_bar_height, width=color_bar_width,
    toolbar_location=None, min_border=0,
    outline_line_color=None)

    color_bar_plot.add_layout(color_bar, 'right')
    color_bar_plot.title.align="center"
    color_bar_plot.title.text_font_size = '12pt'

    layout = row(plot, color_bar_plot)

    show(layout)

    这给出了以下输出图像:

    enter image description here

    需要注意的一件事是 color_bar_width 设置得足够宽,可以同时包含 Colorbar、它的轴标签和 Colorbar 标签。如果宽度设置得太小,你会得到一个错误并且绘图不会渲染。

    关于Bokeh Colorbar 颜色条右侧的垂直标题?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/46841919/

    25 4 0
    Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
    广告合作:1813099741@qq.com 6ren.com