Change x-axis names in ggplot - r

I am not very good in R, and need some help.
My ggplot has a lot of dates(in the x-axis) so you can't actually see the dates, and I want to change it to months to give a better overview of the plot.
For example to something like this in the link:
Display the x-axis on ggplot as month only in R
This is the script I'm using:
r <- read.csv("xxdive.csv", header = T, sep = ";")
names(r) <- c("Date", "Number")
r <- data.frame(r)
r$Date <- factor(r$Date, ordered = T)
r[1:2, ]
Date Number
16.02.2015 97
17.02.2015 47
library(tidyverse)
ggplot(r, aes(Date, Number)) +
theme_light() +
ggtitle("16.02.15-10.02.16") +
ylab("Dives") +
geom_line(aes(group = 1), color = "blue")
This shows what kind of data I have.
I have tried using scale etc, but I can't make it work..
I hope this was understandable, and that someone can help me!! :)

I would convert column Date to data type Date
r$Date <- as.Date(r$Date, "%d.%m.%Y");
instead of converting it to data type factor.
r$Date <- factor(r$Date, ordered = T);

It's a little tricky without a working example, but try this.
install.packages("tidyverse")
library(tidyverse)
r <- read_delim("xxdive.csv", ";", col_types = list(col_date(), col_integer()))
names(r) <- c("Date", "Number")
ggplot(r, aes(Date, Number)) +
geom_line(aes(group = 1), color = "blue") +
scale_x_date(date_breaks = "1 month") +
ylab("Dives") +
ggtitle("16.02.15-10.02.16") +
theme_light()

Related

ggplot2, x-axis not recognizing dates

Trying to plot the following data frame (call it bob):
1
Since the original date is in d/m/y, I use Finaldate and Value to graph.
Here is the code used to graph:
ggplot(Bob, aes(Finaldate, Value)) +geom_line() + geom_point(size = 3) +
labs(title = "TITLE",subtitle = "SUBTITLE", y = "Y", x = "X") +
theme_fivethirtyeight()+scale_y_continuous(name="name", labels = scales::comma)+theme(legend.title = element_blank())+scale_x_discrete(guide = guide_axis(check.overlap = TRUE))
While I do get an output, it is not as a time series but rather the dates are not in order and the plot makes no sense. Attached a copy of the plot as well.
enter image description here
Not sure how to fix this problem, and have tried a couple of different things
Have you tried using
+ scale_x_date(date_labels = "%d %m %Y") (ggplot2)
https://r-graph-gallery.com/279-plotting-time-series-with-ggplot2.html
You need to convert Finaldate to a date -- it is being treated as a character so all the dates are in "alphabetical" order. Try:
Bob$finalDate <- as.Date(Bob$finalDate, format = "%m/%d/%Y")

How to make funnel chart with bars in R ggplot2?

I want to make a funnel chart in R with ggplot2 as following:
https://chartio.com/assets/c15a30/tutorials/charts/funnel-charts/c7cd4465bc714689646515692b6dbe7c74ae7550a265cd2d6a530f1f34d68ae1/funnel-chart-example.png
My code looks like this, but I don't know how to do the the light blue fills between the bars. (maybe with polygon?)
library(ggplot2)
library(reshape2) # for melt()
library(dplyr)
# get data
dat <- read.table(text=
"steps numbers rate
clicks 332835 100.000000
signup 157697 47.379933
cart 29866 8.973215
buys 17012 5.111241",
header = T)
barWidth <- 0.9
# add spacing, melt, sort
total <- subset(dat, rate==100)$numbers
dat$padding <- (total - dat$numbers) / 2
molten <- melt(dat[, -3], id.var='steps')
molten <- molten[order(molten$variable, decreasing = T), ]
molten$steps <- factor(molten$steps, levels = rev(dat$steps))
ggplot(molten, aes(x=steps)) +
geom_bar(aes(y = value, fill = variable),
stat='identity', position='stack') +
geom_text(data=dat,
aes(y=total/2, label= paste(round(rate), '%')),
color='white') +
scale_fill_manual(values = c('grey40', NA) ) +
coord_flip() +
theme(legend.position = 'none') +
labs(x='steps', y='volume')
I needed the same but hadn't found one, so I created a function to do so. It might need some improvements, but it is working well. The example below shows only numbers, but you can also add texts.
x <- c(86307,
34494,
28127,
17796,
12488,
11233
)
source("https://gist.github.com/jjesusfilho/fd14b58becab4924befef5be239c6011")
gg_funnel(x, color = viridisLite::plasma(6))
This should be just a comment, since you explicitly asked for a ggplot solution, which this is not - I posted it as an answer purely for reasons of code formatting.
You could consider plotly, which has a funnel type. Something like
library(plotly)
dat %>% mutate(steps=factor(steps, unique(steps)),
rate=sprintf("%.2f%%", rate)) %>%
plot_ly(
type = "funnel",
y = ~steps,
text= ~rate,
x = ~numbers)
could get you started; I do not really grasp the padding you have in your data, so this might not be exactly what you want.

