Circular bar plots, also known as radial bar charts or circular histograms, are a visually appealing way to display data. In this article, we’ll explore how to create circular bar plots using the Seaborn library in Python.
What are circular bar plots?
In contrast to conventional bar charts, which display the bars horizontally or vertically, circular bar plots, sometimes called radial bar charts or circular histograms, display the bars radially around a circle. Every bar in the plot denotes a category, and the value of each category is represented by the bar’s length. The figure exhibits radial symmetry due to the bars’ uniform spacing around the circle.
Benefits of Circular Bar Plots:
- Cyclic Data Visualization: Hourly patterns, monthly trends, or directional data are examples of cyclic or periodic data that work well when displayed using circular bar charts.
- Space Efficiency: They utilize space well, particularly when handling a large number of categories.
Steps to Build a Circular Bar Plot Using Seaborn
Importing Necessary Libraries
import matplotlib.pyplot as plt
import seaborn as sns
import numpy as np
import pandas as pd
|
Creating Sample Data
categories = [ 'A' , 'B' , 'C' , 'D' , 'E' ]
values = [ 20 , 35 , 30 , 25 , 40 ]
# Create a DataFrame from the data data = pd.DataFrame({ 'categories' : categories, 'values' : values})
|
Plotting Circular bar Plot
-
Convert Values to Radians: The
np.deg2rad
function is used to convert the values in the ‘values’ column of the DataFrame to radians. This is necessary because the radial axis in the circular bar plot represents angles, and values need to be converted to radians to correctly position the bars around the circle. -
Create a Figure and Axis: The
plt.subplots
function is used to create a figure (fig
) and a set of subplots (ax
) with a polar projection (subplot_kw=dict(polar=True)
). This means that the plot will be circular, with the radial axis representing angles. -
Plot the Bars: The
sns.barplot
function is used to plot the bars on the circular plot. The ‘categories’ column is used as the x-axis variable (x='categories'
), the ‘angle’ column (converted to radians) is used as the y-axis variable (y='angle'
), and the ‘categories’ column is also assigned to thehue
parameter to color the bars differently for each category. Thepalette='viridis'
argument specifies the color palette to use. -
Set the Radial Axis Label: The
ax.set_rticks([])
function is used to remove the radial axis labels. Since the radial axis represents angles and not numerical values, the labels are unnecessary in this context.
# Convert values to radians data[ 'angle' ] = np.deg2rad(data[ 'values' ])
# Create a figure and axis fig, ax = plt.subplots(figsize = ( 6 , 6 ), subplot_kw = dict (polar = True ))
# Plot the bars sns.barplot(x = 'categories' , y = 'angle' , hue = 'categories' ,
data = data, ax = ax, palette = 'viridis' , legend = False )
# Set the radial axis label ax.set_rticks([]) # Display the plot plt.show() |
Output:
Adding Labels, Titles
- Labeling Categories on the Plot: We can add text labels to each bar to indicate the category it represents and the value it corresponds to.
- Adding a Title to the Plot: We can add a descriptive title to the plot to provide context and make it easier for viewers to understand the purpose of the visualization.
The ax.set_title('Circular Bar Plot', pad=20)
function is used to add a title to the plot, with a padding of 20 units to adjust the distance between the title and the plot.
# Convert values to radians data[ 'angle' ] = np.deg2rad(data[ 'values' ])
# Create a figure and axis fig, ax = plt.subplots(figsize = ( 6 , 6 ), subplot_kw = dict (polar = True ))
# Plot the bars bars = sns.barplot(x = 'categories' , y = 'angle' , hue = 'categories' , data = data,
ax = ax, palette = 'viridis' , edgecolor = 'none' , alpha = 0.8 , linewidth = 0 )
# Set the radial axis label ax.set_rticks([]) # Add text labels to the bars for bar, value in zip (bars.patches, data[ 'values' ]):
ax.text(bar.get_x() + bar.get_width() / 2 ,
bar.get_height() + 0.1 ,
str (value),
ha = 'center' , va = 'bottom' , color = 'black' , fontsize = 10 )
# Add category labels ax.set_xticks(np.linspace( 0 , 2 * np.pi, len (categories), endpoint = False ))
ax.set_xticklabels(categories) # Add a title plt.title( 'Circular Bar Plot' , pad = 20 )
# Display the plot plt.show() |
Output:
Reordering Circular Bar Plot
To reorder the categories in the circular bar plot, we can customize the order of categories in the DataFrame before plotting.
# Create a DataFrame from the data data = pd.DataFrame({ 'categories' : categories, 'values' : values})
# Define the desired order of categories custom_order = [ 'B' , 'C' , 'A' , 'E' , 'D' ]
# Reorder the DataFrame based on the custom order data[ 'categories' ] = pd.Categorical(data[ 'categories' ],
categories = custom_order, ordered = True )
data = data.sort_values( 'categories' )
# Convert values to radians data[ 'angle' ] = np.deg2rad(data[ 'values' ])
# Create a figure and axis fig, ax = plt.subplots(figsize = ( 6 , 6 ), subplot_kw = dict (polar = True ))
# Plot the bars bars = sns.barplot(x = 'categories' , y = 'angle' , hue = 'categories' ,
data = data, ax = ax, palette = 'viridis' )
# Set the radial axis label ax.set_rticks([]) # Add text labels to the bars for bar, value in zip (bars.patches, data[ 'values' ]):
ax.text(bar.get_x() + bar.get_width() / 2 ,
bar.get_height() + 0.1 ,
str (value),
ha = 'center' , va = 'bottom' )
# Add category labels ax.set_xticks(np.linspace( 0 , 2 * np.pi, len (custom_order),
endpoint = False ))
ax.set_xticklabels(custom_order) # Add a title ax.set_title( 'Circular Bar Plot' , pad = 20 )
# Add legend handles, labels = ax.get_legend_handles_labels()
ax.legend(handles, labels, title = 'Categories' , loc = 'upper right' ,
bbox_to_anchor = ( 1.3 , 1 ))
# Display the plot plt.show() |
Output:
Circular Bar Plot for grouped data
To create a grouped circular bar plot, we can use the hue
parameter in the sns.barplot()
function to differentiate between different groups of bars.
# Sample data categories = [ 'A' , 'B' , 'C' , 'D' , 'E' ]
values1 = [ 20 , 35 , 30 , 25 , 40 ]
values2 = [ 15 , 25 , 20 , 30 , 35 ]
groups = [ 'Group 1' , 'Group 2' , 'Group 1' , 'Group 2' , 'Group 1' ]
# Create a DataFrame from the data data = pd.DataFrame({ 'categories' : categories, 'values1' : values1,
'values2' : values2, 'groups' : groups})
# Convert values to radians data[ 'angle1' ] = np.deg2rad(data[ 'values1' ])
data[ 'angle2' ] = np.deg2rad(data[ 'values2' ])
# Create a figure and axis fig, ax = plt.subplots(figsize = ( 8 , 8 ), subplot_kw = dict (polar = True ))
# Plot the first group of bars sns.barplot(x = 'categories' , y = 'angle1' , hue = 'groups' , data = data,
ax = ax, palette = 'Set1' )
# Plot the second group of bars, offsetting them slightly to avoid overlap sns.barplot(x = 'categories' , y = 'angle2' , hue = 'groups' , data = data, ax = ax,
palette = 'Set2' , alpha = 0.7 )
# Set the radial axis label ax.set_rticks([]) # Add a title ax.set_title( 'Grouped Circular Bar Plot' , pad = 20 )
# Add legend handles, labels = ax.get_legend_handles_labels()
ax.legend(handles, labels, title = 'Groups' , loc = 'upper right' , bbox_to_anchor = ( 1.3 , 1 ))
# Display the plot plt.show() |
Output: