# How to Add Custom Markers to a Scatter Plot Using Bokeh ?

Published: August 12, 2024

Updated: August 12, 2024

Tags: Bokeh; ;

## Introduction

Bokeh is a powerful data visualization library in Python that provides interactive and versatile plotting capabilities. One of its strengths is the ability to customize visual elements, such as scatter markers, to enhance the clarity and aesthetics of your data presentation. In this article, we will explore how to add custom scatter markers using Bokeh, enabling you to create more distinctive and informative plots.

## Create basic scatter plot using Bokeh

Let's start by importing the necessary libraries and setting up a basic Bokeh plot:

 ``` 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21``` ```from bokeh.plotting import figure, show # Import figure and show functions from Bokeh for creating and displaying plots from bokeh.models import Range1d # Import Range1d to manually set the range of the plot's axes import numpy as np # Import NumPy for numerical operations, particularly for generating random data np.random.seed(42) # Set a seed for NumPy's random number generator to ensure reproducible results # Generate some random data x = np.random.random(15) * 100 # Generate 15 random x values between 0 and 100 y = np.random.random(15) * 100 # Generate 15 random y values between 0 and 100 # Create a basic scatter plot p = figure(title="Custom Scatter Markers with Bokeh", x_axis_label='X', y_axis_label='Y') # Initialize a figure with title and axis labels p.scatter(x, y, size=10) # Add a scatter plot to the figure with markers of size 10 # Set the x and y axis ranges manually to [0, 100] p.x_range = Range1d(0, 100) # Set the range of the x-axis to be from 0 to 100 p.y_range = Range1d(0, 100) # Set the range of the y-axis to be from 0 to 100 # Display the plot show(p) # Render and display the plot in the notebook or browser ```

At this point, you have a simple scatter plot with default circle markers.

## Adding Custom Markers

Bokeh offers several built-in marker types, such as circle, square, triangle, and more. However, you can also use custom markers to represent your data points. Here’s how you can do it:

### Using Built-In Marker Types

You can specify different marker types using the marker argument in the scatter() method:

 ``` 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22``` ```from bokeh.plotting import figure, show # Import figure and show functions from Bokeh for creating and displaying plots from bokeh.models import Range1d # Import Range1d to manually set the range of the plot's axes import numpy as np # Import NumPy for numerical operations, particularly for generating random data np.random.seed(42) # Set a seed for NumPy's random number generator to ensure reproducible results # Generate random data x = np.random.random(15) * 100 # Generate 15 random x values between 0 and 100 y = np.random.random(15) * 100 # Generate 15 random y values between 0 and 100 # Create a basic scatter plot p = figure(title="Custom Scatter Markers with Bokeh", x_axis_label='X', y_axis_label='Y') # Initialize a figure with title and axis labels # Add a scatter plot with square markers, custom color, size, and transparency p.scatter(x, y, marker="square", size=12, color="coral", alpha=0.6) # Set the x and y axis ranges manually to [0, 100] p.x_range = Range1d(0, 100) # Set the range of the x-axis to be from 0 to 100 p.y_range = Range1d(0, 100) # Set the range of the y-axis to be from 0 to 100 # Display the plot show(p) # Render and display the plot in the notebook or browser ```

Bokeh offers a variety of marker types that you can use to represent data points in a scatter plot. These marker types can be specified using the marker argument in the scatter() method. Here's an overview of the different marker types available in Bokeh:

Built-In Marker Types:

• Circle ("circle"): A simple circular marker.
• Square ("square"): A square-shaped marker.
• Triangle ("triangle"): An equilateral triangle with the point facing upwards.
• Diamond ("diamond"): A diamond-shaped marker.
• Inverted Triangle ("inverted_triangle"): An equilateral triangle with the point facing downwards.
• Cross ("cross"): A cross-shaped marker.
• X ("x"): An X-shaped marker.
• Circle Cross ("circle_cross"): A circular marker with a cross inside it.
• Square Cross ("square_cross"): A square-shaped marker with a cross inside it.
• Diamond Cross ("diamond_cross"): A diamond-shaped marker with a cross inside it.
• Circle X ("circle_x"): A circular marker with an X inside it.
• Square X ("square_x"): A square-shaped marker with an X inside it.
• Asterisk ("asterisk"): A star-shaped marker with multiple intersecting lines.
• Plus ("plus"): A plus sign-shaped marker.
• Hex ("hex"): A hexagon-shaped marker.

When customizing a scatter plot in Bokeh, you can use several options to control the appearance of the markers:

• size=12: This option sets the size of the markers. In this case, the markers are sized at 12 units, which controls how large each marker appears on the plot.
• color="coral": This option determines the color of the markers. Here, the markers are set to a coral color, giving them a warm, reddish-orange hue.
• alpha=0.6: The alpha option adjusts the transparency of the markers. A value of 0.6 means that the markers are semi-transparent, allowing for overlapping markers to be slightly visible through one another. An alpha value of 1 would make the markers fully opaque, while a value of 0 would make them fully transparent.

These options allow you to tailor the visual impact of your scatter plot, making it easier to distinguish different data points or to achieve a specific aesthetic.

### Using External Image as Custom Marker:

In Bokeh, you can use an external image as a marker in your scatter plot, which is especially useful for adding custom icons or visuals to represent data points in a unique way. However, it's important to note that Bokeh currently does not support using local images directly as markers; you must use an image that is hosted online.

For example, in a research project focused on mapping gas flare locations, I wanted to represent each flare with a custom icon rather than the standard marker shapes like circles or squares. By using an external image URL, I was able to incorporate a specific icon that visually communicated the presence of a gas flare at each location on the map. This approach not only made the plot more informative but also more visually engaging, helping to convey the research findings effectively.

 ``` 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33``` ```from bokeh.plotting import figure, show # Import figure and show functions from Bokeh for creating and displaying plots from bokeh.models import Range1d # Import Range1d to manually set the range of the plot's axes from bokeh.core.properties import value # Import value to handle string values in Bokeh properties import numpy as np # Import NumPy for numerical operations, particularly for generating random data # URL of the custom marker image url = "https://cdn4.iconfinder.com/data/icons/industrial-vol-2/72/71-512.png" np.random.seed(42) # Set a seed for NumPy's random number generator to ensure reproducible results # Generate random data for the plot x = np.random.random(15) * 100 # Generate 15 random x values between 0 and 100 y = np.random.random(15) * 100 # Generate 15 random y values between 0 and 100 # Create a scatter plot figure with customized properties p = figure(title="Custom Scatter Markers with Bokeh", # Set the plot title match_aspect=True, # Maintain aspect ratio between x and y axes x_axis_label='X', # Label for the x-axis y_axis_label='Y', # Label for the y-axis background_fill_color="#efefef") # Set background color of the plot # Add custom image markers to the plot # 'value(url)' is used to ensure the string URL is treated as a fixed value, not as a column name from the data source p.image_url(url=value(url), x=x, y=y, alpha=0.7, anchor="center", # Place image markers at x, y coordinates w=18, w_units="screen", h=18, h_units="screen") # Set width and height of markers in screen units # Set the x and y axis ranges manually to [0, 100] p.x_range = Range1d(0, 100) # Define the range of the x-axis from 0 to 100 p.y_range = Range1d(0, 100) # Define the range of the y-axis from 0 to 100 # Display the plot show(p) # Render and display the plot in the notebook or browser ```