A circular bar chart may be useful when plotting cyclic dataseries resulting from the combination of a measurement variable and a time-related categorical variable (hours, months, decades). It usually helps highlighting a cyclic pattern, a repetition (or absence of repetition) in time. In principle, a circular bar chart is a regular line chart which is projected into a polar coordinate system.

Before going any further, if you are not so familiar with (clustered) bar plots, or polar coordinate systems, have a quick look at these pages:

Here we will plot the average temperature (response variable) recorded monthly (predictor variable 1) at Lygra, Hordaland, in 2016, 2017 and 2018 (predictor variable 2).

The dataframe for this tutorial is as follows:

# dataframe
df <- data.frame(year, month, temperature)
# structure of the dataframe
str(df)
## 'data.frame':    36 obs. of  3 variables:
##  $ year       : Factor w/ 3 levels "2016","2017",..: 1 1 1 1 1 1 1 1 1 1 ...
##  $ month      : Factor w/ 12 levels "Jan","Feb","Mar",..: 1 2 3 4 5 6 7 8 9 10 ...
##  $ temperature: num  0.6 1.8 4.3 5.6 11.5 14.7 14.1 13.6 14.9 8.4 ...



Using the coding strategy presented here, we can start by building a grouped/clustered bar plot. The function to use for drawing the bars is geom_col(). We must map the variables with the function aes() which will look more or less like this: aes(month, temperature, year). Our plan is thus to:

The code for the plot is as follows:

ggplot(df, aes(x = month, y = temperature, fill = year)) +
  geom_col(position = "dodge")



Then, to transform this regular bar plot into a circular line plot, we project it into a polar coordinate system with coord_polar():

ggplot(df, aes(x = month, y = temperature, fill = year)) +
  geom_col(position = "dodge") +
  coord_polar()



Now we need to rescale the Y-axis to make the plot more readable. And placing a hole at the center of the chart is part of this rescaling process. To rescale the Y-axis, we use ylim(a,b) where a is the value of the Y-axis corresponding to the center of the circle, and b the value of the Y-axis that corresponds to the outer border of the circular plot. The maximum of the data set is 16.2, so we choose 17 for b. As for a, we can choose for example the negative value of b:

ggplot(df, aes(x = month, y = temperature, fill = year)) +
  geom_col(position = "dodge") +
  coord_polar() + 
  ylim(-17, 17)



Finally we may improve the global look of the plot by applying a nicer palette of colors such as viridis:

ggplot(df, aes(x = month, y = temperature, fill = year)) +
  geom_col(position = "dodge") +
  coord_polar() + 
  ylim(-17, 17) + 
  scale_fill_viridis_d()



Adding plot title, axis titles, ticks, labels and other essential elements

In this section, you will learn how to set/modify all the necessary elements that make a plot complete and comprehensible. Such elements are: