Plotly or geom_smooth get lost date format? - r

I have multiple time-series plots. An example plot and code can be found below. I construct the plot using ggplot2 and make it interactive using ggplotly().
However, date format on the smoothed curve get lost. Interactive chart shows date as some numeric values.
How can I fix the problem?
Thank you very much
structure(list(Date = structure(c(15736, 15764, 15795, 15825,
15856, 15886), class = "Date"), CLI = c(99.93, 100.3, 100.96,
100.71, 100.62, 101.15)), row.names = c(NA, -6L), class = c("tbl_df",
"tbl", "data.frame"))
plot5 <- df %>%
ggplot(aes(x = Date, y = CLI))+
geom_line(size = 0.5, alpha = 0.75, show.legend = FALSE, color = "steelblue4")+
scale_x_date(date_breaks = "6 month", date_labels = "%m/%y")+
theme_pander()+
geom_line(stat='smooth', method = "glm", alpha=0.5, color = "firebrick2", formula = y ~ poly(x, 5))+
geom_ribbon(stat='smooth',method = "glm", se=TRUE,formula = y ~ poly(x, 5), alpha=0.01)+
labs(x = "Date",
y = "Composite Leading Indicator")
ggplotly(plot5)

Adapting my answer on this post to your case one option to get the date format in the tooltip would be to make use of the text aesthetic to manually create the tooltip and convert the numbers to proper dates like so:
plot <- df %>%
ggplot(aes(x = Date, y = CLI)) +
geom_line(size = 0.5, alpha = 0.75, show.legend = FALSE, color = "steelblue4") +
scale_x_date(date_labels = "%m/%y") +
# theme_pander()+
geom_line(aes(text = paste(
"date: ", as.Date(..x.., origin = "1970-01-01"), "<br>",
"y:", ..y..
)), stat = "smooth", method = "glm", alpha = 0.5, color = "firebrick2", formula = y ~ poly(x, 5)) +
geom_ribbon(stat = "smooth", method = "glm", se = TRUE, formula = y ~ poly(x, 5), alpha = 0.01) +
labs(
x = "Date",
y = "Composite Leading Indicator"
)
ggplotly(plot, tooltip = c("text"))

Related

wrapping the labels of legend in ggplot ZINB model

I need help in wrapping the labels of legend in ggplot. I tried various option including
str_wrap(model, width=20)
scale_colour_discrete(labels = function(x) str_wrap(x, width = 5))
guides(colour = guide_legend(nrow = 2))
but without any success
library(ggplot2)
ggplot(coefs, aes(x = estimate, y = term, colour = model)) +
geom_vline(xintercept = 1, lty = 1, color = "yellow", size = 1) +
geom_pointrange(aes(xmin = conf.low, xmax = conf.high),
position = position_dodge(width = 0.5)
) +
facet_wrap(~type, scale = "free") +
geom_text(aes(x = estimate, label = sprintf("%0.2f", estimate)), position = position_dodge(0.5), vjust = -0.5) +
labs(x = "gy", y = "age") +
scale_color_manual(
name = "Model",
labels = c("Fullfasdfasdfad-asdkljaflsdjfals;jfasdf", "Subadfasdfaasdfasdfasdfsdfasdfasf"),
values = c("dodgerblue4", "firebrick4")
)
Data
coefs <- structure(list(model = c(
"all_adj", "all_adj", "all_adj", "all_adj",
"adj_sub", "adj_sub"
), term = c(
"ageb", "agec", "ageb", "agec",
"ageb", "ageb"
), type = c(
"count", "count", "zero", "zero", "count",
"zero"
), estimate = c(
0.937781183281121, 1.09774595782208, 0.895560088459192,
0.891707940838411, 0.76445315191301, 1.01406754426526
), conf.low = c(
0.422176961883128,
0.319479297647212, 0.273199977915238, 0.132809852827134, 0.175087960312586,
0.186498610242251
), conf.high = c(
2.08309222699744, 3.77190696483063,
2.93568058885374, 5.98707878088866, 3.33768592898348, 5.51389087026671
)), row.names = c(NA, -6L), class = c("tbl_df", "tbl", "data.frame"))

Geom_label_repel not properly referencing to the sec.axis

