2017-03-10 17 views
2

カテゴリファクタ(私の場合は性別)の2つのレベルの2つの回帰直線を持つ散布図を作成する必要があります。散布図はすべての観測値を持つ必要がありますが、各レベルの線形モデルは別々にプロットする必要があります。つまり、次のモデルの散布図:R plot_ly連続的な相互作用散布図色と記号の回帰直線

continuousA = intercept + continuousB + categorical + continuousB * categorical。

add_lines()およびadd_ribbons()が削除されない限り、Plotlyはadd_markers()で指定された色を登録しません。 Plotly(バグ?)でこれを行うことができない場合、ggplot(とおそらくGGally)を使って行うことができますか?

また、もっと短く、よりきめ細やかな、よりきれいなコードで、または関数でこれを行うことができますか?一度に3つのアイリスをすべて種にする方が良いでしょう。

library(plotly) 
library(broom) 
plot_ly() %>% 
    add_lines(data = iris[which(iris$Species=='versicolor'), ], 
      y = ~fitted(lm(data = iris[which(iris$Species=='versicolor'), ], Petal.Width ~ Petal.Length)), 
      x = ~Petal.Length, 
      line = list(color = "red"), 
      name = "Versicolor") %>% 
    # Plot the 95% CI of slope ribbon 
    add_ribbons(data = augment(lm(data = iris[which(iris$Species=='versicolor'), ], Petal.Width ~ Petal.Length)), 
       y = ~Petal.Width, 
       x = ~Petal.Length, 
       ymin = ~.fitted - 1.96 * .se.fit, 
       ymax = ~.fitted + 1.96 * .se.fit, 
       line = list(color = 'rgba(255, 255, 255, 0.05)'), #get rid of the border line 
       fillcolor = 'rgba(255, 0, 0, 0.1)', #red with alpha transparency 
       name = "Versicolor (Standard Error)", 
       showlegend = FALSE) %>% 
    add_lines(data = iris[which(iris$Species=='virginica'), ], 
      y = ~fitted(lm(data = iris[which(iris$Species=='virginica'), ], Petal.Width ~ Petal.Length)), 
      x = ~Petal.Length, 
      line = list(color = "green", dash = "dash"), 
      name = "Viginica") %>% 
    add_ribbons(data = augment(lm(data = iris[which(iris$Species=='virginica'), ], Petal.Width ~ Petal.Length)), 
       y = ~Petal.Width, 
       x = ~Petal.Length, 
       ymin = ~.fitted - 1.96 * .se.fit, 
       ymax = ~.fitted + 1.96 * .se.fit, 
       line = list(color = 'rgba(255, 255, 255, 0.05)'), #get rid of the border line 
       fillcolor = 'rgba(0, 255, 0, 0.1)', #green with alpha transparency 
       name = "Virginica (Standard Error)", 
       showlegend = FALSE) %>% 
    add_markers(data = iris[which(iris$Species=='versicolor' | iris$Species=='virginica'), ], 
       x = ~Petal.Length, 
       y = ~Petal.Width, 
       symbol = ~Species, 
       color = ~Species, colors = c("versicolor" = "red", "virginica" = "green")) %>% 
    layout(xaxis = list(title = "Petal Length"), yaxis = list(title = "Petal Width")) 

Interaction Scatterplot

答えて

2

Plotlyは( add_linesない限り、)(add_markersによって指定された色を登録しない)とadd_ribbons()が除去されます。これができない場合はPlotly(バグですか?)と を実行して、ggplot(とおそらく GGally)を実行できますか?

異なるカテゴリのマーカーを個別に追加することができます。すなわち、add_markersを繰り返し呼び出します。

また、私は、これは、短い整然と、または きれいコードで、または関数で行うことができるかどうか見てみたいです。一度にすべて3種類のアイリス$種を することがさらに良いでしょう。

3つの種すべてをループすることができます。そのため、コードを1回書く必要があります。

library(plotly) 
library(broom) 

species <- unique(iris$Species) 
colors <- c('(255, 0, 0', '(0, 255, 0', '(0, 0, 255') 

p <- plot_ly() 

for (i in 1:length(species)) { 
    p <- add_lines(p, data = iris[which(iris$Species==species[[i]]), ], 
      y = fitted(lm(data = iris[which(iris$Species==species[[i]]), ], Petal.Width ~ Petal.Length)), 
      x = ~Petal.Length, 
      line = list(color = paste('rgb', colors[[i]], ')')), 
      name = species[[i]]) 
    p <- add_ribbons(p, data = augment(lm(data = iris[which(iris$Species==species[[i]]), ], Petal.Width ~ Petal.Length)), 
       y = ~Petal.Width, 
       x = ~Petal.Length, 
       ymin = ~.fitted - 1.96 * .se.fit, 
       ymax = ~.fitted + 1.96 * .se.fit, 
       line = list(color = paste('rgba', colors[[i]], ', 0.05)')), 
       fillcolor = paste('rgba', colors[[i]], ', 0.1)'), 
       showlegend = FALSE) 
    p <- add_markers(p, data = iris[which(iris$Species==species[[i]]), ], 
       x = ~Petal.Length, 
       y = ~Petal.Width, 
       symbol = ~Species, 
       marker=list(color=paste('rgb', colors[[i]]))) 
} 
p <- layout(p, xaxis = list(title = "Petal Length"), yaxis = list(title = "Petal Width")) 

p 

enter image description here

+0

これは美しいです。ありがとうございました! –

0

マクシミリアン・ピーターズは、この質問への優れた答えを提供します。彼の答えから私が作った機能があります。

plotly_interaction <- function(data, x, y, category, colors = col2rgb(viridis(nlevels(as.factor(data[[category]])))), ...) { 
    # Create Plotly scatter plot of x vs y, with separate lines for each level of the categorical variable. 
    # In other words, create an interaction scatter plot. 
    # The "colors" must be supplied in a RGB triplet, as produced by col2rgb(). 

    require(plotly) 
    require(viridis) 
    require(broom) 

    groups <- unique(data[[category]]) 

    p <- plot_ly(...) 

    for (i in 1:length(groups)) { 
    groupData = data[which(data[[category]]==groups[[i]]), ] 
    p <- add_lines(p, data = groupData, 
        y = fitted(lm(data = groupData, groupData[[y]] ~ groupData[[x]])), 
        x = groupData[[x]], 
        line = list(color = paste('rgb', '(', paste(colors[, i], collapse = ", "), ')')), 
        name = groups[[i]], 
        showlegend = FALSE) 
    p <- add_ribbons(p, data = augment(lm(data = groupData, groupData[[y]] ~ groupData[[x]])), 
        y = groupData[[y]], 
        x = groupData[[x]], 
        ymin = ~.fitted - 1.96 * .se.fit, 
        ymax = ~.fitted + 1.96 * .se.fit, 
        line = list(color = paste('rgba','(', paste(colors[, i], collapse = ", "), ', 0.05)')), 
        fillcolor = paste('rgba', '(', paste(colors[, i], collapse = ", "), ', 0.1)'), 
        showlegend = FALSE) 
    p <- add_markers(p, data = groupData, 
        x = groupData[[x]], 
        y = groupData[[y]], 
        symbol = groupData[[category]], 
        marker = list(color=paste('rgb','(', paste(colors[, i], collapse = ", ")))) 
    } 
    p <- layout(p, xaxis = list(title = x), yaxis = list(title = y)) 
    return(p) 
} 
関連する問題