R: Как «заполнить» сетку точками

#r #plot #3d #plotly #data-visualization

Вопрос:

Я работаю с языком программирования R.

Предположим, у меня есть следующая функция:

 # function: defined the first way

my_function_a <- function(x) {
  
  final_value = sin(x[1])   cos(x[2])   x[3] 
  
 
}

    #function : defined the second way
    
    my_function_b <- function(input_1, input_2, input_3) {
    
    final_value = sin(input_1)   cos(input_2)   input_3 
     
    }
 

Цель: Я хочу оценить эту функцию в разных точках, чтобы я мог построить трехмерный график.

Первая попытка:

Я попробовал очень простой подход для оценки этой функции в ряде фиксированных точек (с использованием сетки).:

 library(plotly)
library(dplyr)

#create grid and evaluate function
input_1 <- seq(0,100,1)
input_2 <- seq(0,100,1)
input_3 <- seq(0,100,1)


my_grid <- data.frame(input_1, input_2, input_3)
my_grid$final_value = sin(input_1)   cos(input_2)   input_3 
 

А затем я попытался построить эту функцию:

 #plot function

plot_ly() %>% 
        add_trace(data = my_grid,  x=my_grid$input_1, y=my_grid$input_2, z=my_grid$input_3, type='mesh3d') %>%
        add_surface(
                z = my_grid %>% as.matrix(),
                surfacecolor = my_grid,
                cauto=F,
                cmax=max(my_grid$final_value),
                cmin=min(my_grid$final_value)
        )
 

Сюжет этой функции выглядит обманчиво «простым».:
введите описание изображения здесь

Затем я понял, что это происходит потому, что я оценивал эту функцию только в «равномерно расположенных» точках, например:

  head(my_grid)
  input_1 input_2 input_3 final_value
1       0       0       0    1.000000
2       1       1       1    2.381773
3       2       2       2    2.493151
4       3       3       3    2.151128
5       4       4       4    2.589554
6       5       5       5    4.324738
 

Например, в приведенном выше фрейме данных вы не найдете комбинации таких точек, как (input_1 = 5, input_2 = 2, input_3 =11)

Вторая попытка

Затем я попытался добавить некоторую «случайность», чтобы решить, в каких точках оценивать функцию:

 #create grid and evaluate function
input_1 <- rnorm(100,100,20)
input_2 <- rnorm(100,100,20)
input_3 <- rnorm(100,100,20)


my_grid <- data.frame(input_1, input_2, input_3)
my_grid$final_value = sin(input_1)   cos(input_2)   input_3 


#create plot
plot_ly() %>% 
        add_trace(data = my_grid,  x=my_grid$input_1, y=my_grid$input_2, z=my_grid$input_3, type='mesh3d') %>%
        add_surface(
                z = my_grid %>% as.matrix(),
                surfacecolor = my_grid,
                cauto=F,
                cmax=max(my_grid$final_value),
                cmin=min(my_grid$final_value)
        )
 

введите описание изображения здесь

Теперь график, по-видимому, содержит более высокий уровень сложности, как видно из данных, используемых для создания графика:

 head(my_grid)
    input_1   input_2   input_3 final_value
1  82.09936  65.48251 103.26060   102.78460
2  81.94343 118.69431  76.51834    77.55103
3  76.90372 115.58958 123.96159   124.16298
4 128.52814  85.52632  69.02835    68.53927
5  96.89466 121.53117 124.39381   124.32069
6  97.59012 126.80997  87.54789    87.76038
 

Вопрос: Есть ли какие-либо «лучшие» способы заполнить эту сетку точками, чтобы вы могли построить «более красивый и реалистичный» сюжет? Например, можно ли создать сетку таким образом, чтобы

 #iterate input_1 from 1-100 AND fix input_2 and input_3 as constant
input_1 = 1, input_2 = 1, input_3 = 1 ; input_1 = 2, input_2 = 1, input_3 = 1 ; etc; input_1 = 100, input_2 = 1, input_3 = 1

#iterate input_2 from 1-100 AND fix input_1 and input_3 as constant 
input_1 = 1, input_2 = 2, input_3 = 1; input_1 = 1, input_2 = 3, input_3 = 1 , etc
 

Можно ли оценить «my_function_a» или «my_function_b», используя такую сетку?

Спасибо

Ответ №1:

Если я правильно понимаю, проблема вызвана my_grid неполным заполнением.

 head(my_grid)
 
   input_1 input_2 input_3 final_value
1       0       0       0    1.000000
2       1       1       1    2.381773
3       2       2       2    2.493151
4       3       3       3    2.151128
5       4       4       4    2.589554
6       5       5       5    4.324738
 

Все три входные переменные выдвигаются одновременно, что создает линию в трехмерном пространстве.

Возможно, вы имели в виду использовать expand.grid() для создания трехмерной сетки:

 n <- 3
my_grid <- expand.grid(i1 = 1:n, i2 = 1:n, i3 = 1:n)
my_grid$final_value = with(my_grid, sin(i1)   cos(i2)   i3)
head(my_grid)
 
   i1 i2 i3 final_value
1  1  1  1   2.3817733
2  2  1  1   2.4495997
3  3  1  1   1.6814223
4  1  2  1   1.4253241
5  2  2  1   1.4931506
6  3  2  1   0.7249732
 

Итак, сюжет

 library(plotly)
plot_ly() %>% 
  add_trace(data = my_grid,  x=my_grid$i1, y=my_grid$i2, z=my_grid$i3, type='mesh3d') %>%
  add_surface(
    z = my_grid %>% as.matrix(),
    surfacecolor = my_grid,
    cauto=F,
    cmax=max(my_grid$final_value),
    cmin=min(my_grid$final_value)
  )
 

становится

введите описание изображения здесь

Комментарии:

1. Я внес небольшое изменение в код построения графиков: plot_ly() %>% add_trace(данные = my_grid, x=my_grid$i1, y=my_grid$i2, z=my_grid$final_value, тип=’mesh3d’) %>>% add_surface( z = my_grid %>>>% as.matrix(), цвет поверхности = my_grid, cauto=F, cmax=макс(my_grid$final_value), cmin=мин(my_grid$окончательное значение) )

2. Я также нашел способ изменить приращения пояса: n <- 3 my_grid

3. @noob Рад, что вы нашли решение самостоятельно! seq(from, to, by) это тоже было бы моим предложением.