Bokeh is a popular Python library for creating interactive visualizations and plots. One of the powerful features of Bokeh is the ability to create draggable and droppable elements within a graph. In this blog post, we will explore how to implement this feature in your Bokeh graphs.
Setting up the Environment
To begin, make sure you have Bokeh installed in your Python environment. You can install it using pip:
pip install bokeh
Creating the Graph
Let’s start by creating a simple scatter plot using Bokeh. We will use the built-in figure
function to create a blank canvas, and then add a scatter glyph to display our data points.
from bokeh.plotting import figure, show
from bokeh.models import ColumnDataSource
# Create a blank canvas
p = figure()
# Add scatter glyphs
x = [1, 2, 3, 4, 5]
y = [5, 4, 3, 2, 1]
source = ColumnDataSource(data=dict(x=x, y=y))
p.circle('x', 'y', source=source, size=10)
# Show the graph
show(p)
This will create a basic scatter plot with data points. However, currently, there is no interaction available.
Implementing Drag and Drop
To enable dragging and dropping within our graph, we will utilize the Drag
and Drop
tools provided by Bokeh. These tools allow us to define callbacks that are triggered when a draggable element is dropped onto a droppable element.
from bokeh.models import CustomJS, TapTool, Drag, Drop
# Create a callback for the drop event
drop_callback = CustomJS(args=dict(source=source), code="""
const data = source.data;
const index = cb_data.index;
const droppedData = cb_data.data_transfer.data;
const droppedX = parseFloat(droppedData.get('x'));
const droppedY = parseFloat(droppedData.get('y'));
// Update the dropped data point
data.x[index] = droppedX;
data.y[index] = droppedY;
// Trigger an update in the graph
source.change.emit();
""")
# Add the drop tool to the graph
drop_tool = Drop(callback=drop_callback)
p.add_tools(drop_tool)
# Create a callback for the drag event
drag_callback = CustomJS(args=dict(source=source), code="""
const data = source.data;
const index = cb_data.index;
// Get the dragged data point
const draggedX = data.x[index];
const draggedY = data.y[index];
// Set the dragged data as text in the data transfer object
const dt = cb_data.data_transfer;
dt.setData('x', draggedX.toString());
dt.setData('y', draggedY.toString());
""")
# Add the drag tools to the graph
drag_tool = Drag(callback=drag_callback)
p.add_tools(drag_tool)
# Show the graph
show(p)
In this code, we define a drop_callback
function that is triggered when a data point is dropped onto our graph. This callback updates the dropped data point’s coordinates and triggers an update in the graph.
We also define a drag_callback
function that is triggered when a data point is being dragged. This callback sets the dragged data point as text in the data transfer object.
Finally, we create instances of the Drop
and Drag
tools and add them to our graph using the add_tools
method.
Conclusion
Implementing draggable and droppable elements within a Bokeh graph is a great way to enhance interactivity and user experience. By utilizing the Drag
and Drop
tools, you can enable your users to manipulate data points directly within the graph, making it easier to explore and analyze data.
Remember to explore the Bokeh documentation for more advanced features and examples. Happy coding!