Comment appliquer simultanément couleur/forme / taille dans un nuage de points en utilisant plotly?

je suis en train de créer (dans plotly) un scatterplot qui distingue les points de la même série par deux (ou trois) esthétiques -- couleur, forme, taille. En fin de compte, l'objectif est de pouvoir basculer des groupes de points sur/hors via la légende, en utilisant l'une des trois esthétiques. Cela fonctionne bien pour une esthétique.

[Ajouté 2016-06-20] pour développer le comportement interactif souhaité: l'idée est, une fois la figure montrée, de pouvoir basculer des groupes de des points en cliquant sur l'une des légendes. Par exemple (dans l'échantillon de données ci-dessous), si je devais cliquer sur y dans la légende, elle cacherait/montrerait les points #4, 5 et 10 de toutes les séries. S'il y a un clic sur A, puis basculer les points 1, 2 et 8. Comme un cas d'utilisation réelle-pensez aux prix des obligations, avec maturité sur l'axe horizontal et prix sur la verticale. Les obligations se caractérisent par le pays d'origine, la cote de crédit et la taille de l'émission. Donc, si je clique sur, disons, la cote de crédit "A", je voudrais que tous les a-noté questions, indépendamment de la taille et du pays d'origine, pour être caché. Actuellement, ils sont seulement cachés de la trace liée à la notation. Les points dans les traces qui reflètent les autres attributs (taille & pays) restent représentés. Compte tenu de la réponse détaillée ci-dessous, je suis enclin à poster ceci comme une requête de fonctionnalité sur plotly's site.

j'ai encadré la question pour plotly, mais si ce comportement peut être atteint dans un autre paquet/bibliothèque à partir de R avec des niveaux de douleur relativement faibles (ce qui signifie pas de Javascript personnalisé ou similaire), Je l'accepte comme une réponse aussi. [fin edit]

La partie statique se fait facilement en ggplot2 mais je ne peux pas recréer dans plotly (pour l'interactivité), même en utilisant ggplotly(). Je ne sais pas si c'est possible, mais j'ai pensé demander. Exemple de données et de code ci-dessous.

(possiblement lié à en utilisant 2 + legends de R à plotly / plot.ly)

Générer de mannequin données:

library(data.table)
library(plotly)
library(ggplot2)


DT <- data.table(
    x = c(1:10), y = 1:10/2,
    gr1 = c("A", "A", "B", "C", "D", "D", "B", "A", "E", "E"),
    gr2 = c("x", "x", "x", "y", "y", "z", "z", "x", "x", "y"),
    gr3 = c(1,2,2,1,3,4,1,2,2,1)
)

ggplot() version ressemble à cela, et c'est ce que j'aimerais entrer en plotly:

p <- ggplot(data = DT) + geom_point(aes(x = x, y = y, color = gr1, shape = gr2, size = gr3))
p

il y a trois groupes de critères dans la légende, et les points ont une couleur, une forme et une taille variables. ggplot version

appel ggplotly(p) génère un tas d'Avertissements:

Warning messages:
1: In if (s == Inf) { :
  the condition has length > 1 and only the first element will be used
2: In if (s == Inf) { :
  the condition has length > 1 and only the first element will be used
3: In if (s == Inf) { :
  the condition has length > 1 and only the first element will be used
4: In if (s == Inf) { :
  the condition has length > 1 and only the first element will be used
5: In if (s == Inf) { :
  the condition has length > 1 and only the first element will be used
6: In if (s == Inf) { :
  the condition has length > 1 and only the first element will be used
7: In if (s == Inf) { :
  the condition has length > 1 and only the first element will be used
8: In if (s == Inf) { :
  the condition has length > 1 and only the first element will be used

et produit ce chiffre:

ggplotly version

essayer d'utiliser plot_ly(), j'obtiens le code suivant:

plot_ly(data = DT, x = x, y = y, color = gr1, symbol = gr2, type = "scatter", mode = "markers", marker = list(size = 10 * gr3)) # size is multiplied by 10, in plotly it is in pixels

plot_ly version

le problème est le plus évident au milieu de la figure -- au lieu d'une croix colorée, il y a plusieurs formes de différentes couleurs superposées les unes sur les autres. Puisqu'il s'agit d'un point unique, je m'attends à une forme d'une seule couleur, comme dans ggplot. Dans plotly, les arguments' color',' symbol 'et' size ' créent-ils une nouvelle trace?

je suis tout nouveau plotly, donc je peut-être manque quelque chose d'évident.

Le dessus est fait à l'aide de R 3.2.2 sous Windows, avec plotly_2.0.16 et ggplot2_2.0.0.

13
demandé sur Peter 2016-01-04 01:55:50

1 réponses

Malheureusement, plotly ne donne pas ce comportement automatiquement. Mais, cela peut être fait assez simplement en spécifiant la couleur, la forme et la taille de chaque point individuellement -- en utilisant le colors =,size = et symbols = arguments. Cela permet de contrôler la façon dont les points sont tracés, mais n'obtient pas la légende que vous voulez. Nous avons donc utiliser showlegend = FALSE dans l'intrigue principale et construire la légende en ajoutant trois traces (invisibles) qui ne sont là que pour générer la légende article.

notez Qu'il y a encore une astuce que nous devons appliquer ici. Pour obtenir une légende indiquant les couleurs ou les tailles, vous pouvez utiliser l'argument visible = "legendonly" qui crée une entrée de légende sans surligner les points supplémentaires sur le graphique. MAIS cela ne fonctionne pas avec les formes. Combinant visible = "legendonly"symbols = semble avoir un bug qui met les mauvais éléments dans la légende. Ainsi, pour créer les entrées de légende pour les formes, vous pouvez les reporter à un endroit loin dans la stratosphère où ils ne seront jamais visible (ici j'ai utilisé x=y=1E6) et défini les limites des axes x et y pour les garder hors de vue.

DT <- data.table(
  x = c(1:10), y = 1:10/2,
  gr1 = as.factor(c("A", "A", "B", "C", "D", "D", "B", "A", "E", "E")),
  gr2 = as.factor(c("x", "x", "x", "y", "y", "z", "z", "x", "x", "y")),
  gr3 = c(1,2,2,1,3,4,1,2,2,1)
)
shapes <- c("circle", "square", "diamond","cross", "x","square-open","circle-open","diamond-open")
DT$shapes <- shapes[DT$gr1]
DT$col <- rainbow(3)[DT$gr2]
DT$size <- DT$gr3*10

plot_ly() %>%
  add_trace(data = DT, x = x, y = y, type = "scatter", mode = "markers", 
            color=gr2, colors=col,
            marker = list(size = size, symbol=shapes), showlegend=F) %>%
  add_trace(data = DT, x = x, y = y, type = "scatter",mode = "markers", 
            color= factor(gr2), colors=col, 
            visible="legendonly", showlegend=T, legendgroup="color",
            marker = list(size = 14)) %>%
  add_trace(data = DT, x = x, y = y, type = "scatter",mode = "markers", 
            color=factor(gr3), colors="#000000", 
            marker = list(size = size),
            visible="legendonly", showlegend=T, legendgroup="size") %>%
  add_trace(data = DT, x = 1e6, y = 1e6, type = "scatter", mode = "markers", 
            color=factor(gr1), colors="#000000", 
            marker = list(size=14, symbol=shapes),
            showlegend=T, legendgroup="shape") %>%
  layout(legend=list(traceorder="grouped+reversed", tracegroupgap =30),
         xaxis=list(range=c(0,12)),
         yaxis=list(range=c(0,6)))

enter image description here

5
répondu dww 2016-06-20 15:07:43