Bokeh交互问题:点击第一幅图圆点在第二幅图显示对应文本
Hey there! Let's dig into why your Bokeh app isn't showing up and fix the click-to-display-text feature you want. When modifying Bokeh examples, the most common issues usually relate to missing layout setup, incorrect callback wiring, or not properly running the app. Let's break this down step by step.
1. Missing Proper Layout Configuration
If you're using multiple plots, you need to combine them into a single layout (like row() or column()) and pass that to curdoc().add_root(). Without this, Bokeh doesn't know what elements to render.
2. Incorrect Callback Setup
When linking clicks between plots, you need to use TapTool on the first plot, then connect its selection event to update the second plot's text. Make sure you're referencing the right glyph renderer and updating the text data source correctly.
3. Not Running the App Correctly
Interactive Bokeh apps with callbacks require the Bokeh server. You can't just run the script like a regular Python file—you need to use bokeh serve --show your_script.py to launch it properly.
Here's a tested implementation that does exactly what you want:
from bokeh.models import ColumnDataSource, TapTool, Text from bokeh.plotting import figure, curdoc from bokeh.layouts import row # Data for first plot: circles with coordinates and matching text circle_data = ColumnDataSource(data={ 'x': [1, 2, 3], 'y': [2, 3, 1], 'text': ['first', 'second', 'third'] }) # Data for second plot: initial placeholder text text_data = ColumnDataSource(data={'x': [0], 'y': [0], 'content': ['Click a circle!']}) # Create first plot with interactive circles p1 = figure(title="Click a Circle", tools="tap", width=400, height=400) circles = p1.circle(x='x', y='y', size=20, source=circle_data, color='blue') # Create second plot for text display p2 = figure(title="Display Text", width=400, height=400, x_range=(-1, 4), y_range=(-1, 4)) text_renderer = p2.text(x='x', y='y', text='content', source=text_data, text_font_size='20pt') # Callback to update text when a circle is clicked def update_text(attr, old, new): # Grab the index of the selected circle selected_idx = new.indices[0] # Update the text data with the matching content and position text_data.data = { 'x': [circle_data.data['x'][selected_idx]], 'y': [circle_data.data['y'][selected_idx]], 'content': [circle_data.data['text'][selected_idx]] } # Link the tap selection event to our callback circle_data.selected.on_change('indices', update_text) # Combine plots into a layout and add to the Bokeh document curdoc().add_root(row(p1, p2))
To run this, save it as
circle_click.pyand execute this command in your terminal:bokeh serve --show circle_click.py
Key Notes on This Implementation
- We use
ColumnDataSourcefor both plots—this is Bokeh's way of enabling dynamic data updates and sharing between elements. - The
TapToolis enabled on the first plot, and we listen for changes in theselected.indicesproperty of the circle data source. - The callback updates the text data source with the corresponding text, and positions it at the clicked circle's coordinates for clarity.
- Combining the two plots into a
rowlayout and adding it tocurdoc()is critical—this tells Bokeh exactly what to render.
内容的提问来源于stack exchange,提问作者hungry4code

