Related
does anyone know how to deal with line charts in log scale where there are zero values in plotly? The lines sort of just disappear.
library(tidyverse)
library(lubridate)
library(plotly)
df2 <- tibble::tribble(
~SAMPLE_DATE, ~REPORT_RESULT_VALUE,
"2018-10-04", 0.05,
"2019-05-05", 0.01,
"2019-10-04", 0,
"2020-06-05", 0.01,
"2020-09-11", 0,
"2021-04-23", 0,
"2022-05-08", 0.06 ) %>%
mutate(SAMPLE_DATE = ymd(SAMPLE_DATE))
plot_ly(data = df2) %>%
add_trace(x = ~SAMPLE_DATE,
y = ~REPORT_RESULT_VALUE,
mode = "lines+markers") %>%
layout(xaxis = list(title = 'Sample date'),
yaxis = list(title = "Concentration (mg/L)",
type = "log"))
I found a similar post in the plotly forum a while ago, but no solution: https://community.plotly.com/t/line-chart-with-zero-in-logarithmic-scale/40084
-----------------------
An extra example based on Jon Spring's edited answer.
df3 <- tibble::tribble(
~SAMPLE_DATE, ~REPORT_RESULT_VALUE, ~CHEMICAL_NAME,
"2018-10-04", 0.05, "a",
"2019-05-05", 0.01, "a",
"2019-10-04", 0, "a",
"2020-06-05", 0.01, "a",
"2020-09-11", 0, "a",
"2021-04-23", 0, "a",
"2022-05-08", 0.06, "a",
"2018-10-04", 95, "b",
"2019-05-05", 90, "b",
"2019-10-04", 80, "b",
"2020-06-05", 91, "b",
"2020-09-11", 90, "b",
"2021-04-23", 90, "b",
"2022-05-08", 96, "b",
"2018-10-04", 9.5, "c",
"2019-05-05", 9.0, "c",
"2019-10-04", 8.0, "c",
"2020-06-05", 9.1, "c",
"2020-09-11", 9.0, "c",
"2021-04-23", 9.0, "c",
"2022-05-08", 9.6, "c") %>%
mutate(SAMPLE_DATE = ymd(SAMPLE_DATE))
ggplotly(
ggplot(df3, aes(SAMPLE_DATE, REPORT_RESULT_VALUE, colour = CHEMICAL_NAME)) +
geom_line() +
geom_point() +
scale_y_continuous(trans = scales::pseudo_log_trans(sigma = 0.1),
breaks = scales::breaks_pretty(n = 10)) +
labs(x = 'Sample date', y = "Concentration (mg/L)")
)
Here ideally I would like to have the labels spread out more.
Here's a way to do it in ggplot2 using the handy scales::pseudo_log_trans function and then using plotly::ggplotly to convert to plotly. pseudo_log_trans is handy when you want a (mostly) log scale but you want to accommodate zeroes or even negative values.
ggplotly(
ggplot(df2, aes(SAMPLE_DATE, REPORT_RESULT_VALUE)) +
geom_line() +
geom_point() +
scale_y_continuous(trans = scales::pseudo_log_trans(sigma = 0.005),
breaks = scales::breaks_pretty(n=10), # EDIT
labels = scales::number_format()) +
labs(x = 'Sample date', y = "Concentration (mg/L)")
)
Would removing zero work for you?
plot_ly(data = df2 %>% filter(REPORT_RESULT_VALUE > 0)) %>%
add_trace(x = ~SAMPLE_DATE,
y = ~REPORT_RESULT_VALUE,
mode = "lines+markers",
na.rm = TRUE) %>%
layout(xaxis = list(title = 'Sample date'),
yaxis = list(title = "Concentration (mg/L)",
type = "log"))
Created on 2022-12-22 with reprex v2.0.2
library(tidyverse)
library(waffle)
df_2 <- structure(list(group = c(2, 2, 2, 1, 1, 1),
parts = c("A", "B", "C", "A", "B", "C"),
values = c(1, 39, 60, 14, 15, 71)), row.names = c(NA,
-6L), class = c("tbl_df", "tbl", "data.frame"))
df_2 %>% ggplot(aes(label = parts)) +
geom_pictogram(
n_rows = 10, aes(color = parts, values = values),
family = "fontawesome-webfont",
flip = TRUE
) +
scale_label_pictogram(
name = "Case",
values = c("male"),
breaks = c("A", "B", "C"),
labels = c("A", "B", "C")
) +
scale_color_manual(
name = "Case",
values = c("A" = "red", "B" = "green", "C" = "grey85"),
breaks = c("A", "B", "C"),
labels = c("A", "B", "C")
) +
facet_grid(~group)
With the above code, I got the legend what I expected:
However, when I replaced df_2 with the following df_1 dataframe, I was unable to combine two legends.
df_1 <- structure(list(group = c(2, 2, 2, 1, 1, 1),
parts = c("A", "B", "C", "A", "B", "C"),
values = c(0, 0, 100, 0, 0, 100)),
row.names = c(NA,-6L), class = c("tbl_df", "tbl", "data.frame"))
I kind of know the cause of the problem (0 values) but I would like to keep the legend the same as the graph above. Any suggestions would be appreciated.
To make it clear, the package "waffle" referred to here is not the CRAN package "waffle", but the GitHub-only package:
remotes::install_github("hrbrmstr/waffle")
library(waffle)
You will also need a way of displaying the pictograms, such as:
library(emojifont)
load.fontawesome()
Now, as with any other discrete scale, if you want to add values that are not present in the (post-stat) data, you need to use the limits argument:
df_1 %>% ggplot(aes(label = parts)) +
geom_pictogram(
n_rows = 10, aes(color = parts, values = values),
family = "fontawesome-webfont",
flip = TRUE
) +
scale_label_pictogram(
name = "Case",
values = c("male"),
breaks = c("A", "B", "C"),
labels = c("A", "B", "C"),
limits = c("A", "B", "C")
) +
scale_color_manual(
name = "Case",
values = c("A" = "red", "B" = "green", "C" = "grey85"),
breaks = c("A", "B", "C"),
labels = c("A", "B", "C")
) +
facet_grid(~group)
It is a bit tricky, but what you could do is say let's add 1 to all values so it will plot it like before. But using ggplot_build to remove from each case one row to get it in the right amount like this:
library(tidyverse)
library(waffle)
library(ggplot2)
library(dplyr)
library(emojifont)
library(waffle)
library(extrafont)
p <- df_1 %>% ggplot(aes(label = parts)) +
geom_pictogram(
n_rows = 10, aes(color = parts, values = values+1),
family = "fontawesome-webfont",
flip = TRUE
) +
scale_label_pictogram(
name = "Case",
values = c("male"),
breaks = c("A", "B", "C"),
labels = c("A", "B", "C")
) +
scale_color_manual(
name = "Case",
values = c("A" = "red", "B" = "green", "C" = "grey85"),
breaks = c("A", "B", "C"),
labels = c("A", "B", "C")
) +
facet_grid(~group)
q <- ggplot_build(p)
q$data[[1]] <- q$data[[1]] %>%
group_by(PANEL) %>%
slice(4:n())
q <- ggplot_gtable(q)
plot(q)
Created on 2022-10-20 with reprex v2.0.2
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!
I am a bit confused with use of highcharter hc_add_series function.
I am trying to create a plot where I need to specify both x and y axis, where x axis are continuous. I have a data-frame, for example:
df_plot <- cbind(
seq(0, 1, by = 0.1),
sample(seq(from = 100, to = 300, by = 10), size = 11, replace = TRUE),
sample(seq(from = 1, to = 100, by = 9), size = 11, replace = TRUE),
sample(seq(from = 50, to = 60, by = 2), size = 11, replace = TRUE),
sample(seq(from = 100, to = 130, by = 1), size = 1, replace = TRUE)
) %>%
as.data.frame()
names(df_plot) <- c("x", "a", "b", "c", "d")
I saw this example that works
highchart() %>%
hc_add_series(data = purrr::map(4:8, function(x) list(x, x)), color = "blue")
So i tried:
df_plot1 <- Map(cbind, split.default(df_plot[-1], names(df_plot)[-1]), x=df_plot[1])
highchart() %>%
hc_add_series(data = df_plot1[[1]]) %>%
hc_add_series(data = df_plot1[[2]], yAxis = 1) %>%
hc_yAxis_multiples(
list(lineWidth = 3, lineColor='#7cb5ec', title=list(text="First y-axis")),
list(lineWidth = 3, lineColor="#434348", title=list(text="Second y-axis")))
However, I am getting "No data to display" on the plot, so I obviously went wrong somewhere.
Also, I cannot use hchart function, as I need have multiple y axis
After reading docs about split.default it Divide into Groups and Reassemble, however you need to access the variable you want to plot, e.g. df_plot1[[1]$a, like so:
library(highcharter)
df_plot <- cbind(
seq(0, 1, by = 0.1),
sample(seq(from = 100, to = 300, by = 10), size = 11, replace = TRUE),
sample(seq(from = 1, to = 100, by = 9), size = 11, replace = TRUE),
sample(seq(from = 50, to = 60, by = 2), size = 11, replace = TRUE),
sample(seq(from = 100, to = 130, by = 1), size = 1, replace = TRUE)
) %>% as.data.frame()
names(df_plot) <- c("x", "a", "b", "c", "d")
df_plot1 <- Map(cbind, split.default(df_plot[-1], names(df_plot)[-1]), x=df_plot[1])
highchart() %>%
hc_xAxis(categories = df_plot1[[1]]$x) %>%
hc_add_series(data = df_plot1[[1]]$a) %>%
hc_add_series(data = df_plot1[[2]]$b, yAxis = 1) %>%
hc_yAxis_multiples(
list(lineWidth = 3, lineColor='#7cb5ec', title=list(text="First y-axis")),
list(lineWidth = 3, lineColor="#434348", title=list(text="Second y-axis")))
not sure if this can help you,
library(tidyr)
df_plot2 <- gather(df_plot, group, y, -x)
hchart(df_plot2, "line", hcaes(x, y, group = group))
hchart(df_plot2, "line", hcaes(x, y, group = group), yAxis = 0:3) %>%
hc_yAxis_multiples(
list(lineWidth = 3, title=list(text="First y-axis")),
list(lineWidth = 3, title=list(text="Second y-axis")),
list(lineWidth = 3, title=list(text="3rd y-axis")),
list(lineWidth = 3, title=list(text="4th y-axis"))
)
I am trying to learn how to use ggvis to make plots. I really would like on that looks like this:
I have learned how to make a nearly identical plot:
library(ggvis)
y <- c(
"a", "b", "c", "d", "e", "f", "g", "h",
"a", "b", "c", "d", "e", "f", "g", "h")
x <- c(28, 25, 38, 19, 13, 30, 60, 18, 11, 10, 17, 13, 9, 25, 56, 17)
Status <- c(rep(c('Group 1'),8), rep(c('Group 2'),8))
df <- data.frame(y,x,Status)
df %>% ggvis(x= ~x, y= ~y, fill= ~Status) %>% layer_points() %>%
add_axis('x', properties= axis_props( grid = list(stroke = 'blank') )) %>%
add_axis('y', properties= axis_props( grid = list(stroke = 'blank') ))
My question: How can I order the plot like they have done in the top plot? It looks like they have ordered it from biggest to smallest somehow. Thanks!
tbl_df(df) %>%
mutate(y=as.character(y), x=as.numeric(x)) %>%
arrange(desc(x)) %>%
ggvis(x= ~x, y= ~y, fill= ~Status) %>% layer_points() %>%
add_axis('x', properties= axis_props( grid = list(stroke = 'blank') )) %>%
add_axis('y', properties= axis_props( grid = list(stroke = 'blank') ))