Interactive: Mean and variance of normal distribution
Summary
    Interactive diagram for seeing how the mean and variance affect the shape of the normal distribution.
  #| '!! shinylive warning !!': |
#|   shinylive does not work in self-contained HTML documents.
#|   Please set `embed-resources: false` in your metadata.
#| standalone: true
#| viewerHeight: 770
library(shiny)
library(bslib)
library(ggplot2)
ui <- page_fluid(
  title = "Normal distribution visualizer",
  
  # Plot at the top
  card(
    card_header("Normal distribution plot"),
    card_body(
      plotOutput("distPlot", height = "500px")
    )
  ),
  
  # Parameters below
  card(
    card_header("Distribution parameters"),
    card_body(
      layout_columns(
        col_widths = c(6, 6),
        sliderInput("mean", "Mean/expected value (μ):", 
                   min = -5, max = 5, value = 0, step = 0.1),
        sliderInput("variance", "Variance (σ²):", 
                   min = 0.25, max = 9, value = 1, step = 0.25)
      )
    )
  )
)
server <- function(input, output, session) {
  
  # Generate the normal distribution plot
  output$distPlot <- renderPlot({
    # Fixed range for x-axis to show consistent scale
    x_min <- -8
    x_max <- 8
    
    # Convert variance to standard deviation
    sd_val <- sqrt(input$variance)
    
    # Create data frame for plotting
    x <- seq(x_min, x_max, length.out = 500)
    y <- dnorm(x, mean = input$mean, sd = sd_val)
    df <- data.frame(x = x, y = y)
    
    # Create plot with fixed axes
    p <- ggplot(df, aes(x = x, y = y)) +
      geom_line(color = "#3F6BB6", size = 1.2) +
      labs(x = "X", y = "Density",
           title = sprintf("Normal distribution: N(μ = %.1f, σ² = %.2f)", 
                          input$mean, input$variance)) +
      theme_minimal() +
      theme(
        panel.grid.minor = element_blank(),
        plot.title = element_text(hjust = 0.5, size = 16),
        axis.title = element_text(size = 14),
        axis.text = element_text(size = 12)
      ) +
      # Fixed axis limits
      xlim(x_min, x_max) +
      ylim(0, 0.8) +
      # Add reference line at x = 0
      geom_vline(xintercept = 0, linetype = "dashed", color = "gray50", alpha = 0.7) +
      # Add reference line at mean
      geom_vline(xintercept = input$mean, linetype = "dashed", color = "#DB4315", alpha = 0.7) +
      annotate("text", x = input$mean + 0.8, y = 0.7, label = "Mean", color = "#DB4315", size = 4)
    
    return(p)
  })
}
shinyApp(ui = ui, server = server)Further reading
Version history
v1.0: initial version created 08/24 by tdhc.