Insert a newline character into a categorical axis factor label in BokehJS

|▌冷眼眸甩不掉的悲伤 提交于 2019-12-13 16:50:42

问题


I have a BokehJS plot with a categorical x-axis with factors that have strings that are very long. The label is being cut off by the edge of the graph and I would like to be able to insert a newline character either manually or automatically to produce a short length string (since it is now taller but narrower with a new line in the middle). I have tried the following code but it does not seem to create a change in the appearance.

p.x_range.attributes['factors'][0] = 'Some very long text string\nthat has now been cut'

回答1:


Until Bokeh adds either CSS rendering for xaxis ticks or add support for new line characters. Here's a workaround that can do what you are asking for, but it isn't perfect.

Instead of using a factor range, we can plot the data like normal using a placeholder x value. Then, we can place Labels under the y_axis at those placeholder positions which can then be rendered by css which will correctly print the newline.


Here's a working example using the Bokeh server.

main.py

from bokeh.plotting import ColumnDataSource, figure
from bokeh.models import LabelSet, FixedTicker
from bokeh.io import curdoc, show


factors = ["Some very long text string\nthat has now been cut\na",
           "Some very long text string\nthat has now been cut\nb"]
y = [50, 40]

# arbitrary placeholders which depends on the length and number of strings
x = [0, 2]
x_label = [0.65, 2.65]  # This is offset is based on the length of the string
y_label = [-2, -2]  # offset under the plot

source = ColumnDataSource(
    data=dict(factors=factors, x=x, y=y, x_label=x_label, y_label=y_label))

p = figure(x_range=(-1, 3), y_range=(0, 52))

p.circle(x='x', y='y', size=15, fill_color="orange", source=source)
p.xaxis.ticker = FixedTicker(ticks=x)

p.xaxis.major_label_text_font_size = '0pt'  # turn off x-axis tick labels
# p.xaxis.major_tick_line_color = None  # turn off x-axis major ticks
p.xaxis.minor_tick_line_color = None  # turn off x-axis minor ticks

labels = LabelSet(x='x_label', y='y_label', text='factors', source=source,
                  level='overlay', render_mode='css', text_align='center')

p.add_layout(labels)

curdoc().add_root(p)

styles.css

.bk-annotation-child {
    white-space: pre-wrap;
    text-align: center;
}

The main disadvantage of this method is that the x_labels must be manually offset on the x axis from our placeholder x values. This is because the built-in bokeh centering called from the LabelSet is calculated on the full length string and not the not the longest sub string between \n. I'm sure you could tinker with this answer and programmatically determine the correct offset for an arbitrary string instead of eyeballing it as I did.



来源:https://stackoverflow.com/questions/44955652/insert-a-newline-character-into-a-categorical-axis-factor-label-in-bokehjs

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!