I am working with a ggplot that has two axis: one for the geom_bar component, and the other for the geom_linecomponent. And for this, I am using the sec.axis() command.
I wanted to insert a box to provide the last value of the geom_line component, but I am struggling because I believe that while using the commmand geom_label_repel, the aesthetic being used, is referent to the geom_barcomponent.
I'll provide a similar data to illustrate what I am saying.
df <- data.frame(day = as.character(seq(from = 1, to = 100, by = 1)),
total = rbinom(n=100,30,0.5),
prop = runif(100))
df <- df %>% arrange(df, by = day)
df$`percentage` <- label_percent(accuracy = 0.01)(df$prop)
ggplot(data = df,
aes(x = day, y = total)) +
geom_bar(stat = "identity", fill = "lightgreen", width = 0.35) +
geom_line(data = df,
aes(x = day, y = (prop)*15, group = 1),
color = "red", size = 1,inherit.aes = TRUE) +
scale_y_continuous(
labels = function(x) format(x, scientific = FALSE),
#breaks = seq(from = 0, to = 10000000,by = 100000),
sec.axis = sec_axis(trans = ~./15,
name = "Secondary axis",
breaks = seq(from = 0, to = 10, by = 0.1),
scales::percent))+
theme(axis.text.x = element_text(angle = 90, vjust = 0.5))+
geom_label_repel(data=df[nrow(df),],
aes(x = day,
y = prop*1,
label = round(prop*100,2)),
color = 'red',
segment.alpha = 0.5) +
scale_x_discrete(expand = expansion(add = c(0, 7)))
Which outputs the following image:
As you can tell, it works well in regards to obtaining the last number of the prop column, which is intended, but it is not automatically placed beside the geom_line.
I have tried messing with the nudge_xand nudge_y commands but it didn't lead me to anywhere, given the fact that I want to have this "number placement" automatic.
Can anyone help?
The sec.axis is in some ways just decorative. ggplot is plotting everything by the main axis. To make the label follow the line, make the same transform as in your geom_line call (y = prop*15):
library(tidyverse)
library(ggrepel)
df <- data.frame(day = as.character(seq(from = 1, to = 100, by = 1)),
total = rbinom(n=100,30,0.5),
prop = runif(100))
df <- df %>% arrange(df, by = day)
df$`percentage` <- scales::label_percent(accuracy = 0.01)(df$prop)
ggplot(data = df,
aes(x = day, y = total)) +
geom_bar(stat = "identity", fill = "lightgreen", width = 0.35) +
geom_line(data = df,
aes(x = day, y = (prop)*15, group = 1),
color = "red", size = 1,inherit.aes = TRUE) +
scale_y_continuous(
labels = function(x) format(x, scientific = FALSE),
#breaks = seq(from = 0, to = 10000000,by = 100000),
sec.axis = sec_axis(trans = ~./15,
name = "Secondary axis",
breaks = seq(from = 0, to = 10, by = 0.1),
scales::percent))+
theme(axis.text.x = element_text(angle = 90, vjust = 0.5))+
geom_label_repel(data=df[nrow(df),],
aes(x = day,
y = prop*15,
label = round(prop*100,2)),
color = 'red',
segment.alpha = 0.5) +
scale_x_discrete(expand = expansion(add = c(0, 7)))
#> Warning: Using `size` aesthetic for lines was deprecated in ggplot2 3.4.0.
#> ℹ Please use `linewidth` instead.

How to add a label to horizontal line in ggplot 2 when x-axis is date?

