Related
I want to represent 2D vectors rooted at the origin with plotly in R. Moreover, I want to color the vector based on a categorical variable. The problem is that I can either create the lines color-coded but without the arrow head:
library(plotly)
library(dplyr)
v <- c(1, 1)
b1 <- c(1, 0)
b2 <- c(0, 1)
df <- data.frame(
x = c(v[1], b1[1], b2[1]),
y = c(v[2], b1[2], b2[2]),
is_basis = c(FALSE, TRUE, TRUE)
)
df %>%
plot_ly(x = ~x, y = ~y, color = ~is_basis) %>%
add_segments(xend = ~x, yend = ~y, x = 0, y = 0, colors = c("red","black"))
Or with the arrow-head but not color-coded:
df %>%
plot_ly(x = ~x, y = ~y, color = ~is_basis) %>%
add_annotations(x = ~x, y = ~y, showarrow = TRUE, text = "", ax = 0, ay = 0,
axref = "x", ayref = "y", xref = "x", yref = "y")
So, my question is: Can I add an arrow head with add_segments? Or, can I style and color the arrows generated with add_annotations?
You can chose arrowhead and set the color of the arrow through the arguments arrowhead and arrowcolor in the function add_annotations(). If you set axref = "x" and ayref = "y" you also make sure that the lines start at origo if you set ax and ay to 0.
Here's an example using a subset of the built-in dataset mtcars:
Complete code:
library(plotly)
library(dplyr)
data <- mtcars[which(mtcars$am == 1 & mtcars$gear == 4),]
#data <- data %>% filter(row.names(data) %in% c("Honda Civic", "Fiat X1-9", "Datsun 710"))
#row.names(data) <- c("Honda Civic", "Fiat X1-9", "Datsun 710")
p <- plot_ly(data, x = ~wt, y = ~mpg, type = 'scatter', mode = 'markers',
marker = list(size = 2)) #%>%
p <- p %>%
add_annotations(x = data["Honda Civic","wt"],
y = data["Honda Civic","mpg"],
text = "",
xref = "x",
yref = "y",
showarrow = TRUE,
arrowcolor='blue',
arrowhead = 1,
arrowsize = 2,
ax = 0,
ay = 0,
axref="x",
ayref='y',
font = list(color = '#264E86',
family = 'sans serif',
size = 14))
p <- p %>%
add_annotations(x = data["Fiat X1-9","wt"],
y = data["Fiat X1-9","mpg"],
text = "",
xref = "x",
yref = "y",
showarrow = TRUE,
arrowcolor='green',
arrowhead = 2,
arrowsize = 2,
ax = 0,
ay = 0,
axref="x",
ayref='y',
font = list(color = '#264E86',
family = 'sans serif',
size = 14))
p <- p %>%
add_annotations(x = data["Datsun 710","wt"],
y = data["Datsun 710","mpg"],
text = "",
xref = "x",
yref = "y",
showarrow = TRUE,
arrowcolor='red',
arrowhead = 3,
arrowsize = 2,
ax = 0,
ay = 0,
axref="x",
ayref='y',
font = list(color = '#264E86',
family = 'sans serif',
size = 14))
p <- p %>%
add_annotations(x = data["Fiat 128","wt"],
y = data["Fiat 128","mpg"],
text = "",
xref = "x",
yref = "y",
showarrow = TRUE,
arrowcolor='black',
arrowhead = 4,
arrowsize = 2,
ax = 0,
ay = 0,
axref="x",
ayref='y',
font = list(color = '#264E86',
family = 'sans serif',
size = 14))
p <- p %>%
add_annotations(x = data["Mazda RX4 Wag","wt"],
y = data["Mazda RX4 Wag","mpg"],
text = "",
xref = "x",
yref = "y",
showarrow = TRUE,
arrowcolor='purple',
arrowhead = 5,
arrowsize = 2,
ax = 0,
ay = 0,
axref="x",
ayref='y',
font = list(color = '#264E86',
family = 'sans serif',
size = 14))
p <- p %>%
add_annotations(x = data["Volvo 142E","wt"],
y = data["Volvo 142E","mpg"],
text = "",
xref = "x",
yref = "y",
showarrow = TRUE,
arrowcolor='grey',
arrowhead = 6,
arrowsize = 2,
ax = 0,
ay = 0,
axref="x",
ayref='y',
font = list(color = '#264E86',
family = 'sans serif',
size = 14))
p <- p %>%
add_annotations(x = data["Toyota Corolla","wt"],
y = data["Toyota Corolla","mpg"],
text = "",
xref = "x",
yref = "y",
showarrow = TRUE,
arrowcolor='aquamarine',
arrowhead = 7,
arrowsize = 2,
ax = 0,
ay = 0,
axref="x",
ayref='y',
font = list(color = '#264E86',
family = 'sans serif',
size = 14))
p
I am stuck with the following plotly example which I would like to exploit:
library(plotly)
p <- plot_ly(economics, x = ~date, y = ~uempmed, name = "unemployment")
# add shapes to the layout
p <- layout(p, title = 'Highlighting with Rectangles',
shapes = list(
list(type = "rect",
fillcolor = "blue", line = list(color = "blue"), opacity = 0.3,
x0 = "1980-01-01", x1 = "1985-01-01", xref = "x",
y0 = 4, y1 = 12.5, yref = "y"),
list(type = "rect",
fillcolor = "blue", line = list(color = "blue"), opacity = 0.2,
x0 = "2000-01-01", x1 = "2005-01-01", xref = "x",
y0 = 4, y1 = 12.5, yref = "y")))
How can I include hover information for those rectangles? Neither of the following works:
layout(p, title = 'Highlighting with Rectangles',
shapes = list(
list(type = "rect",
fillcolor = "blue", line = list(color = "blue"), opacity = 0.3,
x0 = "1980-01-01", x1 = "1985-01-01", xref = "x",
# text - hoverinfo pair
text = "hello", hoverinfo = "text",
y0 = 4, y1 = 12.5, yref = "y"),
list(type = "rect",
fillcolor = "blue", line = list(color = "blue"), opacity = 0.2,
x0 = "2000-01-01", x1 = "2005-01-01", xref = "x",
# hovertext
hovertext = "good bye",
y0 = 4, y1 = 12.5, yref = "y")))
Is there any way how I can plot rectangles in plotly and apply a hover to them. Unfortunately, at least as I am aware of, there is no type = "rect" or anything like that available in R.
You can do it by adding polygons instead of shapes. Look below;
library(plotly)
plot_ly() %>%
add_polygons(x=c(as.Date("1980-01-01"), as.Date("1980-01-01"),
as.Date("1985-01-01"), as.Date("1985-01-01")),
y=c(4, 12.5, 12.5, 4),
line=list(width=0),
fillcolor='rgba(255, 212, 96, 0.5)', inherit = FALSE,
name = 'Hello') %>%
add_polygons(x=c(as.Date("2000-01-01"), as.Date("2000-01-01"),
as.Date("2005-01-01"), as.Date("2005-01-01")),
y=c(4, 12.5, 12.5, 4),
line=list(width=0),
fillcolor='rgba(255, 212, 96, 0.5)', inherit = FALSE,
name = 'Bye') %>%
add_markers(data = economics, x = ~date, y = ~uempmed, name = "unemployment")
Let's say, I have a simple polar chart:
R code:
library(plotly)
p <- plot_ly(
type = 'scatterpolar',
r = c(0,1,2,4),
theta = c(0,45,90,120),
size = c(10, 20, 30, 40),
sizes = c(100, 300),
mode = 'markers'
) %>%
layout(
showlegend = FALSE,
polar = list(
angularaxis = list(
showticklabels = TRUE#,
#tickmode="array",
#tickvals = c(22.5, 67.5, 112, 157.5, 202, 247.5, 292, 337.5),
#ticktext = c('A', "B", "C", "D", "E", "F", "G", "H")
),
radialaxis = list(
tickmode="array",
tickvals = c(0, 1, 2, 3, 4, 5, 6, 7),
ticktext = c('', "One", "Two", "Three", "Four", "Five", "Six", "Seven")
)
)
)
ggplotly(p)
Chart plotted:
When I set showticklabels = FALSE, the angle tick labels disappears, and then I want to put A,B,C,D,E,F,G and H at angles c(22.5, 67.5, 112, 157.5, 202, 247.5, 292, 337.5).
I am not able to get the below expected plot using ticktexts and tickvals.
Can someone please help me with getting me to the solution, or if it is possible with add_text or add_annotation ?
Expected plot:
you could remove all grid lines altogether in the angularaxis with showgrid = FALSE, or you can have a line per 22.5 degree starting from 0 and then the ticktext would be something like this c('', 'A', '', 'B', '', 'C', .......) , or you could tediously add the lines you expect to have and then remove the grid lines like this:
p <- plot_ly() %>%
# data points
add_trace(type = 'scatterpolar',
r = c(0,1,2,4),
theta = c(0,45,90,120),
size = c(10, 20, 30, 40),
sizes = c(100, 300),
mode = 'markers') %>%
# straight line from 0 dg to 180 dg
add_trace(type = 'scatterpolar',
r = c(0,4.3,4.3),
theta = c(0, 180, 360),
mode = 'lines',
line = list(color = 'grey', width = 1)) %>%
# straight line from 45 dg to 225 dg
add_trace(type = 'scatterpolar',
r = c(0,4.3,4.3),
theta = c(0, 45, 225),
mode = 'lines',
line = list(color = 'grey', width = 1)) %>%
# straight line from 90 dg to 270 dg
add_trace(type = 'scatterpolar',
r = c(0,4.3,4.3),
theta = c(0, 90, 270),
mode = 'lines',
line = list(color = 'grey', width = 1)) %>%
# straight line from 135 dg to 315 dg
add_trace(type = 'scatterpolar',
r = c(0,4.3,4.3),
theta = c(0, 135, 315),
mode = 'lines',
line = list(color = 'grey', width = 1)) %>%
# fill circle of radius 1
add_trace(type = 'scatterpolar',
mode = 'lines',
r = 1,
theta =seq(0, 360, 0.1),
line = list(color = 'grey'),
fill = 'toself',
fillcolor = 'grey',
opacity = 0.5) %>%
layout(
showlegend = FALSE,
polar = list(
angularaxis = list(
showticklabels = TRUE,
# remove grid lines and ticks
showgrid = FALSE,
ticks = '',
# if you want the axis to go the other way around
# direction = 'clockwise',
tickmode="array",
tickvals = seq(22.5, 337.5, 45),
ticktext = LETTERS[1:8]
),
radialaxis = list(
tickmode="array",
tickvals = c(0, 1, 2, 3, 4, 5, 6, 7),
ticktext = c('', "One", "Two", "Three", "Four", "Five", "Six", "Seven")
)
)
)
ggplotly(p)
Output chart:
I noticed that the expected output you have there, lists the letters the other way around as you have them in your code. If this is something you also want just change the order of the letters to match the angles like this c("A", "H", "G", "F", "E", "D", "C", "B") (reversed order starting from A)
I encountered a problem while using plotly and R shiny to visualize data. My sample codes are:
y <- c("q1", "q2", "q3", "q4", "q5", "q6", "q7")
x1 <- c(20, 10, 15, 15, 20, 10, 15)
x2 <- c(10, 20, 20, 10, 10, 30, 10)
x3 <- c(10, 10, 5, 10, 10, 5, 5)
x4 <- c(20, 25, 25, 35, 55, 40, 35)
x5 <- c(40, 35, 35, 30, 5, 15, 35)
num <- c(1,3,5,6,7,2,4)
df <- data.frame(y, x1, x2, x3, x4, x5, num)
plot_ly(df[order(-xtfrm(df$num)),]) %>%
add_trace(x = ~x1, y = ~y, marker = list(color = 'rgb(202,0,32)'), type = 'bar', orientation = 'h') %>%
add_trace(x = ~x2, y = ~y, marker = list(color = 'rgb(244,165,130)'), type = 'bar', orientation = 'h') %>%
add_trace(x = ~x3, y = ~y, marker = list(color = 'rgb(223,223,223)'), type = 'bar', orientation = 'h') %>%
add_trace(x = ~x4, y = ~y, marker = list(color = 'rgb(146,197,222)'), type = 'bar', orientation = 'h') %>%
add_trace(x = ~x5, y = ~y, marker = list(color = 'rgb(5,113,176)'), type = 'bar', orientation = 'h') %>%
layout(title="mytitle",
xaxis = list(title = "",
showticklabels = TRUE,
zeroline = FALSE,
domain = c(0.15, 1)),
yaxis = list(title = "",
showticklabels = FALSE,
zeroline = FALSE,
categoryorder = 'array',
categoryarray = ~qt),
barmode = 'relative',
paper_bgcolor = 'rgb(248, 248, 255)', plot_bgcolor = 'rgb(248, 248, 255)',
autosize=T,
margin = list(l = 150, r = 10, t = 100, b = 50, pad=4),
showlegend=F) %>%
# labeling the y-axis
add_annotations(xref = 'paper', yref = 'y', x = 0.14, y = df$y,
xanchor = 'right',
text = df$y,
font = list(family = 'Arial', size = 5,
color = 'rgb(67, 67, 67)'),
showarrow = FALSE, align = 'right')
The problem is that the margins does not work very well with large amount of questions. In my data, one of the categories includes more than 40 questions. The plot with 5 questions looks fine. (length=500)
But the plot with over 40 questions have big top and bottom margins. (length=4000)
Please help me get rid of these weird margins.
Also, I'd like to know how to put the x-axis on both the top and bottom of the plot. Thank you!
I'm looking for a way to sort my plotly bar plot by yaxis alphabetically. I tried several ways but the order of y is still from z to a, instead of a to z. Please help me out!
qt <- c("A", "C", "B","B","A", "C", "C")
y <- c("q1", "q2", "q3", "q4", "q5", "q6", "q7")
x1 <- c(20, 10, 15, 15, 20, 10, 15)
x2 <- c(10, 20, 20, 10, 10, 30, 10)
x3 <- c(10, 10, 5, 10, 10, 5, 5)
x4 <- c(20, 25, 25, 35, 55, 40, 35)
x5 <- c(40, 35, 35, 30, 5, 15, 35)
df <- data.frame(qt, y, x1, x2, x3, x4, x5)
df$qt <- factor(df$qt, levels = c("A", "B", "C"))
plot_ly(df) %>%
add_trace(x = ~x1, y = ~y, marker = list(color = 'rgb(202,0,32)'), type = 'bar', orientation = 'h') %>%
add_trace(x = ~x2, y = ~y, marker = list(color = 'rgb(244,165,130)'), type = 'bar', orientation = 'h') %>%
add_trace(x = ~x3, y = ~y, marker = list(color = 'rgb(223,223,223)'), type = 'bar', orientation = 'h') %>%
add_trace(x = ~x4, y = ~y, marker = list(color = 'rgb(146,197,222)'), type = 'bar', orientation = 'h') %>%
add_trace(x = ~x5, y = ~y, marker = list(color = 'rgb(5,113,176)'), type = 'bar', orientation = 'h') %>%
layout(title="mytitle",
xaxis = list(title = "",
showticklabels = TRUE,
zeroline = FALSE,
domain = c(0.15, 1)),
yaxis = list(title = "",
showticklabels = FALSE,
zeroline = FALSE),
barmode = 'relative',
paper_bgcolor = 'rgb(248, 248, 255)', plot_bgcolor = 'rgb(248, 248, 255)',
autosize=T,
margin = list(l = 150, r = 50, t = 100, b = 50),
showlegend=F) %>%
# labeling the y-axis
add_annotations(xref = 'paper', yref = 'y', x = 0.14, y = df$y,
xanchor = 'right',
text = df$y,
font = list(family = 'Arial', size = 15,
color = 'rgb(67, 67, 67)'),
showarrow = FALSE, align = 'right')%>%
#labeling the y-axis (category)
add_annotations(xref = 'paper', yref = 'qt', x = 0.01, y = df$y,
xanchor = 'right',
text = df$qt,
font = list(family = 'Arial', size = 15,
color = 'rgb(67, 67, 67)'),
showarrow = FALSE, align = 'right')
The primary goal I would like to accomplish is to order this by the variable qt (from A to C). But if this is impossible, ordering the plot by y is also desirable (from q1 to q7). My plot looks like this:
Thank you in advance!