I have a dataframe with timestamp column and one integer column with range 0-8.
I'd like to plot a marker for every data point, but plotly shows me a plot with x-axis starting in 1970.
When I convert integer column to factor, x-axis range is set correctly.
Any idea, how to set marker color using integer column and get proper range for x-axis?
Bad range:
library(plotly)
library(tidyverse)
library(lubridate)
set.seed(99)
tsRange = seq(ymd_hm("2021-01-01 00:00", tz = "CET"), ymd_hm("2021-01-08 23:59", tz = "CET"), by = "60 secs")
nRows <- 20
df <- tibble(
ts = sample(tsRange, nRows),
point = sample(1:8, nRows, replace = TRUE)
) %>%
mutate(point_fac = as.factor(point))
plot_ly(df, x = ~ts, y = "something", color = ~point) %>% add_markers()
good range
plot_ly(df, x = ~ts, y = "something", color = ~point_fac) %>% add_markers()
Regards
Paweł
Related
I'm trying to plot a time series using Plotly, but it adds days that are not in the original dataset. The dates are in POSIXct class.
Here is a minimal reproducible example:
library(plotly)
data <- data.frame(
Date = as.POSIXct(c('2022-10-20 10:11:29',
'2022-10-20 14:11:29',
'2022-10-24 16:31:33',
'2022-10-24 19:31:33')),
Names = rep('X', 4),
Value = seq(1, 4)
)
fig <- plot_ly(data, x = ~Date, y = ~Value,
color = ~Names, type = 'scatter',
mode = 'lines',
colors = 'blue')
Plotly Output (red shows the problem)
As we can see from the image above, even though the days 2022-10-21, 2022-10-22, and 2022-10-23 don't exist in the dataset, they still appear in the plot. I would like to remove these days and connect '2022-10-20 14:11:29' directly to '2022-10-24 16:31:33'.
Convert the Date to a factor via as.factor or a string via as.character otheriwse plotly will use a discrete time axis with equidistant ticks:
library(plotly)
data <- data.frame(Date = as.POSIXct(
c(
'2022-10-20 10:11:29',
'2022-10-20 14:11:29',
'2022-10-24 16:31:33',
'2022-10-24 19:31:33'
)
),
Names = rep('X', 4),
Value = seq(1, 4))
fig <- plot_ly(
data,
x = ~ as.factor(Date),
y = ~ Value,
color = ~ Names,
type = 'scatter',
mode = 'lines',
colors = 'blue'
)
fig
I would like to declutter a plot created with plotly and remove the repetitions of the year on the x-axis. The year should be shown only for the first month. For the rest of the labels the month (without the year) is enough.
I have tried to achieve this result with the ifelse function - without success (see reproducible example below). Is there any way to use ifelse or if_else to set the axis labels in plotly? I think it works that way in ggplot.
library(tidyverse)
library(plotly)
set.seed(42)
df <-
data.frame(date = seq(ymd('2021-01-01'), ymd('2021-12-12'), by = 'weeks'),
value = cumsum(sample(-10:20, length(seq(ymd('2021-01-01'), ymd('2021-12-12'), by = 'weeks')), replace = TRUE)))
df %>%
plot_ly(x = ~date, y = ~value) %>%
add_lines() %>%
layout(xaxis = list(dtick = "M1", tickformat = ~ifelse(date <= "2021-01-31", "%b\n%Y", "%b")))
I have a data frame contains month-end data. I'm using the stacked column chart but have an issue with the x-axis date labels. For example, it shows April under the March column.
library(highcharter)
df = data.frame(Date = as.Date(c('2020-03-31','2020-03-31','2020-04-30','2020-05-31','2020-05-31','2020-06-30')), Value = c(1,2,3,4,5,6), Country = c('US','Mexico','US','Canada','US','Canada'))
hchart(df, "column", hcaes(Date, Value, group = Country)) %>%
hc_plotOptions(column = list(stacking = "normal"))
I tried to specify the type and labels by adding hc_xAxis(type = 'datetime', labels = list(format = '{value:%m-%Y}')), but it doesn't help. The tooltip shows the correct dates.
A simple and valuable solution is to transform dates into characters.
library(highcharter)
df = data.frame(Date = as.Date(c('2020-03-31','2020-03-31','2020-04-30',
'2020-05-31','2020-05-31','2020-06-30')),
Value = c(1,2,3,4,5,6),
Country = c('US','Mexico','US','Canada','US','Canada'))
df$Date <- as.character(df$Date)
hchart(df, "column", hcaes(Date, Value, group = Country)) %>%
hc_plotOptions(column = list(stacking = "normal")) %>%
hc_xAxis(type="category", categories=unique(df$Date))
i have this small dataset that i need to plot with plotly. Im struggling with it :/
Im looking to have 3 colored lines (each line for each of the rows (1,2,3). The x axis needs to be the column names and the Y axis represents each one of the numeric values.
My code so far looks wrong
plot_ly (x = colnames(a), y = a[1], type = "scatter" ,mode = "lines" )
I'm not sure that this is your desired plot, but it sounded closest to your description. I adapted a few columns of your data to describe.
The plot will be easier if data is in longer form with pivot_longer. Also easier if you add row numbers to your data so you can plot one line for each row number.
Since plotly will plot your xaxis categories alphabetically, you will want to relevel your name factor (name is your column names) to order of your columns.
In your plot_ly statement, use split to plot by row number.
library(plotly)
library(tidyverse)
a %>%
mutate(rn = row_number()) %>%
pivot_longer(cols = -rn, names_to = "name", values_to = "value") %>%
mutate(name = factor(name, levels = colnames(a))) %>%
plot_ly(x = ~name, y = ~value, split = ~rn, type = "scatter", mode = "lines")
Output
Data
a <- data.frame(
N_of_Brands = c(-.4, .8, -.4),
Brand_Runs = c(-.26, .70, -.75),
Total_Volume = c(-.69, .15, -.015),
No_of_Trans = c(-.81, .45, -.35)
)
I want to plot some timestamps with plotly bars, with 1 bar indicating a whole hour.
My problem is that the ticks are centered in the middle and I would like to shift them to the left end of the bars.
When the plot isn't zoomed in, it's not such a problem, but when zooming in, more tick-labels will appear and they would be wrong.
EDIT: I need the option barmode = 'overlay' as I also have other traces to plot, which are not included in this example.
The picture below illustrates my current and exptected layout and here's some data to make that plot. (Some option I tried without success are also included in the xaxis configuration but uncommented).
library(plotly)
library(lubridate)
df <- data.frame(
ts = seq(as.POSIXct("2019-03-20 00:00:00"), by = "hour", length.out = 24),
val = sample(1:100, 24)
)
plot_ly() %>%
add_bars(data = df, x = ~ts, y = ~val) %>%
layout(dragmode = "select", autosize = TRUE, selectdirection = "h",
barmode = 'overlay',
bargap = 0.05,
xaxis = list(ticks = "outside",
type = "date",
# tickson="boundaries",
# offset=1800,
tickmode = "auto",
title = ""
)) %>%
config(scrollZoom = TRUE)
Would the following meet your needs?
One of the things that I take advantage of sometimes with plotly is that you can show different values in text that are independent of your the x and y values used to plot the data.
In this case, we can create a column with an offset time value, ts_x and plot the x values a half hour past the time for each row -- If you have a column for every hour, this effectively left-aligns the bars.
library(plotly)
df <- data.frame(
ts = seq(as.POSIXct("2019-03-20 00:00:00"), by = "hour", length.out = 24),
val = sample(1:100, 24)
)
## Create a dummy column with x offset values
df$ts_x <- df$ts + 1800
plot_ly() %>%
## Plot based on the dummy column
add_bars(data = df, x = ~ts_x, y = ~val,
## Cover up our tracks by not showing true x value on hoverinfo
hoverinfo = "text",
## Give text that includes the un-altered time values
text = ~paste0("Time: ",format(ts, format = "%B %d, %Y %H:%M"),
"<br>Value: ",val)) %>%
layout(dragmode = "select", autosize = TRUE, selectdirection = "h",
barmode = 'overlay',
bargap = 0.05,
xaxis = list(ticks = "outside",
type = "date",
tickmode = "auto",
title = ""
)) %>%
config(scrollZoom = TRUE)
By default, bars are centered, I didn't find how to change this.
One alternative is to add a second bar, because when there are 2 bars for each x-axis unity, one bar is at the left of the axis tick, and the second at the right (what you are trying to obtain with one bar).
Why not creating a second invisible bar ? :)
df <- data.frame(
ts = seq(as.POSIXct("2019-03-20 00:00:00"), by = "hour", length.out = 24),
val = sample(1:100, 24),
val0 = 0
)
plot_ly(df, type = 'bar') %>%
add_trace(x = ~ts, y = ~val0) %>%
add_trace(x = ~ts, y = ~val) %>%
layout(
showlegend = FALSE
) %>%
config(scrollZoom = TRUE)
This will create a legend (as there are 2 kind of bars, ones for val and ones for val0), so I removed it.
Are you sure you are not over engineering? Subtracting 30 minutes gives me a nice graph when zooming in.
I'm not suggest you actually edit the data, even if it's what I'm doing in the code. A small function in the call to add bars could solve it? If you overlay other data it could make a mess but I just wanted to suggest it.
library(plotly)
library(lubridate)
df2 <- data.frame(
ts = seq(as.POSIXct("2019-03-20 00:00:00"), by = "hour", length.out = 24) - minutes(30),
val = sample(1:100, 24)
)
plot_ly() %>%
add_bars(data = df2, x = ~ts, y = ~val) %>%
layout(dragmode = "select", autosize = TRUE, selectdirection = "h",
barmode = 'overlay',
bargap = 0.05,
xaxis = list(ticks = "outside",
type = "date",
# tickson="boundaries",
# offset=1800,
tickmode = "auto",
title = ""
)) %>%
config(scrollZoom = TRUE)