Here is some example code I wrote to illustrate my problem. Right now, the plot generates only the points. What I want to do is have horizontal lines that go through each point, spanning a length of 1 to each side. (i.e. for a point at (2,1) I want the line to run from (1,1) to (3,1)) How can I do this in plotly? I've looked here but can't seem to figure out how to get this to work when the y-axis is not numerical.
library(plotly)
p <- plot_ly(data = mtcars, x = ~mtcars$mpg, y = rownames(mtcars), type = 'scatter', mode = 'markers')
p
EDIT is the output from the code provided in the accepted answer (except showing all car names). I was wondering if there is a way to draw a horizontal line between each y-axis label, so that for example, between "Volvo 142E" and "Maserati Bora", a line separates them, and goes for the length of the plot. Right now, each horizontal line of the plot has a point on it. I want to separate each of those lines with another line.
To get this to work we had to replot the original scatter plot with an using the row index to prevent plotly from reordering cars. Then I added back to the axis labels.
library(plotly)
##I added the text argument(hover over text) so that I could make sure
##that the yaxis labels matched the points. feel free to delete.
p <- plot_ly(x = mtcars$mpg, y = seq_along(rownames(mtcars)), text=rownames(mtcars),
type = 'scatter', mode = 'markers')
##This sets some attributes for the yaxis. Note: in your origianl plot every other
##car name was shown on the y-axis so that is what I recreated but you could remove
##the "seq(1,32, by=2)" to show all car names.
ax <- list(
title = "",
ticktext = rownames(mtcars)[seq(1,32, by=2)],
tickvals = seq(1,32, by=2)
)
##This is taken from the plotly help page. y0 and y1 now are set to equal the row
##number and x0 and x1 are +/-1 from the car's mpg
line <- list(
type = "line",
line = list(color = "pink"),
xref = "x",
yref = "y"
)
lines <- list()
for (i in seq_along(rownames(mtcars))) {
line[["x0"]] <- mtcars$mpg[i] - 1
line[["x1"]] <- mtcars$mpg[i] + 1
line[c("y0", "y1")] <- i
lines <- c(lines, list(line))
}
p <- layout(p, title = 'Highlighting with Lines', shapes = lines, yaxis=ax)
p
Update based on OP's request.
To underline text in plotly use HTML tags. But <u> </u> does not work so we have to use <span> </span>...
ax2 <- list(
title = "", ticktext = paste0('<span style="text-decoration: underline;">',
rownames(mtcars)[1:32 %% 2 ==0],"</span>"),
tickvals = seq(1,32, by=2), style=list(textDecoration="underline"))
Related
I'm trying to use R plotly's bar type plot to generate a plot with horizontally laid out boxes and add to that a horizontal line which is in their background (rather than goes on top of them). In addition, I would like the line to extend symmetrically one box unit in each direction.
Here's what I'm doing:
plot.df <- data.frame(x = paste0("LONG NAME ",1:6),y = 0.2,width=0.75,group = c("A","B","B","B","C","A"),stringsAsFactors = F)
plot.df$group <- factor(plot.df$group)
plotly::plot_ly(plot.df) %>%
plotly::add_trace(x=~x,y=~y/2,type='scatter',mode='lines',line=list(color='black'),showlegend=F) %>%
plotly::add_bars(x=~x,y=~y,width=~width,color=~group) %>%
plotly::layout(xaxis=list(title=NA,zeroline=F,tickangle=45),yaxis=list(title=NA,zeroline=F,showgrid=F,range=c(0,1),showticklabels=F))
Which gives:
My questions are:
How to extend the the line in both directions
How to put the line in the background so it does not run over the boxes
I specified plot.df$y as 0.2 but the yaxis range to be c(0,1) so that the boxes don't look like long bars. But then the legend appears too high. Any better way to get square boxes with the legend appearing lower than it currently is?
For the horizontal line you can see Horizontal/Vertical Line in plotly
with
layout(legend =list(x = 1 ,y =0 ))
you can solve the legend problem
I could not solve your second point (put the bar in the background). I hope it helps:
hline <- function(y = 0, color = "blue") {
list(
type = "line",
x0 = 0,
x1 = 1,
xref = "paper",
y0 = y,
y1 = y,
line = list(color = color)
)
}
plot_ly(plot.df) %>%
add_bars(x=~x,y=~y,width=~width,color=~group, hoverinfo = "text") %>%
layout(shapes = list(hline(0.1)))%>%
layout(legend =list(x = 1 ,y =0 ))%>%
layout(xaxis=list(title=NA,zeroline=F,tickangle=45),yaxis=list(title=NA,zeroline=F,showgrid=F,range=c(0,1),showticklabels=F))
I'm trying to write the symbol degrees celsius with R/Plotly in one of my titles. It works when I just use a simple plot a below:
# Working code
library(latex2exp)
set.seed(1)
betas <- rnorm(1000)
hist(betas, main = TeX("Temperature (^0C)"))
However, when I try to run the code through plotly, I get the following error: "unimplemented type 'expression' in 'HashTableSetup'".
#Initialise the plot
p <- plot_ly()
#Add axis names
#Font
f <- list(
family = "Courier New, monospace",
size = 18,
color = "#7f7f7f")
#X axis name
x <- list(
title = "x Axis",
titlefont = f)
#Y Axis name
y <- list(
title = TeX("Temperature (^0C)"),
titlefont = f)
#Add layout
p <- p %>%
layout(xaxis = x, yaxis= y)
p
Any ideas?
Try,
title = "Temperature (\u00B0C)"
Try title = expression("Temperature ("*~degree*C*")") or title = "Temperature (°C)"
I just found a hacky solution: Look for the special character on google and copy and paste it directly in the R code.
#Y Axis name
y <- list(
title = "Temperature (°C)",
titlefont = f)
I'm still interested in a less hacky solution which allows to insert LaTeX into Plotly.
I have created subplots in Plotly that each contain a bar chart (or boxplot) and three trace lines. I have created traces at y= 1,2,3 to act as ablines like in ggplot.
What the plots look like:
and
.
Problem:
I want to have it so the bars of the bar chart are in front of the trace lines so you should only be able to see the trace lines in between the bars.
My code currently:
(I have excluded the code that generates the subplots as I don't think it is needed)
generate_plotly_barPlot <- function(dat, showLeg, err) {
p <- plot_ly(x=dat$xVar, # Initialize graph with line y=2
y=2,
type="scatter",
mode="lines",
hoverinfo="none",
layer="below",
line=list(color="grey",
width=2),
showlegend=FALSE) %>%
# Add trace at line y=1
add_trace(x=dat$xVar,
y=1,
type="scatter",
mode="lines",
hoverinfo="none",
line=list(color="grey",
width=1.5,
dash="dot"),
inherit=FALSE,
showlegend=FALSE) %>%
# Add trace at line y=3
add_trace(x=dat$xVar,
y=3,
type="scatter",
mode="lines",
hoverinfo="none",
line=list(color="grey",
width=1.5,
dash="dot"),
inherit=FALSE,
showlegend=FALSE)%>%
# Create Bar Chart
add_trace(x=dat$xVar,
y=dat$CopyNumber,
type="bar",
mode="markers",
color=dat$fillColor,
orientation="v",
inherit=FALSE,
marker=list(opacity=1),
legendgroup=dat$xVar,
showlegend=showLeg,
error_y = list(value=dat[[err]],
color='#000000',
thickness=3,
width=6,
visible=TRUE))
My approach:
I thought that the order the traces were created would define which layer they would be on in the graph, so since I plotted the bar chart after all of the trace lines, it would sit above them.
I also tried creating shapes to be the ablinesbut it was really difficult to get them in the correct position for subplots. add_traces was my best approach. Shapes in plotly have a layer parameter to define whether to place the shape above or below (see the plotly reference). I was hoping there was something like this that applied to traces, but I couldn't find it.
Maybe this could help you started. You did not provide a data set so here is a small made-up example. You can use layout to add a shape (a line in your case) to your graphic. As you can see the bar is above the line. Hope it helps!
plot_ly() %>%
add_bars(x = c("giraffes", "orangutans", "monkeys"), y = c(20, 14, 23)) %>%
layout(shapes = list(list(type = "lines",x0 = -1, x1 = 3, xref = "x", y0 = 3, y1 = 3, yref = "y", layer = "below")))
Here is some example code to illustrate my issue.
library(plotly)
p <- plot_ly(x = mtcars$mpg, y = seq_along(rownames(mtcars)), text=rownames(mtcars),
type = 'scatter', mode = 'markers')
ax <- list(
title = "",
ticktext = rownames(mtcars),
tickvals = seq(1,32)
)
line <- list(
type = "line",
line = list(color = "pink"),
xref = "x",
yref = "y"
layer = 'below'
)
lines <- list()
for (i in seq_along(rownames(mtcars))) {
line[["x0"]] <- mtcars$mpg[i] - 1
line[["x1"]] <- mtcars$mpg[i] + 1
line[c("y0", "y1")] <- i
lines <- c(lines, list(line))
}
p <- layout(p, title = 'Highlighting with Lines', shapes = lines, yaxis=ax)
p
I would like to add horizontal lines through the plot to separate each y-axis label. I would prefer the line split the labels as well as the graph, but splitting just the graph would suffice. I have looked extensively through the plotly reference but have yet to find anything that appears to help. I was told that there might be some sort of solution through some custom JS in the y-axisof the layout section, but am unsure on how I would go about this / am not very JS savvy.
I was able to accomplish this by adding more lines to the lines list. Under the for loop shown above, if you add the code:
for (i in seq_along(rownames(mtcars))) {
line[["x0"]] <- 10
line[["x1"]] <- 35
line[c("y0", "y1")] <- i-.5
lines <- c(lines, list(line))
}
It will place a separating line in between each of the data lines.
I am attempting to use subplots with the plot.ly R library for interactive online charting. I can successfully create a subplot, however am struggling to only have a single y-axis that is common to both charts.
The plot.ly website does provide an example for a common x-axis, however this is done slightly differently using and additional trace rather than the group option that is provided within the plot_ly() function.
example code:
library(data.table)
library(plotly)
dt <- data.table(x = c("A","B","C","D","A","B","C","D"),
y = c(12,4,3,9,5,10,3,7),
group = factor(c(rep("G1",4),rep("G2",4))))
dt$id <- as.integer(dt$group)
xx <- xaxis_standard
yy <- yaxis_standard
p <- plot_ly(dt, x=x, y=y, group = group, xaxis = paste0("x",id))
p <- layout(p, yaxis = list(range = c(0, max(y))))
p <- subplot(p, margin = 0.05)
p <- layout(p,showlegend = F, yaxis = list(anchor = 'x1'))
p
This image shows what results when I execute the code.
What I would like to have is the same chart, however without the y-axis on the right hand subplot.
Subplots are on separate axes labeled xaxis2, yaxis2, etc. Those axes are also arguments to layout().
p <- layout(p, showlegend = F, yaxis = list(anchor = 'x1'),
yaxis2 = list(showticklabels = F))
p