Violin Plots in R

How to create violin plots in R with Plotly.


Plotly Studio: Transform any dataset into an interactive data application in minutes with AI. Sign up for early access now.

Basic Violin Plot

library(plotly)

df <- read.csv("https://raw.githubusercontent.com/plotly/datasets/master/violin_data.csv")

fig <- df %>%
  plot_ly(
    y = ~total_bill,
    type = 'violin',
    box = list(
      visible = T
    ),
    meanline = list(
      visible = T
    ),
    x0 = 'Total Bill'
  ) 

fig <- fig %>%
  layout(
    yaxis = list(
      title = "",
      zeroline = F
    )
  )

fig

Multiple Trace

library(plotly)

df <- read.csv("https://raw.githubusercontent.com/plotly/datasets/master/violin_data.csv")

fig <- df %>%
  plot_ly(
    x = ~day,
    y = ~total_bill,
    split = ~day,
    type = 'violin',
    box = list(
      visible = T
    ),
    meanline = list(
      visible = T
    )
  ) 

fig <- fig %>%
  layout(
    xaxis = list(
      title = "Day"
    ),
    yaxis = list(
      title = "Total Bill",
      zeroline = F
    )
  )

fig

Grouped Violin Plot

library(plotly)

df <- read.csv("https://raw.githubusercontent.com/plotly/datasets/master/violin_data.csv")

fig <- df %>%
  plot_ly(type = 'violin') 
fig <- fig %>%
  add_trace(
    x = ~day[df$sex == 'Male'],
    y = ~total_bill[df$sex == 'Male'],
    legendgroup = 'M',
    scalegroup = 'M',
    name = 'M',
    box = list(
      visible = T
    ),
    meanline = list(
      visible = T
    ),
    color = I("blue")
  ) 
fig <- fig %>%
  add_trace(
    x = ~day[df$sex == 'Female'],
    y = ~total_bill[df$sex == 'Female'],
    legendgroup = 'F',
    scalegroup = 'F',
    name = 'F',
    box = list(
      visible = T
    ),
    meanline = list(
      visible = T
    ),
    color = I("pink")
  ) 

fig <- fig %>%
  layout(
    yaxis = list(
      zeroline = F
    ),
    violinmode = 'group'
  )

fig
SunSatThurFri−100102030405060
MFday[df$sex == "Male"]total_bill[df$sex == "Male"]

Split Violin Plot

library(plotly)

df <- read.csv("https://raw.githubusercontent.com/plotly/datasets/master/violin_data.csv")

fig <- df %>%
  plot_ly(type = 'violin') 
fig <- fig %>%
  add_trace(
    x = ~day[df$smoker == 'Yes'],
    y = ~total_bill[df$smoker == 'Yes'],
    legendgroup = 'Yes',
    scalegroup = 'Yes',
    name = 'Yes',
    side = 'negative',
    box = list(
      visible = T
    ),
    meanline = list(
      visible = T
    ),
    color = I("blue")
  ) 
fig <- fig %>%
  add_trace(
    x = ~day[df$smoker == 'No'],
    y = ~total_bill[df$smoker == 'No'],
    legendgroup = 'No',
    scalegroup = 'No',
    name = 'No',
    side = 'positive',
    box = list(
      visible = T
    ),
    meanline = list(
      visible = T
    ),
    color = I("green")
  ) 

fig <- fig %>%
  layout(
    xaxis = list(
      title = ""  
    ),
    yaxis = list(
      title = "",
      zeroline = F
    ),
    violingap = 0,
    violingroupgap = 0,
    violinmode = 'overlay'
  )

fig

Advanced Violin Plot

library(plotly)

df <- read.csv("https://raw.githubusercontent.com/plotly/datasets/master/violin_data.csv")

pointposMale <- c(-0.9,-1.1,-0.6,-0.3)
pointposFemale <- c(0.45,0.55,1,0.4)
showLegend <- c(T,F,F,F)

fig <- plot_ly(type = 'violin')

i = 0
for (i in 1:length(unique(df$day))) {
 fig <- add_trace(
    fig,
    x = df$day[df$sex == 'Male' & df$day == unique(df$day)[i]],
    y = df$total_bill[df$sex == 'Male' & df$day == unique(df$day)[i]],
    hoveron = "points+kde",
    legendgroup = 'M',
    scalegroup = 'M',
    name = 'M',
    side = 'negative',
    box = list(
      visible = T
    ),
    points = 'all',
    pointpos = pointposMale[i],
    jitter = 0,
    scalemode = 'count',
    meanline = list(
      visible = T
    ),
    color = I("#8dd3c7"),
    marker = list(
      line = list(
        width = 2,
        color = "#8dd3c7"
      ),
      symbol = 'line-ns'
    ),
    showlegend = showLegend[i]
    ) 

fig <- fig %>%
    add_trace(
      x = df$day[df$sex == 'Female' & df$day == unique(df$day)[i]],
      y = df$total_bill[df$sex == 'Female' & df$day == unique(df$day)[i]],
      hoveron = "points+kde",
      legendgroup = 'F',
      scalegroup = 'F',
      name = 'F',
      side = 'positive',
      box = list(
        visible = T
      ),
      points = 'all',
      pointpos = pointposFemale[i],
      jitter = 0,
      scalemode = 'count',
      meanline = list(
        visible = T
      ),
      color = I("#bebada"),
      marker = list(
        line = list(
          width = 2,
          color = "#bebada"
        ),
        symbol = 'line-ns'
      ),
      showlegend = showLegend[i]
  )
}

fig <- layout(
  fig,
  title = "Total bill distribution<br><i>scaled by number of bills per gender",
  yaxis = list(
    zeroline = F
  ),
  violingap = 0,
  violingroupgap = 0,
  violinmode = 'overlay',
  legend = list(
    tracegroupgap = 0
  )
)

fig
SunSatThurFri−100102030405060
MFTotal bill distributionscaled by number of bills per gender

Reference

See https://plotly.com/r/reference/ for more information and options!

What About Dash?

Dash for R is an open-source framework for building analytical applications, with no Javascript required, and it is tightly integrated with the Plotly graphing library.

Learn about how to install Dash for R at https://dashr.plot.ly/installation.

Everywhere in this page that you see fig, you can display the same figure in a Dash for R application by passing it to the figure argument of the Graph component from the built-in dashCoreComponents package like this:

library(plotly)

fig <- plot_ly() 
# fig <- fig %>% add_trace( ... )
# fig <- fig %>% layout( ... ) 

library(dash)
library(dashCoreComponents)
library(dashHtmlComponents)

app <- Dash$new()
app$layout(
    htmlDiv(
        list(
            dccGraph(figure=fig) 
        )
     )
)

app$run_server(debug=TRUE, dev_tools_hot_reload=FALSE)