问题
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