Related
I want to create bind them all together so that when I click hover on any chart it displays the value for all three altogether and how to correct the percentage value for each line chart.
rendered reprex looks like this...
library(plotly)
#> Loading required package: ggplot2
#>
#> Attaching package: 'plotly'
#> The following object is masked from 'package:ggplot2':
#>
#> last_plot
#> The following object is masked from 'package:stats':
#>
#> filter
#> The following object is masked from 'package:graphics':
#>
#> layout
library(shiny)
ui<-fluidPage(plotlyOutput("p3"))
server<-function(input,output){
output$p3<-renderPlotly({
# df <- read.csv("c:/users/nic user/desktop/lk.csv")
df<-tibble::tribble(
~month, ~abortion, ~delivery, ~pregnant,
"Jan-17", 13, 30, 43,
"Feb-17", 40, 14, 54,
"Mar-17", 19, 15, 34,
"Apr-17", 45, 20, 65,
"May-17", 16, 60, 76,
"Jun-17", 10, 35, 45,
"Jul-17", 10, 55, 65,
"Aug-17", 17, 70, 87,
"Sep-17", 10, 88, 98,
"Oct-17", 18, 60, 78,
"Nov-17", 25, 40, 65,
"Dec-17", 30, 37, 67,
"Jan-18", 30, 26, 56,
"Feb-18", 25, 20, 45,
"Mar-18", 20, 14, 34,
"Apr-18", 30, 24, 54,
"May-18", 20, 45, 65,
"Jun-18", 10, 57, 67,
"Jul-18", 10, 88, 98,
"Aug-18", 60, 18, 78,
"Sep-18", 30, 35, 65,
"Oct-18", 30, 37, 67,
"Nov-18", 10, 46, 56,
"Dec-18", 20, 45, 65,
"Jan-19", 10, 35, 45,
"Feb-19", 10, 24, 34,
"Mar-19", 30, 35, 65,
"Apr-19", 40, 25, 65,
"May-19", 40, 48, 88
)
d1<-aggregate(. ~month, data=df,sum)
d1
xaxis <- list(title = "months",
showline = TRUE,
showgrid = FALSE,
showticklabels = TRUE,
linecolor = 'rgb(204, 204, 204)',
linewidth = 2,
autotick = FALSE,
ticks = 'outside',
tickcolor = 'rgb(204, 204, 204)',
tickwidth = 2,
ticklen = 5,
tickfont = list(family = 'Arial',
size = 16,
color = 'rgb(82, 82, 82)'))
yaxis <- list(title = "abortion vs pregnant vs delivery",
showgrid = FALSE,
zeroline = FALSE,
showline = FALSE,
showticklabels = FALSE)
margin <- list(autoexpand = TRUE,
l = 100,
r = 100,
t = 110)
# Build the annotations
abortion1 <- list(
xref = 'paper',
yref = 'y',
x = 0.05,
y = d1$abortion[1],
xanchor = 'right',
yanchor = 'middle',
text = ~paste('abortion ', d1$abortion[1], '%'),
font = list(family = 'Arial',
size = 16,
color = 'rgba(67,67,67,1)'),
showarrow = FALSE)
pregnant1 <- list(
xref = 'paper',
yref = 'y',
x = 0.05,
y = d1$pregnant[1],
xanchor = 'right',
yanchor = 'middle',
text = ~paste('pregnant ', d1$pregnant[1], '%'),
font = list(family = 'Arial',
size = 16,
color = 'rgba(49,130,189, 1)'),
showarrow = FALSE)
delivery1 <- list(
xref = 'paper',
yref = 'y',
x = 0.05,
y = d1$delivery[1],
xanchor = 'right',
yanchor = 'middle',
text = ~paste('delivery ', d1$delivery[1], '%'),
font = list(family = 'Arial',
size = 16,
color = 'rgba(67,67,67,1)'),
showarrow = FALSE)
abortion2 <- list(
xref = 'paper',
x = 0.95,
y = d1$abortion[12],
xanchor = 'left',
yanchor = 'middle',
text = paste('abortion ', d1$abortion[29], '%'),
font = list(family = 'Arial',
size = 16,
color = 'rgba(67,67,67,1)'),
showarrow = FALSE)
pregnant2 <- list(
xref = 'paper',
x = 0.95,
y = d1$pregnant[12],
xanchor = 'left',
yanchor = 'middle',
text = paste('pregnant ', d1$pregnant[29], '%'),
font = list(family = 'Arial',
size = 16,
color = 'rgba(67,67,67,1)'),
showarrow = FALSE)
delivery2 <- list(
xref = 'paper',
x = 0.95,
y = d1$delivery[29],
xanchor = 'left',
yanchor = 'middle',
text = paste('delivery ', d1$delivery[29], '%'),
font = list(family = 'Arial',
size = 16,
color = 'rgba(67,67,67,1)'),
showarrow = FALSE)
fig <- plot_ly(d1, x = d1$month)
fig <- fig %>% add_trace(y = d1$abortion, type = 'scatter', mode = 'lines', line = list(color = 'rgba(67,67,67,1)', width = 3),name="abortion")
fig <- fig %>% add_trace(y = d1$pregnant, type = 'scatter', mode = 'lines', line = list(color = 'rgba(49,130,189, 1)', width = 3),name="pregnant")
fig <- fig %>% add_trace(y = d1$delivery, type = 'scatter', mode = 'lines', line = list(color = 'rgba(49,130,189, 1)', width = 3),name="delivery")
fig <- fig %>% add_trace(x = ~c(d1$month[1], d1$month[29]), y = ~c(d1$abortion[1], d1$abortion[29]), type = 'scatter',name="abortion", mode = 'markers', marker = list(color = 'rgba(67,67,67,1)', size = 16))
fig <- fig %>% add_trace(x = ~c(d1$month[1], d1$month[29]), y = ~c(d1$pregnant[1], d1$pregnant[29]), type = 'scatter',name="pregnant", mode = 'markers', marker = list(color = 'rgba(49,130,189, 1)', size = 16))
fig <- fig %>% add_trace(x = ~c(d1$month[1], d1$month[29]), y = ~c(d1$delivery[1], d1$delivery[29]), type = 'scatter',name="delivery", mode = 'markers', marker = list(color = 'rgba(49,130,189, 1)', size = 16))
fig <- fig %>% layout(title = "pregnant vs abortion vs delivery", xaxis = xaxis, yaxis = yaxis, margin = margin,
autosize = TRUE,
showlegend = FALSE,
annotations = abortion1)
fig <- fig %>% layout(annotations =pregnant1 )
fig <- fig %>% layout(annotations =delivery1 )
fig <- fig %>% layout(annotations =abortion2 )
fig <- fig %>% layout(annotations =pregnant2 )
fig <- fig %>% layout(annotations =delivery2 )
fig})}shinyApp(ui,server)
Any help and suggestion would be great. if there is any other suggestion to improvise it further would be appreciated.
fig <- fig %>% layout(hovermode = "x unified")
fig <- fig %>% layout(hovermode = "y unified")
You could user either one of these. The first ones unifies it for each x value and the second unifies for each y value.
I am trying to make a contour plot and draw a line on top of it (which I can do). I then overlaid two other lines using add_trace. For some reason the two lines I add using add_trace comes out orange instead of grey even though I specify grey (line = list(color = 'grey', )
I don't know how to add my data, it is very big. Is there any obvious reason as to why the colour changes to orange? If I change the width or the dash, it works. it just doesn't want to use the grey colour!
Thank you
(plot <- plot_ly(df, x = ~A, y = ~B, z = ~Difference, zauto = FALSE, zmin = -250, zmax = 250,
type="contour",
colorbar = list(title = "", titleside='right',
tickvals=c(-250, -200, -150, -100, -50, 0, 50, 100, 150, 200, 250), len = 1),
colorscale = "RdBu",
contours = list(start = 0, end = 0, coloring='heatmap', coloring='lines'),
line = list(color = 'black', width = 2)) %>%
add_trace(z = df$C, showscale = FALSE, line = list(color = 'grey', width = 2, dash = 'dash'), contours = list(start = 0, end = 0, coloring='lines')) %>%
add_trace(z = df$C, showscale = FALSE, line = list(color = 'grey', width = 2, dash = 'solid'), contours = list(start = 0, end = 0, coloring='lines')) %>%
layout(margin = list(l = 50, r = 70, b = 50, t = 50, pad = 4),
title = "", xaxis = x, yaxis = list(title = ""), font=t))
I guess the problem in your above code is, that you aren't specifiying the trace type. Accordingly plot_ly assumes that you are adding two more contour traces. Those traces are inheriting the colorscale you defined.
To avoid this you need to specify type = "scatter", mode = "lines", inherit = FALSE.
I made a simple example based on this.
library(plotly)
fig <- plot_ly(
x = c(-9, -6, -5, -3, -1),
y = c(0, 1, 4, 5, 7),
z = matrix(c(10, 10.625, 12.5, 15.625, 20, 5.625, 6.25, 8.125, 11.25, 15.625, 2.5, 3.125, 5, 8.125, 12.5, 0.625, 1.25, 3.125,
6.25, 10.625, 0, 0.625, 2.5, 5.625, 10), nrow = 5, ncol = 5),
type = "contour", colorbar = list(title = "", titleside='right'),
colorscale = "RdBu",
line = list(color = 'black', width = 2)) %>%
add_trace(x = -1:-7, y = 1:7, type = "scatter", mode = "lines", line = list(color = 'lightgreen', width = 2, dash = 'solid'), inherit = FALSE)
fig
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)
Is it possible to have two axes for a bar chart using plotly for R?
The code is modified from plotly bar chart example
library(plotly)
x <- c('January', 'February', 'March', 'April', 'May', 'June', 'July', 'August', 'September', 'October', 'November', 'December')
y1 <- c(20, 14, 25, 16, 18, 22, 19, 15, 12, 16, 14, 17)/10
y2 <- c(19, 14, 22, 14, 16, 19, 15, 14, 10, 12, 12, 16)
data <- data.frame(x, y1, y2)
#The default order will be alphabetized unless specified as below:
data$x <- factor(data$x, levels = data[["x"]])
p <- plot_ly(data, x = ~x, y = ~y1, type = 'bar', name = 'Primary Product', marker = list(color = 'rgb(49,130,189)')) %>%
add_trace(y = ~y2, name = 'Secondary Product', marker = list(color = 'rgb(204,204,204)')) %>%
layout(xaxis = list(title = "", tickangle = -45),
yaxis = list(title = ""),
margin = list(b = 100),
barmode = 'group')
p
This gives:
Values for the primary product are much smaller than secondary product - my purpose is to compare proportions by month, while still having y-axes show the actual values rather than a normalised value so it looks like this (mocked up):
I have tried plotly help to add another axis, here's the code. However, it doesn't seem to do anything, the resulting chart is the same as first one.
library(plotly)
x <- c('January', 'February', 'March', 'April', 'May', 'June', 'July', 'August', 'September', 'October', 'November', 'December')
y_1 <- c(20, 14, 25, 16, 18, 22, 19, 15, 12, 16, 14, 17)/10
y_2 <- c(19, 14, 22, 14, 16, 19, 15, 14, 10, 12, 12, 16)
data <- data.frame(x, y_1, y_2)
#The default order will be alphabetized unless specified as below:
data$x <- factor(data$x, levels = data[["x"]])
ay <- list(
tickfont = list(color = "red"),
overlaying = "y",
side = "right",
title = "second y axis"
)
p <- plot_ly(data, x = ~x, y = ~y_1, type = 'bar', name = 'Primary Product', marker = list(color = 'rgb(49,130,189)')) %>%
add_trace(y = ~y_2, name = 'Secondary Product', marker = list(color = 'rgb(204,204,204)'), axis = "y2") %>%
layout(yaxis2 = ay,
xaxis = list(title = "", tickangle = -45),
yaxis = list(title = ""),
margin = list(b = 100),
barmode = 'group')
p
Update 9 Aug 2018
MLavoie posted this code, which is similar to the attempt, however it gives a stacked bar chart - which is not the intended result.
data$x <- factor(data$x, levels = data[["x"]])
ay <- list(
tickfont = list(color = "red"),
overlaying = "y",
side = "right",
title = "second y axis"
)
p <- plot_ly() %>%
add_bars(data, x = ~x, y = ~y1, name = 'Primary Product', marker = list(color = 'rgb(49,130,189)')) %>%
add_bars(data, x = ~x, y = ~y2, name = 'Secondary Product', marker = list(color = 'rgb(204,204,204)'), yaxis = "y2") %>%
layout(yaxis2 = ay,
xaxis = list(title = "", tickangle = -45),
yaxis = list(title = ""),
margin = list(b = 100),
barmode = 'group')
p
I played with this answer and found the following derivative to give the best result.
This is the resulting plot:
library(plotly)
library(dplyr)
x <- c('January', 'February', 'March', 'April', 'May', 'June', 'July', 'August', 'September', 'October', 'November', 'December')
y1 <- c(20, 14, 25, 16, 18, 22, 19, 15, 12, 16, 14, 17)/10
y2 <- c(19, 14, 22, 14, 16, 19, 15, 14, 10, 12, 12, 16)
data <- data.frame(x, y1, y2)
data$x <- factor(data$x, levels = data[["x"]])
ay <- list(
overlaying = "y",
side = "right",
title = "Right Hand Axis"
)
p <- plot_ly() %>%
add_bars(data, x = ~x, y = ~y1, name = 'Primary Product (LHS)',
marker = list(color = 'rgb(49,130,189)'), offsetgroup = 1) %>%
add_bars(data, x = ~x, y = ~y2, name = 'Secondary Product (RHS)',
marker = list(color = 'rgb(204,204,204)'), yaxis = "y2", offsetgroup = 2) %>%
layout(yaxis2 = ay,
xaxis = list(title = "Time Period", tickangle = -45),
yaxis = list(title = "Left Hand Axis"),
margin = list(b = 100),
barmode = 'group',
legend = list(x = 1.1, y = 1))
p
I think you have a few typos, but this work.
data$x <- factor(data$x, levels = data[["x"]])
ay <- list(
tickfont = list(color = "red"),
overlaying = "y",
side = "right",
title = "second y axis"
)
p <- plot_ly() %>%
add_bars(data, x = ~x, y = ~y1, name = 'Primary Product', marker = list(color = 'rgb(49,130,189)')) %>%
add_bars(data, x = ~x, y = ~y2, name = 'Secondary Product', marker = list(color = 'rgb(204,204,204)'), yaxis = "y2") %>%
layout(yaxis2 = ay,
xaxis = list(title = "", tickangle = -45),
yaxis = list(title = ""),
margin = list(b = 100),
barmode = 'group')
p
A solution is to create two extra traces. Here is an example in Python :
This code is based on the code of the following separate question : Plotly Python: Align X-Axes in a grouped bar chart with multiple Y-axis
According to the discussion here, this should work.
x <- c('January', 'February', 'March', 'April', 'May', 'June', 'July', 'August', 'September', 'October', 'November', 'December')
y1 <- c(20, 14, 25, 16, 18, 22, 19, 15, 12, 16, 14, 17)/10
y2 <- c(19, 14, 22, 14, 16, 19, 15, 14, 10, 12, 12, 16)
data <- data.frame(x, y1, y2)
data$x <- factor(data$x, levels = data[["x"]])
ay <- list(
tickfont = list(color = "red"),
overlaying = "y",
side = "right",
title = "second y axis"
)
p <- plot_ly() %>%
add_bars(data, x = ~x, y = ~y1, name = 'Primary Product',
marker = list(color = 'rgb(49,130,189)'), offsetgroup = 1) %>%
add_bars(data, x = ~x, y = ~y2, name = 'Secondary Product',
marker = list(color = 'rgb(204,204,204)'), yaxis = "y2", offsetgroup = 2) %>%
layout(yaxis2 = ay,
xaxis = list(title = "", tickangle = -45),
yaxis = list(title = ""),
margin = list(b = 100),
barmode = 'group')
p
The attribute offsetgroup allows you to have more control over how the cross-trace offset and width values are computed.
Resulting plot
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!