plotly line chart with zero logarithmic scale - r

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

Related

R ggplot legend with Waffle chart

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

show total /sum of values in donut plot in R plotly

I have a sample data set and I am trying to plot a basic donut plot in R via plotly. The code almost (currently the code below does not update the second color) works fine. Now, I want to show sum of the values of both the IDs under Type next to the respective percentages.
How can I do this?
Data
Value = c(50124, 9994, 9822, 13580, 5906, 7414, 16847, 59, 80550, 6824, 3111, 16756, 7702, 23034, 38058, 6729, 6951, 2, 408,
37360, 20517, 18714, 352, 3, 42922, 30850, 21, 4667, 12220, 8762, 445, 1875, 719, 188, 26, 124, 996, 10,
27, 304, 55, 34980, 67, 3, 25, 1012, 3588, 77, 847, 47, 1057, 924, 233, 40, 2, 2362, 3,
1866, 16, 0, 0, 0)
Type = c("A", "A", "A", "A", "A", "A", "A", "A", "A", "A", "A", "A", "A", "A", "A", "A", "A", "A", "A", "A", "A", "A",
"A", "A", "A", "A", "A", "A", "A", "A", "A", "A", "A",
"B", "B", "B", "B", "B", "B", "B", "B", "B", "B", "B",
"B", "B", "B", "B", "B" "B", "B", "B", "B", "B", "B",
"B", "B", "B", "B", "B", "B", "B")
df = data.frame(Type, Value)
Code
library(tidyverse)
library(plotly)
color = c('rgb(0,255,255)', 'rgb(255,127,80)')
fig = df %>% plot_ly(labels = ~Type,
values = ~Value,
#colors = c("grey50", "blue"),
marker = list(colors = color))
fig = fig %>% add_pie(hole = 0.6,
text = ~paste(sum(Value)),
textinfo = "text + percent"))
fig = fig %>% layout(title = "Title", showlegend = T,
xaxis = list(showgrid = FALSE, zeroline = FALSE, showticklabels = T),
yaxis = list(showgrid = FALSE, zeroline = FALSE, showticklabels = T))
fig
Desired output
In your dataframe calculate a sum column and paste it in text = ~paste(sum)
df1 <- df %>%
group_by(Type) %>%
mutate(sum = sum(Value))
library(tidyverse)
library(plotly)
color = c('rgb(0,255,255)', 'rgb(255,127,80)')
fig = df1 %>% plot_ly(labels = ~Type,
values = ~Value,
#colors = c("grey50", "blue"),
marker = list(colors = color))
fig = fig %>% add_pie(hole = 0.6,
text = ~paste(sum),
textinfo = "text + percent")
fig = fig %>% layout(title = "Title", showlegend = T,
xaxis = list(showgrid = FALSE, zeroline = FALSE, showticklabels = T),
yaxis = list(showgrid = FALSE, zeroline = FALSE, showticklabels = T))
fig

Plotly R: Hovertext for values which have 0 y-axis values

Problem: In plotly, is there a possibility to get the hoverinfo also for values which have zero y-value? So, in the example below, I want to have hovertext for xaxis value a, d and e.
Any suggestions?
library(data.table)
library(plotly)
dt <- data.table(
x = c("a", "b", "c", "d", "e"),
y = c(0 , 5, 2, 0, 0),
z = c(12, 14, 19, 23, 0)
)
plot_ly(dt,
x = ~x) %>%
add_bars(y = ~y,
text = ~paste("y-Values:", y, " z-Values:", z),
hoverinfo = "text")
I found the solution (add in layout hovermode = 'x'):
library(data.table)
library(plotly)
dt <- data.table(
x = c("a", "b", "c", "d", "e"),
y = c(0 , 5, 2, 0, 0),
z = c(12, 14, 19, 23, 0)
)
plot_ly(dt,
x = ~x) %>%
add_bars(y = ~y,
text = ~paste("y-Values:", y, " z-Values:", z),
hoverinfo = "text") %>%
layout(hovermode = 'x')

Why does addPolylines work differently on an R Shiny leaflet map?