I am trying to graph a temperature dataset using mean, max, and min temps by month over 2 years. The graph includes two horizontal temperature thresholds.
I have succeeded in creating a graph, but I want to add labels "9.9" and "12.97" to my 2 horizontal threshold lines, and am having trouble I think because the x-axis is a date.
Here is the dput() sample of my data (hob_m_cs1_sort):
structure(list(year = c(2021, 2021, 2021, 2021), month = c(2,
3, 4, 5), tmin_mean = c(10.625, 8.27870967741936, 7.78666666666667,
9.34225806451613), tmax_mean = c(15.255, 15.8003225806452, 16.869,
18.6835483870968), tmean = c(12.3655534638554, 11.5371012544803,
11.9291921296296, 13.5006406810036), date = structure(c(18659,
18687, 18718, 18748), class = "Date"), month_name = c("Feb",
"Mar", "Apr", "May")), row.names = c(NA, 4L), class = "data.frame")`
This is the code I have been using:
hob_m_cs1_sort %>% group_by(date) %>%
summarise(min = min(tmin_mean, na.rm = TRUE),
max = max(tmax_mean, na.rm = TRUE),
avg = mean(tmean,na.rm = TRUE)) %>%
gather(metric, value, -date) %>%
ggplot(.,aes(x = date, y = value,
group = metric, color = metric)) +
labs(color='Temperature') +
ggtitle ("Hakalau Monthly Temperatures: Pua 'Akala, 1510 m") +
theme(plot.title = element_text(hjust = 0.5)) +
xlab("Date") + ylab ("Temperature ( ºC )") +
scale_y_continuous(limits = c(2.5, 22.5), breaks = seq(5, 25, by = 5)) +
scale_x_date(date_breaks = "2 months", date_labels = "%b %Y") +
theme_ipsum() +
theme(axis.text.x=element_text(angle=60, hjust=1)) +
geom_line(aes(color = metric)) +
geom_hline(aes(yintercept=h, linetype = "Culex development"), colour= 'darkorange1') +
geom_hline(aes(yintercept=h2, linetype = "Avian malaria development"), colour= 'red') +
scale_linetype_manual(name = "Temperature Thresholds", values = c(2, 2),
guide = guide_legend(override.aes = list(color = c("red", "darkorange1")))) +
scale_color_manual(values = c("steelblue1", "navyblue", "darkturquoise"), breaks=c('max', 'avg', 'min'), labels=c('Max', 'Avg', 'Min'))
I am able to produce this graph, but no labels on the thresholds:
link below
I have tried these options but they are not producing labels for me:
geom_text(aes(0, h, label = h, vjust = - 1)) +
geom_text(aes(0, h2, label = h2, vjust = - 1)) +
geom_text(aes("2021-02-01", h, label = h)) +
geom_text(aes("2021-02-01", h2, label = h2)) +
annotate(y= 9.9, x = dmy("01/02/2021"), label="Normal Limit", geom = "label")
Please help!
Thanks :)
You need to remind R that you're dealing with dates. You can use lubridate::as_date. I've removed a good deal of code that wasn't necessary for the problem.
May I suggest using vectors for annotation instead, thus you will need only one call to annotate.
May I suggest the geomtextpath package and direct labelling of your lines with a proper label and not the value. Why? The value is already represented by the very height of the line. And the direct label will make it easier for the reader to understand the meaning of the line.
Smaller comments / suggestions in the code
library(tidyverse)
library(lubridate)
#> Loading required package: timechange
#>
#> Attaching package: 'lubridate'
#> The following objects are masked from 'package:base':
#>
#> date, intersect, setdiff, union
library(geomtextpath)
hob_m_cs1_sort <- structure(list(year = c(2021, 2021, 2021, 2021), month = c(2,
3, 4, 5), tmin_mean = c(10.625, 8.27870967741936, 7.78666666666667,
9.34225806451613), tmax_mean = c(15.255, 15.8003225806452, 16.869,
18.6835483870968), tmean = c(12.3655534638554, 11.5371012544803,
11.9291921296296, 13.5006406810036), date = structure(c(18659,
18687, 18718, 18748), class = "Date"), month_name = c("Feb",
"Mar", "Apr", "May")), row.names = c(NA, 4L), class = "data.frame")
h <- 9.9
h2 <- 12.97
## I like to store as a proper data frame if more than one manipulation step
hob_long <- hob_m_cs1_sort %>% group_by(date) %>%
summarise(min = min(tmin_mean, na.rm = TRUE),
max = max(tmax_mean, na.rm = TRUE),
avg = mean(tmean,na.rm = TRUE)) %>%
gather(metric, value, -date)
ggplot(hob_long, aes(x = date, y = value, group = metric, color = metric)) +
## removed aes, as specified in main ggplot call
geom_line() +
geom_hline(aes(yintercept=h, linetype = "Culex development"), colour= 'darkorange1') +
geom_hline(aes(yintercept=h2, linetype = "Avian malaria development"), colour= 'red') +
## do both in one call, use vectors
annotate("text", x = as_date(c("2021-02-01", "2021-02-01")), y = c(h, h2), label = c(h, h2))
## how I would do the plot
ggplot(hob_long, aes(x = date, y = value, group = metric, color = metric)) +
geom_line() +
geom_texthline(aes(yintercept=h, label = "Culex development"), lty = 2, colour= 'darkorange1') +
geom_texthline(aes(yintercept=h2, label = "Avian malaria development"), lty = 2, colour= 'red')
Created on 2023-01-18 with reprex v2.0.2

Combining geom_text with substitute doesn't work

I have the following dataset
structure(list(X = c(9.8186734, 19.6373468, 29.4560202, 39.2746936,
49.093367, 58.9120404, 68.7307138, 78.5493872, 88.3680606, 98.186734
), Y = c(1, 1, 1, 1, 1, 1, 1, 1, 1, 1), radii = c(530.595715856625,
530.595715856625, 524.270569515141, 520.785212389348, 524.423046929159,
524.777454042683, 523.089321742221, 522.852371975715, 523.124870390148,
522.612174462367), slope = c(-21.796356958782, -21.796356958782,
-21.796356958782, -21.796356958782, -21.796356958782, -21.796356958782,
-21.796356958782, -21.796356958782, -21.796356958782, -21.796356958782
)), row.names = c(NA, -10L), class = c("data.table", "data.frame"
), .internal.selfref = <pointer: 0x7f989f011ce0>, sorted = "Y")
and I am simply trying to print slope as a text to the figure as
str_slope <- c(substitute("Slope = "~sp~mu*"m/s", list(sp = sprintf("%2.1f", dt[!duplicated(slope), slope]))))
d_text <- data.table(x=2000, y=500, label = str_slope)
ggplot(dt, aes(x = X, y=radii)) +
geom_point()+
geom_smooth(method = "lm", level = 0.9999, se = TRUE)+
scale_colour_manual(values = getPalette) +
labs(x = "time (s)", y = expression("radius ["*mu*"m]"), color = "Speed [µm/s]") +
geom_text(data = d_text, aes(x = x, y = y, label = label))+
theme_default(legend.position = "none")
but I get something like this
Why is the text in str_slope not evaluated as an expression? How can I force ggplot to interpret it as an expression, so that the text will look like
For this type of plot annotation, you should use annotate(geom="text"...) rather than geom_text(). For how to generate the expression, you can use the parse=TRUE argument within annotate().
I think we're missing all your plot data, so here's an example with mtcars that incorporates the contents of str_slope in your example.
str_slope <- c(substitute("Slope = "~sp~mu*"m/s", list(sp = sprintf("%2.1f", dt[!duplicated(slope), slope]))))
p <- ggplot(mtcars, aes(x = wt, y = mpg)) + geom_point()
p + annotate(
"text", x=4, y=25,
label= str_slope, parse=TRUE)
For your information, geom_text() is designed to be used wherein one or more aesthetics are mapped to a data frame. If you have only one line of text you want to appear on the plot, you should use annotate(geom="text"...), which is used when you do not want to map any aesthetics to a data frame.

How to add long text and data to x tick labels using ggplot2

I am trying to replicate the bar plot as shown bellow.
Here is an example of the data frame. Where the y variable is tasa and the x variable is year, and the number showed in the text of each x tick label is inscripciones.
df <- structure(list(year = c("2018", "2019"), inscripciones = c(3038910, 3680696), tasa = c(88.9528707645112, 104.692208214133)), class = c("tbl_df", "tbl", "data.frame"), row.names = c(NA, -2L))
p <- ggplot(data = df, aes(x = year, y = tasa)) +
geom_bar(width = 0.4, stat = "identity", fill="orange")+
geom_text(aes(year, tasa + 5, label = round(tasa,2), fill = NULL), size=4)+
labs(x = NULL, y = NULL)+
scale_y_continuous(breaks = seq(0, 110, by = 10))+
theme_bw()
How can I add these long text including information from the dataframe to the x tick labels?
Firstly, your data & plot combination are not reproducible. I renamed annoh as year then create the plot p.
Then,scale_x_discrete with "\n" strings works when you want to skip lines;
long_text_1 <- 'Gün, senden ışık alsa\n da bir renge bürünse;\n
Ay, secde edip çehrene,\n yerlerde sürünse;\n
Her şey silinip\n kayboluyorken nazarımdan,\n
Yalnız o yeşil\n gözlerinin nuru görünse...'
long_text_2 <- 'Ruhun mu ateş,\nyoksa o gözler mi alevden?\n
Bilmem bu yanardağ\n ne biçim korla tutuştu?\n
Pervane olan kendini\n gizler mi hiç alevden?\n
Sen istedin ondan bu\n gönül zorla tutuştu.'
p <- ggplot(data = df, aes(x = year, y = tasa)) +
geom_bar(width = 0.4, stat = "identity", fill="orange")+
geom_text(aes(year, tasa + 5, label = round(tasa,2), fill = NULL), size=4)+
labs(x = NULL, y = NULL)+
scale_y_continuous(breaks = seq(0, 110, by = 10))+
theme_bw()+
scale_x_discrete(labels=c('2018'=long_text_1,'2019'=long_text_2))

Resources