ggplot2 comparation of time period

I need to visualize and compare the difference in two equally long sales periods. 2018/2019 and 2019/2020. Both periods begin at week 44 and end at week 36 of the following year. If I create a graph, both periods are continuous and line up. If I use only the week number, the values ​​are sorted as continuum and the graph does not make sense. Can you think of a solution?
Thank You
Data:
set.seed(1)
df1 <- data.frame(sells = runif(44),
week = c(44:52,1:35),
YW = yearweek(seq(as.Date("2018-11-01"), as.Date("2019-08-31"), by = "1 week")),
period = "18/19")
df2 <- data.frame(sells = runif(44),
week = c(44:52,1:35),
YW = yearweek(seq(as.Date("2019-11-01"), as.Date("2020-08-31"), by = "1 week")),
period = "19/20")
# Yearweek on x axis, when both period are separated
ggplot(df1, aes(YW, sells)) +
geom_line(aes(color="Period 18/19")) +
geom_line(data=df2, aes(color="Period 19/20")) +
labs(color="Legend text")
# week on x axis when weeks are like continuum and not splited by year
ggplot(df1, aes(week, sells)) +
geom_line(aes(color="Period 18/19")) +
geom_line(data=df2, aes(color="Period 19/20")) +
labs(color="Legend text")
Another alternative is to facet it. This'll require combining the two sets into one, preserving the data source. (This is commonly a better way of dealing with it in general, anyway.)
(I don't have tstibble, so my YW just has seq(...), no yearweek. It should translate.)
ggplot(dplyr::bind_rows(tibble::lst(df1, df2), .id = "id"), aes(YW, sells)) +
geom_line(aes(color = id)) +
facet_wrap(id ~ ., scales = "free_x", ncol = 1)
In place of dplyr::bind_rows, one might also use data.table::rbindlist(..., idcol="id"), or do.call(rbind, ...), though with the latter you will need to assign id externally.
One more note: the default formatting of the x-axis is obscuring the "year" of the data. If this is relevant/important (and not apparent elsewhere), then use ggplot2's normal mechanism for forcing labels, e.g.,
... +
scale_x_date(labels = function(z) format(z, "%Y-%m"))
While unlikely that you can do this without having tibble::lst available, you can replace that with list(df1=df1, df2=df2) or similar.
If you want to keep the x axis as a numeric scale, you can do:
ggplot(df1, aes((week + 9) %% 52, sells)) +
geom_line(aes(color="Period 18/19")) +
geom_line(data=df2, aes(color="Period 19/20")) +
scale_x_continuous(breaks = 1:52,
labels = function(x) ifelse(x == 9, 52, (x - 9) %% 52),
name = "week") +
labs(color="Legend text")
Try this. You can format your week variable as a factor and keep the desired order. Here the code:
library(ggplot2)
library(tsibble)
#Data
df1$week <- factor(df1$week,levels = unique(df1$week),ordered = T)
df2$week <- factor(df2$week,levels = unique(df2$week),ordered = T)
#Plot
ggplot(df1, aes(week, sells)) +
geom_line(aes(color="Period 18/19",group=1)) +
geom_line(data=df2, aes(color="Period 19/20",group=1)) +
labs(color="Legend text")
Output:

How to show the ticks' labels on an axis while having single data point in R using ggplot?

I have a dataframe with one row, i'd like to show it when the horizontal axis is of type datetime. for some reason when I have a single dot, there are no ticks on the horizontal axis.
table_hr_tags_per_bin <- data.frame(matrix(c("2018-11-21 12:40:35", "25"),nrow = 1,ncol = 2))
colnames(table_hr_tags_per_bin) <-c('StartTimeStamp', 'cars')
plot_conf = ggplot() +
geom_point(data = table_hr_tags_per_bin, aes_string(x='StartTimeStamp', y= "cars"),colour = "red", size=3) +
labs(subtitle="plot_name",
y="y_axis_name",
x="Time",
title="my mitle",
caption = "") +
theme(axis.text.x = element_text(angle = 80, hjust = 1)) +
scale_x_datetime(date_breaks = paste0(4," sec"), label=function(x) substr(x,12,19))+
scale_y_continuous(breaks=waiver())
plot(plot_conf)
The problematic output is shown below:
Any suggestion would be helpful!
Maybe I am wrong in anticipating what you mean, if not, I think your datetime and scale_x_datetime use is not right.
If you use lubridate package and the right format for dates, it probably is much easier to get what you want. I have added a second date with a second value for coming nearer to what you wanted with just showing one single point.
library(lubridate)
df <- tibble(dt=c("2018-11-21T12:40:35",
"2018-11-22T12:41:35"),
value=c("25", "26"))
ggplot(df %>% filter(dt < "2018-11-22T12:41:35"), aes(dt, value)) + geom_point()

ggplot2 graphic with several x variable?

I need help for a R graphic issue with ggplot2.
Lets take an example :
date <- c("oct", "dec")
min.national <- c(17, 20)
min.international <- c(11, 12)
min.roaming <- c(5, 7)
mb.national <- c(115, 150)
mb.international <- c(72, 75)
mb.roaming <- c(30, 40)
df <- data.frame(min.national, min.international, min.roaming, mb.national, mb.international, mb.roaming)
What I want is to have two graphic one for the minutes and one for the megabytes sideline. And to get bars for the three variable (for the minutes in national, international and roaming for example) on the same graphic with fill = date ?
Is it clear for you ?
Thanks
I appreciate there may be a language challenge here, and it sounds like you're just getting started with ggplot2 so not sure how to get started on this, so I hope you find this useful.
It makes sense to treat the minutes and mb separately; they're different units. So I'll just use the minutes as an example. What I understand you're trying to achieve is easy with the right approach and the tidyr library.
library(tidyr)
library(ggplot2)
#first get your data in a data frame
min.df <- data.frame(national = min.national, international = min.international, roaming = min.roaming, month = date)
#now use the tidyr function to create a long data frame, you should recognize that this gives you a data structure readily suited to what you want to plot
min.df.long <- gather(min.df, "region", "minutes", 1:3)
ggplot(min.df.long) + geom_bar(aes(x = region, y = minutes, fill = month), stat = "identity")
If you want the months side by side, as I understand your question, then you could do:
ggplot(min.df.long) + geom_bar(aes(x = region, y = minutes, fill = factor(month, levels = c("oct", "dec"))), position = "dodge", stat = "identity") + labs(fill = "month")
The key parameter is the position keyword, the rest is just to make it neater.
df <- data.frame(date, min.national, min.international, min.roaming, mb.national, mb.international, mb.roaming)
df.stk <- tidyr::separate(melt(df), col="variable", into=c("min_byte", "type"), sep="\\.")
plt <- ggplot(df.stk, aes(type, value, fill = date)) +
geom_bar(stat = "identity") +
facet_grid(.~min_byte)
print(plt)

Resources