# Adding Horizontal & Vertical Lines to plotly Graph in R

This tutorial provides several examples to add custom lines and shapes to plotly graphs in the R programming language.

Table of contents:

**Note:** This article was created in collaboration with Kirby White. Kirby is a Statistics Globe author, innovation consultant, and data science instructor. His Ph.D. is in Industrial-Organizational Psychology. You can read more about Kirby here!

## Packages and Example Data

If you have not already done so, install and load these packages:

We’ll use the `mtcars`

dataset for this example, which is already included in R.

df <- datasets::mtcars |

df <- datasets::mtcars

Let’s build a basic scatterplot that we’ll store in an object called `fig`

, which we’ll modify throughout the tutorial to demonstrate the features:

fig <- df %>% plot_ly( x = ~disp, y = ~mpg, color = ~factor(cyl), type = "scatter", mode = "markers" ) %>% layout(title=list(text='<b>Cylinders</b>')) |

fig <- df %>% plot_ly( x = ~disp, y = ~mpg, color = ~factor(cyl), type = "scatter", mode = "markers" ) %>% layout(title=list(text='<b>Cylinders</b>'))

## Single Lines

Let’s start by adding a horizontal line to show the mean `mpg`

for all cylinders and displacement values.

fig %>% add_lines( y = mean(df$mpg), x = range(df$disp), line = list( color = "grey" ), inherit = FALSE, showlegend = FALSE ) |

fig %>% add_lines( y = mean(df$mpg), x = range(df$disp), line = list( color = "grey" ), inherit = FALSE, showlegend = FALSE )

The `x`

and `y`

arguments can accept a single value or a vector of two numeric values. In this case, we passed a single value to the `y`

argument by calculating the mean `mpg`

. The `range`

function returned a two-element vector with the min and max `disp`

to have the line stretch across all points in the graph. Note that you may need to add `na.rm = TRUE`

to your `mean`

function to ignore missing values.

Creating a vertical line is the same, but flipping the inputs to the `x`

and `y`

arguments:

fig %>% add_lines( y = range(df$mpg), x = mean(df$disp), line = list( color = "grey" ), inherit = FALSE, showlegend = FALSE ) |

fig %>% add_lines( y = range(df$mpg), x = mean(df$disp), line = list( color = "grey" ), inherit = FALSE, showlegend = FALSE )

## Multiple Lines

You can add multiple `add_lines()`

elements to a graph to mix-and-match multiple lines across groups. This example shows how to create a vertical line within each group of vehicles.

fig %>% add_lines( y = range(df[df$cyl == 4,"mpg"]), x = mean(df[df$cyl == 4,"disp"]), inherit = FALSE, showlegend = FALSE, line = list(color = "gray") ) %>% add_lines( y = range(df[df$cyl == 6,"mpg"]), x = mean(df[df$cyl == 6,"disp"]), inherit = FALSE, showlegend = FALSE, line = list(color = "gray") ) %>% add_lines( y = range(df[df$cyl == 8,"mpg"]), x = mean(df[df$cyl == 8,"disp"]), inherit = FALSE, showlegend = FALSE, line = list(color = "gray") ) |

fig %>% add_lines( y = range(df[df$cyl == 4,"mpg"]), x = mean(df[df$cyl == 4,"disp"]), inherit = FALSE, showlegend = FALSE, line = list(color = "gray") ) %>% add_lines( y = range(df[df$cyl == 6,"mpg"]), x = mean(df[df$cyl == 6,"disp"]), inherit = FALSE, showlegend = FALSE, line = list(color = "gray") ) %>% add_lines( y = range(df[df$cyl == 8,"mpg"]), x = mean(df[df$cyl == 8,"disp"]), inherit = FALSE, showlegend = FALSE, line = list(color = "gray") )

This is an explicit way of adding several lines, but it can be cumbersome if you have much more than this! Let’s look at a more complicated — but scalable — way of adding several lines. We’ll create a function to add a vertical line to each group, regardless of how many groups there are.

vertical_lines <- function(fig, groups, x_variable, y_variable, data){ return_fig <- fig for (i in unique(data[,`groups`])){ temp_dat <- data[data[,`groups`] == i,c(`x_variable`, `y_variable`)] # print(dim(temp_dat)) return_fig <- return_fig %>% add_lines( y = range(temp_dat[,2], na.rm = TRUE), x = mean(temp_dat[,1], na.rm = TRUE), inherit = FALSE, showlegend = FALSE ) } return(return_fig) } |

vertical_lines <- function(fig, groups, x_variable, y_variable, data){ return_fig <- fig for (i in unique(data[,`groups`])){ temp_dat <- data[data[,`groups`] == i,c(`x_variable`, `y_variable`)] # print(dim(temp_dat)) return_fig <- return_fig %>% add_lines( y = range(temp_dat[,2], na.rm = TRUE), x = mean(temp_dat[,1], na.rm = TRUE), inherit = FALSE, showlegend = FALSE ) } return(return_fig) }

We can now pass our baseline figure (fig) into the function and it will add a vertical line to each group.

vertical_lines(fig = fig, groups = 'cyl', data = df, x_variable = 'disp', y_variable = 'mpg') |

vertical_lines(fig = fig, groups = 'cyl', data = df, x_variable = 'disp', y_variable = 'mpg')

## Line Formatting

There are many ways to format lines in plotly. Let’s use an example from above, but change several characteristics of each line. This example should give you ideas about ways to change your graphs!

fig %>% add_lines( y = range(df[df$cyl == 4, 'mpg']), x = mean(df[df$cyl == 4, 'disp']), inherit = FALSE, showlegend = FALSE, line = list(color = "gray", width = 15, dash = 'dot') ) %>% add_lines( y = range(df[df$cyl == 6, 'mpg']), x = mean(df[df$cyl == 6, 'disp']), inherit = FALSE, showlegend = FALSE, line = list(color = "red", width = 5, dash = 'dash') ) %>% add_lines( y = range(df[df$cyl == 8, 'mpg']), x = mean(df[df$cyl == 8, 'disp']), inherit = FALSE, showlegend = FALSE, line = list(color = "rgb(115,112,110)", dash = 'solid')) ) |

fig %>% add_lines( y = range(df[df$cyl == 4, 'mpg']), x = mean(df[df$cyl == 4, 'disp']), inherit = FALSE, showlegend = FALSE, line = list(color = "gray", width = 15, dash = 'dot') ) %>% add_lines( y = range(df[df$cyl == 6, 'mpg']), x = mean(df[df$cyl == 6, 'disp']), inherit = FALSE, showlegend = FALSE, line = list(color = "red", width = 5, dash = 'dash') ) %>% add_lines( y = range(df[df$cyl == 8, 'mpg']), x = mean(df[df$cyl == 8, 'disp']), inherit = FALSE, showlegend = FALSE, line = list(color = "rgb(115,112,110)", dash = 'solid')) )

## Further Resources

You may find a video introduction to the plotly package below:

**Please accept YouTube cookies to play this video.** By accepting you will be accessing content from YouTube, a service provided by an external third party.

If you accept this notice, your choice will be saved and the page will refresh.

Furthermore, you can check out these other articles for more detailed examples and videos of these popular charts in plotly:

- Introduction to the plotly Package in R
- plotly Line Plot in R
- plotly Scatterplot in R
- plotly Barplot in R
- plotly Boxplot in R
- plotly Histograms in R

### Statistics Globe Newsletter