I have R code which creates a leaflet map with points connected by addPolylines().
library(shiny)
library(leaflet)
station = c("A", "B", "C", "D", "E", "F")
latitude = c(-1.63, -1.62, -1.62, -1.77, -1.85, -1.85)
longitude = c(34.3, 34.4, 34.7, 34.3, 34.5, 34.7)
big = c(0, 20, 60, 90, 50, 10)
small = c(100, 80, 40, 10, 50, 90)
colour = c("blue", "blue", "red", "red", "black", "black")
group = c("A", "A", "B", "B", "C", "C")
df = cbind.data.frame(station, latitude, longitude, big, small, colour, group)
colnames(df) = c("station", "latitude", "longitude", "big", "small", "colour", "group")
myMap = leaflet() %>%
setView(lng = 34.4, lat = -1.653, zoom = 8) %>%
addTiles()%>%
addCircles(data = df,
lng = ~ longitude, lat = ~ latitude,
color = ~ colour,
radius = 2000,
stroke = TRUE,
opacity = 5,
weight = 1,
fillColor = ~ colour,
fillOpacity = 1)
for(group in levels(df$group)){
myMap = addPolylines(myMap,
lng= ~ longitude,
lat= ~ latitude,
data = df[df$group == group,],
color= ~ colour,
weight = 3)
}
myMap
This is exactly what I am wanting and it looks like this:
However, when I put this into an R shiny app, the map will not appear. The ui code is:
fluidPage(
theme = shinythemes::shinytheme("yeti"),
titlePanel(title = "Polyline Map"))
mainPanel("",
helpText("This is the polyline map"),
hr(),
leafletOutput("myMap", height = 400, width = 600)
)
The server code is:
function(input, output, session) {
output$myMap = renderLeaflet({
leaflet() %>%
setView(lng = 34.4, lat = -1.653, zoom = 8) %>%
addTiles()%>%
addCircles(data = df,
lng = ~ longitude, lat = ~ latitude,
color = ~ colour,
radius = 4000,
stroke = TRUE,
opacity = 5,
weight = 1,
fillColor = ~ colour,
fillOpacity = 0.5)
for(group in levels(df$group)){
myMap = addPolylines(myMap,
lng= ~ longitude,
lat= ~ latitude,
data = df[df$group==group,],
color= ~ colour,
weight = 3)
}
}
)}
And the global code is:
library(shiny)
library(leaflet)
station = c("A", "B", "C", "D", "E", "F")
latitude = c(-1.63, -1.62, -1.62, -1.77, -1.85, -1.85)
longitude = c(34.3, 34.4, 34.7, 34.3, 34.5, 34.7)
big = c(0, 20, 60, 90, 50, 10)
small = c(100, 80, 40, 10, 50, 90)
colour = c("blue", "blue", "red", "red", "black", "black")
group = c("A", "A", "B", "B", "C", "C")
df = cbind.data.frame(station, latitude, longitude, big, small, colour, group)
colnames(df) = c("station", "latitude", "longitude", "big", "small", "colour", "group")
Does anyone know why this happens and what I can do to fix it? Thank you!
I was able to get your code working with two very small adjustments:
You refer to myMap in your renderLeaflet function but that is not defined yet, so I modified the first line to myMap <- leaflet() %>%
You do not return anything from the renderLeaflet function, so I added the statement myMap after the for-loop.
Working code is shown below, hope this helps!
library(shiny)
library(leaflet)
station = c("A", "B", "C", "D", "E", "F")
latitude = c(-1.63, -1.62, -1.62, -1.77, -1.85, -1.85)
longitude = c(34.3, 34.4, 34.7, 34.3, 34.5, 34.7)
big = c(0, 20, 60, 90, 50, 10)
small = c(100, 80, 40, 10, 50, 90)
colour = c("blue", "blue", "red", "red", "black", "black")
group = c("A", "A", "B", "B", "C", "C")
df = cbind.data.frame(station, latitude, longitude, big, small, colour, group)
colnames(df) = c("station", "latitude", "longitude", "big", "small", "colour", "group")
ui <- fluidPage(
theme = shinythemes::shinytheme("yeti"),
titlePanel(title = "Polyline Map"),
mainPanel("",
helpText("This is the polyline map"),
hr(),
leafletOutput("myMap", height = 400, width = 600)
)
)
server <- function(input, output, session) {
output$myMap = renderLeaflet({
myMap <- leaflet() %>%
setView(lng = 34.4, lat = -1.653, zoom = 8) %>%
addTiles()%>%
addCircles(data = df,
lng = ~ longitude, lat = ~ latitude,
color = ~ colour,
radius = 4000,
stroke = TRUE,
opacity = 5,
weight = 1,
fillColor = ~ colour,
fillOpacity = 0.5)
for(group in levels(df$group)){
myMap = addPolylines(myMap,
lng= ~ longitude,
lat= ~ latitude,
data = df[df$group==group,],
color= ~ colour,
weight = 3)
}
myMap
})
}
shinyApp(ui,server)

How to order a plot in ggvis in R

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') ))

Resources