library(plotly)
## Warning: 程辑包'plotly'是用R版本4.2.3 来建造的
## 载入需要的程辑包:ggplot2
## Warning: 程辑包'ggplot2'是用R版本4.2.3 来建造的
## 
## 载入程辑包:'plotly'
## The following object is masked from 'package:ggplot2':
## 
##     last_plot
## The following object is masked from 'package:stats':
## 
##     filter
## The following object is masked from 'package:graphics':
## 
##     layout
library(htmlwidgets)
## Warning: 程辑包'htmlwidgets'是用R版本4.2.2 来建造的
# Create letter labels for axes
x_labels <- LETTERS[1:10]  # A to J for X-axis
y_labels <- letters[1:3]   # a to c for Y-axis

# Create sample data frame
# Structure: x (position), x_label (letter), y (position), y_label (letter), z (value)
df <- data.frame(
  x = rep(1:10, 3),                    # X-axis positions
  x_label = rep(x_labels, 3),          # X-axis letter labels
  y = rep(1:3, each = 10),             # Y-axis positions
  y_label = rep(y_labels, each = 10),  # Y-axis letter labels
  z = c(
    c(2.5, 3.2, 4.1, 3.8, 4.5, 5.2, 4.8, 5.5, 6.0, 5.8),  # First line
    c(3.0, 3.8, 4.5, 4.2, 5.0, 5.8, 5.2, 6.0, 6.5, 6.2),  # Second line
    c(3.5, 4.2, 5.0, 4.8, 5.5, 6.2, 5.8, 6.5, 7.0, 6.8)   # Third line
  )
)
df
##     x x_label y y_label   z
## 1   1       A 1       a 2.5
## 2   2       B 1       a 3.2
## 3   3       C 1       a 4.1
## 4   4       D 1       a 3.8
## 5   5       E 1       a 4.5
## 6   6       F 1       a 5.2
## 7   7       G 1       a 4.8
## 8   8       H 1       a 5.5
## 9   9       I 1       a 6.0
## 10 10       J 1       a 5.8
## 11  1       A 2       b 3.0
## 12  2       B 2       b 3.8
## 13  3       C 2       b 4.5
## 14  4       D 2       b 4.2
## 15  5       E 2       b 5.0
## 16  6       F 2       b 5.8
## 17  7       G 2       b 5.2
## 18  8       H 2       b 6.0
## 19  9       I 2       b 6.5
## 20 10       J 2       b 6.2
## 21  1       A 3       c 3.5
## 22  2       B 3       c 4.2
## 23  3       C 3       c 5.0
## 24  4       D 3       c 4.8
## 25  5       E 3       c 5.5
## 26  6       F 3       c 6.2
## 27  7       G 3       c 5.8
## 28  8       H 3       c 6.5
## 29  9       I 3       c 7.0
## 30 10       J 3       c 6.8
# Define color scheme for lines and points
# Each line has two colors: one for the line itself and one for points
line_colors <- list(
  list(
    line = "rgb(255, 100, 100)",  # Bright red for line
    point = "rgb(200, 50, 50)"    # Dark red for points
  ),
  list(
    line = "rgb(100, 255, 100)",  # Bright green for line
    point = "rgb(50, 200, 50)"    # Dark green for points
  ),
  list(
    line = "rgb(100, 100, 255)",  # Bright blue for line
    point = "rgb(50, 50, 200)"    # Dark blue for points
  )
)

# Point style settings
point_settings <- list(
  size = 10,                # Point size (1-20)
  opacity = 0.8,           # Point transparency (0-1)
  symbol = "circle"        # Point shape: "circle", "square", "diamond", "cross", "x"
)

# Line style settings
line_settings <- list(
  width = 4,               # Line width (1-10)
  opacity = 0.8            # Line transparency (0-1)
)
head(df)
##   x x_label y y_label   z
## 1 1       A 1       a 2.5
## 2 2       B 1       a 3.2
## 3 3       C 1       a 4.1
## 4 4       D 1       a 3.8
## 5 5       E 1       a 4.5
## 6 6       F 1       a 5.2
# Create empty plotly object
fig <- plot_ly()

