rggplot2plotlylegendggplotly

Problem in ggplot2 with color and shape variables combining into a concatenated legend


So I have a plot which I'm trying to have the points colored by type1 and the shape shaped by note1 etc. For some reason, the plot is concatenating the dang things into a key like this:

type1
note1
- - - - (border value name, 1)
------ (another value name, 1)
* (apple, blue)
O (orange, red)

Here's a bad picture of how I want it to be instead:

enter image description here

etc and I want it to just have the names of the variables, not the combination/concatenation of both things in text. When I used an AI chatbot I got a great solution, but the solution doesn't actually work in my code so far as I have tried it. The AI recommended solution (thats not working):

library(ggplot2)
library(plotly)
library(dplyr)
library(forcats)

# Sample data
set.seed(123)
data <- data.frame(
  groupID = rep(1:10, each = 3),
  AttributeValue = rnorm(30),
  type1 = rep(c("Single Observation", "Multiple Observations"), 15),
  note1 = rep(c("specific time", "shift", "notation", "interesting"), length.out = 30),
  MaterialNumber = sample(1000:9999, 30, replace = TRUE),
  MaterialName = sample(LETTERS, 30, replace = TRUE),
  date = sample(seq(as.Date('2022-01-01'), as.Date('2023-01-01'), by="day"), 30, replace = TRUE)
)

# Create ggplot
p1 <- data %>%
  mutate(groupID = fct_reorder(as.factor(groupID), date)) %>%
  mutate(MaterialInfo = paste(MaterialNumber, "-", MaterialName)) %>%
  ggplot(mapping = aes(x = groupID, y = AttributeValue)) +
  geom_line() + 
  facet_wrap(~ note1, scales = "free", ncol = 2) + 
  labs(x = "groupID") +
  theme_bw() +
  theme(axis.text.x = element_blank(), axis.ticks.x = element_blank(), 
        strip.text.x = element_text(size = 8, vjust = 0.5, margin = margin(0.25, 0, 0.25, 0, "cm"))) +
  geom_point(mapping = aes(
    color = note1,
    shape = type1,
    stroke = ifelse(type1 == "Multiple Observations", 0.5, 1),
    text = paste("SKU:", MaterialInfo,
                 "<br>groupID:", groupID,
                 "<br>date:", date,
                 "<br>Attribute Value:",  AttributeValue)),
    show.legend = TRUE) +
  scale_shape_manual(values = c("Multiple Observations" = 1, "Single Observation" = 16)) +
  scale_color_manual(values = c("specific time" = "#ffc425", 
                                "shift" = "#00b159", 
                                "notation" = "#d11141", 
                                "interesting" = "#f37735")) +
  guides(color = guide_legend(order = 1, override.aes = list(shape = NA)), 
         shape = guide_legend(order = 2))

# Convert to plotly
p1_plotly <- ggplotly(p1, tooltip = "text")

# Display plot
p1_plotly 

However, when I try this with my code I still can't get it to work:

library(ggplot2)
library(plotly)
library(dplyr)
library(forcats)

# Sample data
set.seed(123)
data <- data.frame(
  groupID = rep(1:10, each = 3),
  AttributeValue = rnorm(30),
  type1 = rep(c("Single Observation", "Multiple Observations"), 15),
  note1 = rep(c("specific time", "shift", "notation", "interesting"), length.out = 30),
  objectNumber = sample(1000:9999, 30, replace = TRUE),
  objectName = sample(LETTERS, 30, replace = TRUE),
  date = sample(seq(as.Date('2022-01-01'), as.Date('2023-01-01'), by="day"), 30, replace = TRUE)
)

# Create ggplot
p1 <- data %>%
  mutate(groupID = fct_reorder(as.factor(groupID), date)) %>%
  mutate(objectInfo = paste(objectNumber, "-", objectName)) %>%
  ggplot(mapping = aes(x = groupID, y = AttributeValue)) +
  geom_line() + 
  facet_wrap(~ note1, scales = "free", ncol = 2) + 
  labs(x = "groupID") +
  theme_bw() +
  theme(axis.text.x = element_blank(), axis.ticks.x = element_blank(), 
        strip.text.x = element_text(size = 8, vjust = 0.5, margin = margin(0.25, 0, 0.25, 0, "cm"))) +
  geom_point(mapping = aes(
    color = note1,
    shape = type1,
    stroke = ifelse(type1 == "Multiple Observations", 0.5, 1),
    text = paste("SKU:", objectInfo,
                 "<br>groupID:", groupID,
                 "<br>date:", date,
                 "<br>Attribute Value:",  AttributeValue)),
    show.legend = TRUE) +
  scale_shape_manual(values = c("Multiple Observations" = 1, "Single Observation" = 16)) +
  scale_color_manual(values = c("specific time" = "#ffc425", 
                                "shift" = "#00b159", 
                                "notation" = "#d11141", 
                                "interesting" = "#f37735")) +
  guides(color = guide_legend(order = 1, override.aes = list(shape = NA)), 
         shape = guide_legend(order = 2))

# Convert to plotly
p1_plotly <- ggplotly(p1, tooltip = "text")

# Display plot
p1_plotly

enter image description here

Help is appreciated, thank you


Solution

  • It maybe easier to just use plot_ly instead of passing off a ggplot object

    library(dplyr)
    library(ggplot2)
    library(forcats)
    library(plotly)
    
      
    
    
    
    clean = data |>
    janitor::clean_names() |>
      mutate(group_id = fct_reorder(as.factor(group_id), date),
             material_info = paste(material_number, '-', material_name),
             labs_plot = glue::glue('SKU: {material_info} <br>
                                     groupID: {group_id} <br>
                                     Attribute Value: {attribute_value}'))
    
    
    
    pal = c('#ffc425', '#00b159', '#d11141', '#f37735')
    
    pal = setNames(pal, c('specific time', 'shift', 'notation', 'interesting'))
    
    
    plot_ly(data = clean,
             x = ~group_id,
             y = ~attribute_value,
             text = ~labs_plot) |> 
      add_markers(
                  type = 'scatter',
                  mode = 'markers',
                  symbol = ~type1,
                  symbols = c('o', 'circle'),
                  color = I('black')) |> 
      add_markers(type = 'scatter',
                  mode = 'markers',
                  color = ~note1,
                  colors = pal)
    

    Alternatively ggiraph does a pretty good job with the existing ggplot object all you have to do is sub in _interactive

    library(ggiraph)
    
    
    
    p = ggplot(clean, aes(x = group_id, y = attribute_value,
                          color = note1, shape = type1, tooltip = labs_plot)) +
      geom_point_interactive() +
      scale_shape_manual_interactive(values = c("Multiple Observations" = 1, "Single Observation" = 16)) +
      scale_color_manual_interactive(values = c("specific time" = "#ffc425", 
                                                "shift" = "#00b159", 
                                                "notation" = "#d11141", 
                                                "interesting" = "#f37735"))
    
    
    girafe(ggobj = p)
    

    Created on 2024-11-26 with reprex v2.1.1