How to choose colors of several convex hulls in a 3D environment and to display them in the legend?

Hello everyone,

I have built a 3D environment with several points for the different individuals of different groups in plot_ly on R. I was able to get a convex hull for each of the group but I can’t manage to get the same colors for these convex hulls as the ones used for the points, nor to get them in the legend and therefore cannot choose whether to display them or not.

Here is a subset of my data (15 rows):

structure(list(Dim.1 = c(-1.66218218068351, -1.54089611716482, 
-1.69396481956502, -2.17390793775836, -1.89654148822055, 0.133830523545437, 
0.259380958887321, 2.33273285516635, 0.614041383064022, -0.810456498949672, 
2.39414605406972, -0.270490723379913, 0.040624581491233, -0.860085321535654, 
-0.413284603509167, -1.19945764685421, -1.26198490666151, -1.64169470146003, 
-1.41841286755302, 0.116487687654103), Dim.2 = c(1.49013624024412, 
1.10841192775609, 1.36146620587346, 1.47562095807774, 1.40859174651776, 
1.85902171972337, 0.95918804016952, 1.44285670285851, 1.4351058325854, 
1.43065490325377, 1.00461883606259, 0.968929418999014, 0.732442016325051, 
1.80653021141781, 1.31788279983938, 1.27857296355683, 1.16339072990495, 
0.907778819038107, 1.1817781892271, 1.31747874027895), Dim.3 = c(0.448901070403223, 
0.71293085815581, 0.352289255436, 0.104996470361541, -0.00283165166254734, 
2.06082198348797, 2.52481753102989, -1.82823279868644, -0.590469705411186, 
0.101347585955537, -1.82539174036341, 0.521849361206393, 0.968259325821575, 
0.461483660862223, 0.822832783406133, -0.118440056106547, -0.465652890222368, 
-0.00627950759397972, -0.0843161614907643, -0.59313525893342), 
    Dim.4 = c(0.102369924556286, -0.0494120833525201, 0.834691238274808, 
    1.02831262202516, 0.826646086870935, -0.194159779209062, 
    0.704421397982499, 0.631555743217968, -0.713739725809427, 
    -0.131700651175048, 0.504854959572457, -0.570815838805, -1.08543238856329, 
    -0.49193828964481, -0.646650107593492, -0.107973575557607, 
    0.499541481565648, 0.0754431235885086, 0.389310696606881, 
    -0.141921543536795), Dim.5 = c(0.330069037381444, 0.760600822514828, 
    -0.155589492459669, -0.0135600742996482, -0.490304544490695, 
    0.735768333842011, 1.15227810337527, 0.199683055278656, 0.0795865046516087, 
    -0.603990571540292, -0.0419153340483225, -0.761770057884459, 
    -0.317137855265087, -0.325142467426912, -0.359402866621409, 
    -0.104936413340002, -0.100995473052205, -0.361928650451333, 
    -0.180283743190224, 0.163354435137426), Dim.6 = c(0.002982792864095, 
    0.231149659780945, 0.246398896715352, 0.319166032495582, 
    0.168209515277733, -0.630241510076728, -0.0913262723424757, 
    0.204626646512167, -0.106585804403048, 0.160084061288814, 
    0.336839824688217, -0.329428140898598, -0.604000676394403, 
    -0.246446571559567, -0.341960218562125, 0.239923595501739, 
    0.789228711878082, 0.195214145049783, 0.259585914185282, 
    0.324052751084852), Dim.7 = c(0.128134395954979, 0.0940080998379301, 
    0.0532691636740985, 0.0910309933055206, 0.0268173111574301, 
    0.301612442049654, 0.216730382065579, 0.00641657095998016, 
    -0.0784922450876965, -0.0758809037776677, -0.0457154790569843, 
    -0.0157086271797873, 0.13228966072771, 0.0866623211603163, 
    0.181421902637019, -0.177911254203293, -0.313422817560999, 
    0.0244700898604691, -0.0460004297419735, -0.112989594607267
    ), Dim.8 = c(0.0589080578109871, 0.103479814889764, 0.0972768921679227, 
    0.020839419598068, 0.137957898212134, -0.115299052903416, 
    -0.102409767146569, 0.0458647224401064, -0.0253650327056998, 
    0.172102502489923, 0.331980164969441, 0.0457063711034664, 
    0.0705283789649083, -0.0676008615860532, -0.0344453848031957, 
    0.138255360922819, 0.0871484452301794, 0.134727513167339, 
    0.081843338313648, 0.208095205376299), gen = c("<i> Flammeo </i>", 
    "<i> Flammeo </i>", "<i> Holocentrus </i>", "<i> Holocentrus </i>", 
    "<i> Holocentrus </i>", "<i> Holocentrus </i>", "<i> Holocentrus </i>", 
    "<i> Myripristis </i>", "<i> Myripristis </i>", "<i> Myripristis </i>", 
    "<i> Myripristis </i>", "<i> Neoniphon </i>", "<i> Neoniphon </i>", 
    "<i> Neoniphon </i>", "<i> Neoniphon </i>", "<i> Sargocentron </i>", 
    "<i> Sargocentron </i>", "<i> Sargocentron </i>", "<i> Sargocentron </i>", 
    "<i> Sargocentron </i>"), spe_id_ori = c("fla_mar_2_guad", 
    "fla_mar_4_guad", "holo_ads_3_guad", "holo_ads_4_guad", "holo_ads_5_guad", 
    "holo_ruf_1_guad", "holo_ruf_2_guad", "myr_adu_3_pf", "myr_adu_3_sey", 
    "myr_adu_4_gu", "myr_adu_4_pf", "neo_sam_4_pf", "neo_sam_4_ph", 
    "neo_sam_4_sey", "neo_sam_5_pf", "sar_pra_1_sey", "sar_pra_2_sey", 
    "sar_pra_3_sey", "sar_pra_6_sey", "sar_pra_7_ph"), subfamily = c("Holocentrinae", 
    "Holocentrinae", "Holocentrinae", "Holocentrinae", "Holocentrinae", 
    "Holocentrinae", "Holocentrinae", "Myripristinae", "Myripristinae", 
    "Myripristinae", "Myripristinae", "Holocentrinae", "Holocentrinae", 
    "Holocentrinae", "Holocentrinae", "Holocentrinae", "Holocentrinae", 
    "Holocentrinae", "Holocentrinae", "Holocentrinae")), row.names = c(NA, 
-20L), class = c("tbl_df", "tbl", "data.frame"))

