I have the following code and dataframe :
datasku = data.frame(matrix(ncol = 3, nrow = 12))
names_col = c("product", "Bad Waitress", "Black Pumas")
colnames(datasku) = names_col
datasku$product <- c("x","y","s","u","i","o","l","m","n","k","b","c")
artists <- c("Bad Waitress", "Black Pumas")
datasku$`Bad Waitress`<- c(23,40,0,0,0,0,0,0,10,0,0,0)
datasku$`Black Pumas` <- c(0,40,0,0,0,65,0,0,10,0,0,0)
product Bad Waitress Black Pumas
1 x 23 0
2 y 40 40
3 s 0 0
4 u 0 0
5 i 0 0
6 o 0 65
7 l 0 0
8 m 0 0
9 n 10 10
10 k 0 0
11 b 0 0
12 c 0 0
show_vec = c()
for (i in 1:length(artists)){
show_vec = c(show_vec,FALSE)
}
get_menu_list <- function(artists){
n_names = length(artists)
buttons = vector("list",n_names)
for(i in seq_along(buttons)){
show_vec[i] = TRUE
buttons[i] = list(list(method = "restyle",
args = list("visible", show_vec),
label = artists[i]))
print(list(show_vec))
show_vec[i] = FALSE
}
return_list = list(
list(
type = 'dropdown',
active = 0,
buttons = buttons
)
)
return(return_list)
}
print(get_menu_list(artists))
fig <- plot_ly(data=datasku, x = ~product, y = ~`Bad Waitress`,type = 'bar',
transforms = list(
list(
type = 'filter',
target = 'y',
operation = '>',
value = 0
)),
hovertemplate = paste('<i>Popularity</i>: %{y:.2f}%',
'<br><i>Product</i>: %{x}<extra></extra><br>'))
fig <- fig %>% add_trace(y = ~`Black Pumas`)
fig <- fig %>% layout(showlegend = F,yaxis = list(title = 'Count'), barmode = 'group',
updatemenus = get_menu_list(artists))
fig
What this code does is basically create a plotly barchart with dropdown menus corresponding to the artists names. When clicking an artist it should only show the products which have a values >0 but it is partially working and I can't understand why.
If I run the code and select Bad Waitress this is what I obtain :
As you can see some columns are removed (since they have 0 value) but others, which have 0 value they are still shown despite the filter. How can I solve this problem?
Thank you
Related
I have some code that loops through and plots 3 red blocks and 3 blue blocks. The goal is to use the button functionality to turn on/off the blocks. I.e. when TestA is selected the red blocks show and when TestB is selected the blue blocks show. The code initially shows the red blocks but when selecting either buttons the blue blocks show and changing the button selection doesn't resort back to showing the red blocks, I have been able to get this button functionality to work with single blocks but it appears that using a for loop to create the blocks causes problems? Any help figuring this out would be greatly appreciated.
#Start vertices of rectangles at (0,0)
x1 = 0
x2 = 0
y1 = 0
y2 = 0
width=4
listA= append(list(T,T,T,F,F,F)
listB= append(list(F,F,F,T,T,T)
updatemenus <- list(
list(
active = -1,
type= 'buttons',
buttons = list(
list(
label = "TestA",
method = "update",
args = list(list(visible = listA),
list(title = "TestA"))),
list(
label = "TestB",
method = "update",
args = list(list(visible = listB),
list(title = "TestB"))))))
#Begin plot with a blank baseplot
p <- plot_ly(width = 725, height = 725,visible=T)%>%
layout(xaxis=list(range=c(0,width),showticklabels = F),yaxis=list(range=c(0,1625000),
linewidth=2,autotick = TRUE,ticks = "outside",ticklen = 5,tickwidth = 2,tickcolor = toRGB("black"),
title = "Volume [AF]"))
#Plot Red block
x1 = 0.05
x2 = width
y1 = 0
y2 = 500000
for(i in 1:3){
y2 = y2+250000
x2 = x2+1
x1 =x1+1
p <- add_trace(p,type='scatter',mode='none',x = c(x1,x2,x2,x1,x1),
y = c(y1,y1,y2,y2,y1),visible=T,
fill = 'toself',fillcolor = 'rgb(233,87,62)',
opacity=1,line=list(color='black'),
hoveron = 'fills',
showlegend = F)
}
#Plot Blue block
x1 = 0.05
x2 = width
y1 = 0
y2 = 500000
for(i in 1:3){
y2 = y2+250000
x2 = x2+1
x1 =x1+1
p <- add_trace(p,type='scatter',mode='none',x = c(x1,x2,x2,x1,x1),
y = c(y1,y1,y2,y2,y1),visible=F,
fill = 'toself',fillcolor = 'blue',
opacity=1,line=list(color='black'),
hoveron = 'fills',
showlegend = F)
}
p = p %>% layout(updatemenus=updatemenus)
p
The problem was with the T/F list creation. I was using the following code to generate my list:
list=list(c(rep(T,3),rep(F,3)))
Which resulted in a list of length 1. Using the code:
list = c(rep(list(T),3),rep(list(F),3))
Results in a list of length 6 which is needed for this example.
I have this code in R to tabulate a frequency table:
TablaFrecs = function(x,k,A,p){
options(scipen=999)
L = min(x)-p/2+A*(0:k)
x_cut = cut(x, breaks = L, right=FALSE)
intervals = levels(x_cut)
mc = (L[1]+L[2])/2+A*(0:(k-1))
Fr.abs = as.vector(table(x_cut))
Fr.rel = round(Fr.abs/length(x),4)
Fr.cum.abs = cumsum(Fr.abs)
Fr.cum.rel = cumsum(Fr.rel)
tabla = data.frame(intervals, mc, Fr.abs, Fr.cum.abs, Fr.rel, Fr.cum.rel)
tabla
}
but it shows the intervals in scientific notation
The ej 9 it's this:
I'm usingthe OFF.COURSE Variable
I've tried options(scipen=999) and format(scientific = F) but is doesn´t solves it.
PD: I also want to make an hist() of my TablaFrecs function, how can I do it?
You could use mapply and format to create the labels:
TablaFrecs = function(x,k,A,p){
options(scipen=999)
L = min(x)-p/2+A*(0:k)
labels = mapply(function(x,y){paste0("[",format(x),",",format(y),")")},L[-length(L)],L[-1])
x_cut = cut(x,
breaks = L ,
labels = labels,
right=FALSE)
intervals = levels(x_cut)
mc = (L[1]+L[2])/2+A*(0:(k-1))
Fr.abs = as.vector(table(x_cut))
Fr.rel = round(Fr.abs/length(x),4)
Fr.cum.abs = cumsum(Fr.abs)
Fr.cum.rel = cumsum(Fr.rel)
tabla = data.frame(intervals, mc, Fr.abs, Fr.cum.abs, Fr.rel, Fr.cum.rel)
tabla
}
TablaFrecs(1e6, k= 27, A = 3646296, p= 0.1)
intervals mc Fr.abs Fr.cum.abs Fr.rel Fr.cum.rel
1 [999999.9,4646296) 2823148 1 1 1 1
2 [4646296,8292592) 6469444 0 1 0 1
3 [8292592,11938888) 10115740 0 1 0 1
...
I really appreaciate the 'plotly' r-package. Currently I run into an issue, where I want to visualize a data frame as points and map the point size (as well as the shape potentially) to a dimension of the data frame.
The problem I run into with my own dataset is, that the sizes are somehow "mixed up" in the sense, that the bigger points don't correspond to the bigger values.
I haven't fully understood the options I have with plotly (sizeref and other marker-options; the fundamental difference between mapping the dimension directly or in the marker arguments; etc) , so this is my best shot as a minimal example right here.
(The second plot is closer to what I currently do. If this one could be fixed, it would be preferable to me)
Your thoughts are greatly appreciated. :)
library(plotly)
set.seed(1)
df <- data.frame(x = 1:10,
y = rep(c("id1", "id2"), 5),
col = factor(sample(3, 10, replace = TRUE)))
df$size <- c(40, 40, 40, 30, 30, 30, 20, 20, 20, 10)
df
#> x y col size
#> 1 1 id1 1 40
#> 2 2 id2 2 40
#> 3 3 id1 2 40
#> 4 4 id2 3 30
#> 5 5 id1 1 30
#> 6 6 id2 3 30
#> 7 7 id1 3 20
#> 8 8 id2 2 20
#> 9 9 id1 2 20
#> 10 10 id2 1 10
# Mapping looks right, but the size may not be correct
plot_ly(df,
x = ~x,
y = ~y,
color = ~col,
size = ~size,
type = 'scatter',
mode = 'markers',
hoverinfo = "text",
text = ~paste('</br> x: ', x,
'</br> y: ', y,
'</br> col: ', col,
'</br> size: ', size)
# , marker = list(size = ~size)
)
# Size looks right, but mapping to points is wrong
plot_ly(df,
x = ~x,
y = ~y,
color = ~col,
# size = ~size,
type = 'scatter',
mode = 'markers',
hoverinfo = "text",
text = ~paste('</br> x: ', x,
'</br> y: ', y,
'</br> col: ', col,
'</br> size: ', size)
, marker = list(size = ~size)
)
devtools::session_info() # excerpt
#> plotly * 4.8.0
This question already has answers here:
Format axis tick labels to percentage in plotly
(2 answers)
Closed 2 years ago.
I have a df which can have 2 or more columns with the first one month always fixed.I am trying to plot them using plotly r. As of now it has three columns: month,apple,orange. Based on analysis it can have another column banana. Below is the code I am using right now but it even takes the column month for y-axis. How do I fix this:
> sample_test
month apple orange
2 Aug-17 2 1
3 Dec-17 2 1
4 Feb-18 2 1
5 Jan-18 2 1
6 Jul-17 2 1
7 Jun-17 2 1
8 May-17 2 1
9 Nov-17 2 1
10 Oct-17 2 1
11 Sep-17 2 1
p<- plot_ly(sample_test, x = sample_test$month, name = 'alpha', type = 'scatter', mode = 'lines',
line = list(color = 'rgb(24, 205, 12)', width = 4)) %>%
layout(#title = "abbb",
xaxis = list(title = "Time"),
yaxis = list (title = "Percentage"))
for(trace in colnames(sample_test)){
p <- p %>% plotly::add_trace(y = as.formula(paste0("~`", trace, "`")), name = trace)
}
p
The output looks like this :
Does this help?
sample_test <- read.table(
text = ' month apple orange
2 Aug-17 2 1
3 Dec-17 2 1
4 Feb-18 2 1
5 Jan-18 2 1
6 Jul-17 2 1
7 Jun-17 2 1
8 May-17 2 1
9 Nov-17 2 1
10 Oct-17 2 1
11 Sep-17 2 1'
)
sample_test$month <- as.Date(paste('01', sample_test$month, sep = '-'), format = '%d-%b-%y')
library(plotly)
p <- plot_ly(sample_test, type = 'scatter', mode = 'lines',
line = list(color = 'rgb(24, 205, 12)', width = 4)) %>%
layout(#title = "abbb",
xaxis = list(title = "Time"),
yaxis = list (title = "Percentage", tickformat = '%'))
for(trace in colnames(sample_test)[2:ncol(sample_test)]){
p <- p %>% plotly::add_trace(x = sample_test[['month']], y = sample_test[[trace]], name = trace)
}
p
There are couple of things to note here -
While dealing with dates, it's best to format them as dates. This can save a lot of headache later on. It is also useful as most if not all functions that require dealing with dates have methods built to handle them.
While adding traces in a for loop, always reference the vector to be plotted explicitly like data$vector or data[['vector']] and not like y = ~vector, because plotly for some reason ends up plotting just one trace over and over again.
You can specify a trace for the first y element, which will give you your raw counts. Next you can add a format for your y-axis using tickformat, which will convert to percentages.
sample_test <- data.frame(month = c("Aug-17", "Dec-17", "Feb-18"), apple = c(2,2,2), orange = c(1,1,1))
p <- plot_ly(sample_test, x = sample_test$month, y = ~apple, name = 'alpha', type = 'scatter', mode = 'lines',
line = list(color = 'rgb(24, 205, 12)', width = 4)) %>%
layout(xaxis = list(title = "Time")) %>%
layout(yaxis = list(tickformat = "%", title = "Percentage"))
Although for some reason this appears to just multiply by 100 and add a % label for some reason, rather than actually calculate a percentage. From this SO answer, looks like that's all it does. I don't really use plotly, but in ggplot you can do this if you reshape your data to long and map your categorical variable (in this case fruit) as a percent.
Edit: per OP's comment, removed month from being traced.
p <- plot_ly(type = 'scatter', mode = 'lines') %>%
layout(yaxis = list(tickformat = "%", title = "Percentage"))
colNames <- names(sample_test)
colNames <- colNames[-which(colNames == 'month')]
for(trace in colNames){
p <- p %>% plotly::add_trace(data = sample_test, x = ~ month, y = as.formula(paste0("~`", trace, "`")), name = trace)
print(paste0("~`", trace, "`"))
}
p
I have a variable data with the following structure:
week: int 1 1 2 2 3 3 4 4 5 5 ...
earn: int 2 3 2 7 8 9 2 6 4 2 ...
name: chr "C", "A", "C", "A" ...
Each name (person) has a week with what they earned. So from the above we can see that C earned 2 in week 1 while A earned 3 in week 1. C earned 2 in week two while A earned 7 in week too.
I wish to plot this on a line graph. The below is what I have tried.
p <- plot.ly(data, x = data$week, name = "Week", type = "scatter", mode = "lines") %>%
add_trace(y = data$earn, name = "earn", mode = "lines+markers) %>%
add_trace(y = data$earn, name = "earn", mode = "markers")
p
However, this gives a graph with one line where the marker for week one has (2,3) as this is both the earning on this week. However I would like two lines so it can be clearly seen the difference in earnings for both names.
Defining color will give you what you want.
p <- plot_ly(data, x = ~week, y = ~ earn) %>%
add_lines(color = ~name) %>%
add_markers(color = ~name, showlegend = FALSE)
p
alternatively you can also use:
p <- plot_ly(data=data, x = ~week, y = ~ earn) %>%
add_traces(color = ~name, mode = "lines+markers")
p