Skip to content

Bug of Scatter3D plots for only one point with multilevel? #576

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Closed
BoyaoZhang opened this issue May 8, 2016 · 9 comments
Closed

Bug of Scatter3D plots for only one point with multilevel? #576

BoyaoZhang opened this issue May 8, 2016 · 9 comments

Comments

@BoyaoZhang
Copy link

plot_ly(x = iris[1,1], y = iris[1,2], z = iris[1,3], type = "scatter3d", symbol = iris[1,5])
rplot

@kcf-jackson
Copy link

I think the issue is that you supplied a factor to 'symbol'. Using characters string instead would fix the issue.
plot_ly(x = iris[1,1], y = iris[1,2], z = iris[1,3], type = "scatter3d", symbol = as.character(iris[1,5]))
image

@BoyaoZhang
Copy link
Author

In fact I want to perform a machine learning algorithm on the iris data. According to the result, some points may be incorrect predicted. And I want to figure out this kind of points. For example, if the first data is miss-classified, I still want to have the same symbol shape, just want to change the color. Like this,

iris_without1 = iris[-1,]
iris_1 = iris[1,]
p = plot_ly(x = iris_without1[,1], y = iris_without1[,2], z = iris_without1[,3],
            type = "scatter3d", symbol = iris_without1[,5], marker = list(size = 3))
add_trace(p, x = iris_1[,1], y = iris_1[,2], z = iris_1[,3],
          type = "scatter3d", symbol = iris_1[,5], 
          marker = list(size = 3, color = "black"))

rplot01

You can see the square-shaped black point (miss-classified) in setosa group. This is in fact what I want in the end.

But I don't want to change it by giving a symbol name, I hope it perform automatically.

@kcf-jackson
Copy link

If you want to remove the legend of the black dot, simply add "showlegend = FALSE" in the "add_trace" call.

iris_without1 = iris[-1,]
iris_1 = iris[1,]
p = plot_ly(x = iris_without1[,1], y = iris_without1[,2], z = iris_without1[,3],
            type = "scatter3d", symbol = as.character(iris_without1[,5]), marker = list(size = 3))
add_trace(p, x = iris_1[,1], y = iris_1[,2], z = iris_1[,3],
          type = "scatter3d", symbol = as.character(iris_1[,5]), 
          marker = list(size = 5, color = "black"), showlegend = FALSE)

image

I think your questions are not development related, perhaps you could consider asking them in stackoverflow instead.

@BoyaoZhang
Copy link
Author

Sorry I asked here, but I still believe it must be a bug for single point with multi levels.
I think I chose a bad example, if I choose the 70th observation which belongs to versicolor. In the plot it should be a cross, but with as.character function it resolves as circle.

iris_without1 = iris[-70,]
iris_1 = iris[70,]
p = plot_ly(x = iris_without1[,1], y = iris_without1[,2], z = iris_without1[,3],
            type = "scatter3d", symbol = as.character(iris_without1[,5]), 
            marker = list(size = 3))
add_trace(p, x = iris_1[,1], y = iris_1[,2], z = iris_1[,3],
          type = "scatter3d", symbol = as.character(iris_1[,5]), 
          marker = list(size = 5, color = "black"), showlegend = FALSE)

rplot03

@kcf-jackson
Copy link

As far as I see, plotly is doing exactly what you instructed it to do. Here is my understanding.

  1. Plotly treats the data in 'add_trace' independently of the data you use in 'plot_ly', hence plotly produces two sets of symbols.
  2. In 'add_trace', the data only has 1 point, the default 'circle' symbol is used.

To solve your problem, I thought about using 'as.numeric' instead of 'as.character', but somehow plotly doesn't convert the numbers according to https://plot.ly/r/reference/#box-marker-symbol.
Though a simple fix can be found as follows:

data(iris)
symbol_3set <- c("circle", "cross", "square")

iris_without1 = iris[-70,]
iris_1 = iris[70,]
plot_ly(data = iris_without1, x = Sepal.Length, y = Sepal.Width, z = Petal.Length,
            type = "scatter3d", mode = "markers", color = Species,
            marker = list(size = 3, symbol = symbol_3set[as.numeric(Species)]))
add_trace(data = iris_1, x = Sepal.Length, y = Sepal.Width, z = Petal.Length,
          type = "scatter3d", mode = "markers", 
          marker = list(size = 5, color = "black", symbol = symbol_3set[as.numeric(Species)]), 
          showlegend = FALSE)

image

@BoyaoZhang
Copy link
Author

I must thank you for your patient. It goes very close to the end version which I want.
You know, iris is a very simple example. If I change the data set which has a lot of different levels, do you mean I should always type all the symbol names?
Why plotly couldn't convert the numeric symbol values? In https://plot.ly/r/reference/#box-marker-symbol, the symbols are coded both for character and for numeric, aren't they?
In the following example, we can easily see the legend symbols are correct coded.

test = iris[c(1, 2, 51, 52, 101, 102),]
plot_ly(x = test$Sepal.Length, y = test$Sepal.Width, z = test$Petal.Length,
        type = "scatter3d", mode = "markers", color = test$Species,
        marker = list(symbol = c(1,1,2,2,3,3)))

rplot

@kcf-jackson
Copy link

One uses colours if there are many levels as plotly only supports up to 8 symbols as far as I know.
And according to the documentation in the source code,

#' @param symbol Either a variable name or a (discrete) vector to use for symbol encoding.
#' @param symbols A character vector of symbol types. Possible values:
#' 'dot', 'cross', 'diamond', 'square', 'triangle-down', 'triangle-left', 'triangle-right', 'triangle-up' 

there is no mention of allowing numeric encoding of symbols. The reference is possibly outdated.

@BoyaoZhang
Copy link
Author

I have run the following code to test these symbols, but any code couldn't generate the correct answer.

test = iris
test$Species = sample(1:8, 150, replace = T)
test$Species = as.factor(test$Species)

One can find in the legend labels that there are only 4 symbols

plot_ly(x = test$Sepal.Length, y = test$Sepal.Width, z = test$Petal.Length,
        type = "scatter3d", mode = "markers", symbol = test$Species)

rplot

If I put the symbol parameter into the marker list, the symbols in the legend displays correctly, but none of the point are really with the symbol converted.

plot_ly(x = test$Sepal.Length, y = test$Sepal.Width, z = test$Petal.Length,
        type = "scatter3d", mode = "markers", color = test$Species,
        marker = list(symbol = as.numeric(test$Species)))

rplot01

Now I added the symbolset into the function. The output is almost same with the first plot but the incorrect legend labels.

symbolset = c('dot', 'cross', 'diamond', 'square', 'triangle-down', 'triangle-left', 'triangle-right', 'triangle-up')

plot_ly(x = test$Sepal.Length, y = test$Sepal.Width, z = test$Petal.Length,
        type = "scatter3d", mode = "markers",
        symbol = symbolset[as.numeric(test$Species)])

rplot02

Finally, the following code convert some points correctly, but some not. You can see, the triangle and dot symbols don't work. If I replace the symbol "dot" with the name "circle", than it works well for "circle". What is wrong with the outrageously symbols?

plot_ly(x = test$Sepal.Length, y = test$Sepal.Width, z = test$Petal.Length,
        type = "scatter3d", mode = "markers", color = test$Species,
        marker = list(symbol = symbolset[as.numeric(test$Species)]))

rplot03
rplot04

@cpsievert
Copy link
Collaborator

pretty sure this is a duplicate of #577

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

3 participants