I am trying to create (in plotly
) a scatterplot which distinguishes the points of the same series by two (or three) aesthetics -- color, shape, size. Ultimately
Unfortunately, plotly does not give this behaviour automatically. But, it can be done simply enough by specifying the colour, shape, and size of each point individually -- using the colors =
, size =
, and symbols =
arguments. This allows control over how the points are plotted, but does not get the legend you want. So we use showlegend = FALSE
in the main plot and construct the legend by adding three more (invisible) traces that are only there to generate the legend items.
Note that there is one more trick we need to apply here. To get a legend showing colours or sizes, you can use the argument visible = "legendonly"
which creates a legend entry without over-plotting extra points on the graph. BUT this does not work with shapes. Combining visible = "legendonly"
with symbols =
seems to have a bug that puts the wrong items in the legend. So, to create the legend entries for shapes, you can plot them at a location far out in the stratosphere where they will never be visible (here I used x=y=1e6) and set the x and y axis limits to keep these out of view.
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)))