# Add lines and points for each curve
for(y_val in unique(df$y_label)) {
  # Filter data for current line
  curve_data <- df[df$y_label == y_val,]
  color_idx <- which(unique(df$y_label) == y_val)
  
  # Add main curve
  fig <- fig %>% add_trace(
    x = curve_data$x_label,
    y = rep(y_val, nrow(curve_data)),
    z = curve_data$z,
    type = 'scatter3d',
    mode = 'lines',
    line = list(
      width = line_settings$width,
      color = line_colors[[color_idx]]$line
    ),
    opacity = line_settings$opacity,
    showlegend = FALSE
  )
  
  # Add data points with labels
  fig <- fig %>% add_trace(
    x = curve_data$x_label,
    y = rep(y_val, nrow(curve_data)),
    z = curve_data$z,
    type = 'scatter3d',
    mode = 'markers+text',
    marker = list(
      size = point_settings$size,
      color = line_colors[[color_idx]]$point,
      opacity = point_settings$opacity,
      symbol = point_settings$symbol
    ),
    text = sprintf("%.1f", curve_data$z),
    textposition = "top center",
    textfont = list(
      size = 12,
      color = 'rgba(70, 70, 70, 0.9)'
    ),
    showlegend = FALSE
  )
}
print(fig)
# Configure layout settings
fig_1 <- fig %>% layout(
  scene = list(
    camera = list(
      eye = list(x = 2, y = 2, z = 1.5)  # Camera position
    ),
    xaxis = list(
      title = "X",
      ticktext = x_labels,    # X-axis letter labels
      tickvals = 1:10,        # Position of labels
      gridcolor = 'rgb(240, 240, 240)',
      zerolinecolor = 'rgb(200, 200, 200)',
      zerolinewidth = 2,
      range = c(0, 11)
    ),
    yaxis = list(
      title = "Y",
      ticktext = y_labels,    # Y-axis letter labels
      tickvals = 1:3,         # Position of labels
      gridcolor = 'rgb(240, 240, 240)',
      zerolinecolor = 'rgb(200, 200, 200)',
      zerolinewidth = 2,
      range = c(0, 4)
    ),
    zaxis = list(
      title = "Z",
      gridcolor = 'rgb(240, 240, 240)',
      zerolinecolor = 'rgb(200, 200, 200)',
      zerolinewidth = 2,
      range = c(0, max(df$z) * 1.1)
    ),
    aspectmode = 'manual',
    aspectratio = list(x = 1.5, y = 1, z = 1),
    bgcolor = 'rgb(252, 252, 252)'
  ),
  margin = list(l = 0, r = 0, b = 0, t = 0)
)

# Display the plot
fig_1
# Export methods

# 1. Save as HTML (interactive)
saveWidget(fig, "3d_plot_interactive.html", selfcontained = TRUE)

# 2. Save as PNG (static)
# Note: Requires webshot2 package
if (!require("webshot2")) install.packages("webshot2")
## 载入需要的程辑包:webshot2
## Warning: 程辑包'webshot2'是用R版本4.2.3 来建造的
library(webshot2)
# Save as PNG with specified dimensions
saveWidget(fig, "temp.html", selfcontained = TRUE)
webshot("temp.html", "3d_plot.png", delay = 0.1, 
        vwidth = 1000, vheight = 800)

#getwd()
# Additional customization options:
# 1. Change point style:
#    point_settings$size = 15          # Larger points
#    point_settings$symbol = "square"  # Different shape

# 2. Change line style:
#    line_settings$width = 6           # Thicker lines
#    line_settings$opacity = 0.6       # More transparent

# 3. Change colors:
#    line_colors[[1]]$line = "rgb(200, 0, 0)"    # Different line color
#    line_colors[[1]]$point = "rgb(150, 0, 0)"   # Different point color

# 4. Change camera angle:
#    eye = list(x = 1.5, y = 1.5, z = 2)         # Different view angle