My 3D environment :

plot3D_genres <- plot_ly(data = test, x = ~Dim.1, y = ~Dim.2, z = ~Dim.3, type = "scatter3d", mode = "markers",
                         color = ~gen, colors = c("#00BC00", "#8B2DB2", "#FC4E07", "#E7B800", "#00AFBB"), 
                         symbol = ~subfamily, symbols = c('square', 'circle'), # circle, cross, square, 'diamond', 'x'
                         legendgroup = ~gen) %>%
  add_markers(showlegend = FALSE, name = ~spe_id_ori) %>% # name = ~spe ou ~tribe (les infos données sur les points)
  layout(scene = list(
    xaxis = list(title = 'PC1 (47%)'),
    yaxis = list(title = 'PC2 (19%)'),
    zaxis = list(title = 'PC3 (16%)')),
    legend = list(title=list(text='<b> Genus </b>'), font = list(size = 18), x = 0.85, y = 0.5)
  ) 
plot3D_genres

And this is how I build the convex hulls :

test$gen <- ifelse(test$gen == "<i> Sargocentron </i>", "Sargocentron", 
                               ifelse(test$gen == "<i> Neoniphon </i>", "Neoniphon",
                                      ifelse(test$gen == "<i> Holocentrus </i>", "Holocentrus",
                                             ifelse(test$gen == "<i> Flammeo </i>", "Flammeo",
                                                    ifelse(test$gen == "<i> Myripristis </i>", "Myripristis",  test$gen)))))

# Get unique 'gen' values
unique_gen_values <- c("Holocentrus", "Myripristis", "Neoniphon", "Sargocentron")
# Create a color mapping based on the 'gen' values in plot3D_genres
color_mapping <- c("#8B2DB2", "#FC4E07", "#E7B800", "#00AFBB")
# Create an empty list to store the hull plots
hull_plots <- list()
# Iterate through each 'gen' value
  for(i in 1:4) {
    # Subset data for the current 'gen'
    g <- unique_gen_values[i]
  # Subset data for the current 'gen'
  gen_data <- test[test$gen == g, 1:9]
  # Compute the convex hull
  hull <- cxhull(as.matrix(gen_data[, c("Dim.1", "Dim.2", "Dim.3")]), triangulate = TRUE)
  # Extract the vertices and faces from the convex hull
  mesh <- hullMesh(hull, simplify = TRUE, rgl = FALSE)
  vertices <- mesh$vertices
  faces <- mesh$faces
  # Color
  current_color <- color_mapping[i]
  # Create 3D mesh plot for the convex hull with the same color as in the scatter plot
  hull_plot <- plot_ly(x = vertices[, 1], y = vertices[, 2], z = vertices[, 3],
                       i = faces[, 1] - 1, j = faces[, 2] - 1, k = faces[, 3] - 1,
                       type = "mesh3d",
                       opacity = 0.5, name = paste("<i>", g, "</i>"), color = current_color) # paste("Convex Hull ", g)
  # Add the hull plot to the list
  hull_plots[[g]] <- hull_plot
}
# Combine hull plots using subplot
combined_hull_plots <- subplot(plot3D_genres,
  hull_plots[[unique_gen_values[1]]],
  hull_plots[[unique_gen_values[2]]],
  hull_plots[[unique_gen_values[3]]],
  hull_plots[[unique_gen_values[4]]]
)