The Grammar of Graphics and Radar Charts

[This article was first published on R-Chart, and kindly contributed to R-bloggers]. (You can report issue about the content on this page here)
Want to share your content on R-bloggers? click here if you have a blog, or here if you don't.

A radar chart (also known as a web chart, spider chart, or star chart) is described on Wikipedia as ‘a two-dimensional chart of three or more quantitative variables represented on axes starting from the same point.’  

Although this is an accurate description, it does not express the design and structure of a chart in a way that relates it to other types of charts.  The grammar of graphics embodied by ggplot2 provides not only a way of representing such a chart, but also utilizes a syntax that can help one compare it to other types of charts.  A radar chart might be described using ggplot2 terminology as being a line chart with a completed path plotted using a polar rather than a cartesian coordinate system.

The components of this definition map to ggplot functions:

  • The phrase “a line chart” suggests the geom_line() function.  We can do our first exploratory plots using a line chart and modify the results incrementally.
  • The phrase “with a completed path” indicates that a line is not sufficient.  We need to ensure the beginning and end meet.  The geom_polygon() function can be used to generate the outline of a polygon to accomplish this.
  • The final requirement is that the chart be “plotted using a polar rather than a cartesian coordinate system”.  The coord_polar() function accomplishes this transformation.  

Throughout this post, the equals assignment operator will be used instead of “less-than-dash” because blogger mangles this character sequence.  I prefer the latter stylistically.  The code in this post is available in a script at GitHub as well.  Start by importing the following packages.


Dplyr and reshape are used to structure and filter the dataset.  The scales package is used to normalize data values for convenient comparison.  The tibble package can be imported to provide convenient viewing and utility functions when working through dplyr pipelines, and ggplot2 is used to create the charts.

Create a data frame based on the mtcarts dataset. The rownames_to_column function from the tibble package is used to create a new column named “cart” based on the rownames.  The rescale function from the scales package transforms all numeric variables in the dataset so that they have comparable values (between 0 and 1).  The melt function from the reshape package creates name and value columns and populates them with the names and values that previously were independent columns.  The data set is now “longer” and not tidy, but the format is useful for the plots created later.  The data set is then ordered by the name of the car.

df = mtcars %>%
 rownames_to_column( var = “car” ) %>% 
 mutate_each(funs(rescale), -car) %>% 
 melt(id.vars=c(‘car’), measure.vars=colnames(mtcars)) %>% 

A radar chart is really just a line plot altered to be charted in an alternative coordinate system. 

line_plot = df %>%
 filter(variable==’mpg’) %>%
 ggplot(aes(x=car, y=value, group=1)) + 
 geom_line(color = ‘purple’)


Compare the line plot above with the same plot modified to use polar coordinates.

print(line_plot + coord_polar())

The result is not exactly a radar chart, there is a gap where the beginning and the end of the line were not connected.  We need to connect the line so that there is a completed path with no beginning and endpoint.  This can be accomplished using the geom_polygon instead of geom_line function.  Since we only want an outline (not a filled polygon) we specify fill=NA as an argument.  This looks a bit funny when plotted using a standard cartesian coordinate system.

polygon_plot = df %>% 
 filter(variable==’mpg’) %>%
 ggplot(aes(x=car, y=value, group=1)) + 
 geom_polygon(color = ‘purple’, fill=NA)


The result rendered with polar coordinates now includes a completed path.

print(polygon_plot + coord_polar())

A bit of cleanup of the themes and label orientation can improve the presentation further.

print(polygon_plot + coord_polar() + 
        theme_bw() + 
        theme(axis.text.x = 
      angle=-90 – 360 / length(unique(df$car)) * seq_along(df$car)

One of the values of radar charts is that the result has a distinctive “shape” that can help to highlight certain patterns or similarities between results.  Multifaceted charts can be used to quickly render a set of radar charts.  This example plots all car data variables and facets by variable type.

df %>%
 ggplot(aes(x=car, y=value, group=variable, color=variable)) + 
 geom_polygon(fill=NA) + 
 coord_polar() + theme_bw() + facet_wrap(~ variable) + 
 #scale_x_discrete(labels = abbreviate) + 
 theme(axis.text.x = element_text(size = 3))

This final example facets by car rather than variable type.  Cars with related characteristics share a similar shape.

df %>%
 ggplot(aes(x=variable, y=value, group=car, color=car)) + 
 geom_polygon(fill=NA) + 
 coord_polar() + theme_bw() + facet_wrap(~ car) 

Ggplot2 not only renders good-looking charts… it enables you to reason about them based upon a well thought out API.  Although radar plots are not currently included by default in ggplot2, if you reason about their structure a bit, you can “build up” a chart from the functions available.  Pie charts are also not included in ggplot2 but can be constructed using a stacked bar chart and specifying an appropriate coordinate system.  Ggplot2 provides a playground where you can train yourself to better understand the components of charts and how various chart types relates.  Working with the package in this way will help you see that the “gg” in ggplot2 is as significant as the plotting itself.

To leave a comment for the author, please follow the link and comment on their blog: R-Chart. offers daily e-mail updates about R news and tutorials about learning R and many other topics. Click here if you're looking to post or find an R/data-science job.
Want to share your content on R-bloggers? click here if you have a blog, or here if you don't.

Never miss an update!
Subscribe to R-bloggers to receive
e-mails with the latest R posts.
(You will not see this message again.)

Click here to close (This popup will not appear again)