How to create bar plot for characters in R - r

I have a data frame that looks like this
head(data1, 30)
date cur.gas
1 2015-01-01 00:00:45 RD
2 2015-01-01 00:02:45 RD
3 2015-01-01 00:04:45 RD
4 2015-01-01 00:06:45 RD
5 2015-01-01 00:08:45 RD
6 2015-01-01 00:10:45 RD
7 2015-01-01 00:12:45 RD
8 2015-01-01 00:14:45 RD
9 2015-01-01 00:16:45 RD
10 2015-01-01 00:18:45 RD
11 2015-01-01 00:20:45 RD
12 2015-01-01 00:22:45 RD
13 2015-01-01 00:24:45 RD
14 2015-01-01 00:26:45 RD
15 2015-01-01 00:28:45 RD
16 2015-01-01 00:30:45 RD
17 2015-01-01 00:40:45 BL
18 2015-01-01 00:42:45 BL
19 2015-01-01 00:44:45 BL
20 2015-01-01 00:46:45 BL
21 2015-01-01 00:48:45 BL
22 2015-01-01 00:50:45 BL
23 2015-01-01 00:52:45 BL
24 2015-01-01 00:54:45 BL
25 2015-01-01 00:56:45 BL
26 2015-01-01 00:58:45 BL
27 2015-01-01 01:00:45 BL
28 2015-01-01 01:46:45 RD
29 2015-01-01 01:50:45 RD
30 2015-01-01 01:52:45 RD
Where the cur.gas column indicated which line (Red (RD) or blue (BL)) is feeding the sample into the analyser. I want to create horizontal bar plot from this data that would show me the colour corresponding to the current line (red and blue).
I have tried using ggplot:
ggplot(data=data1, aes(x=0.1, y = date, col=cur.gas)) +
geom_bar(stat = "identity", width = 0.1) +
coord_flip() +
scale_fill_manual(values = c("red","blue")) +
theme(text = element_text(size = 10), axis.title = element_blank(), axis.text = element_blank(),
axis.ticks = element_blank())
And the output plot looks like this:
Which looks horible, and the colours are wrong (the legend gives red colour for BL and blue for RD).
Then I tried the barplot function:
attach(data1)
barplot(date,names.arg=cur.gas, horiz = TRUE, col = c("blue", "red"), legend = rownames(data1$cur.gas))
and I got this error:
Error in barplot.default(date, names.arg = cur.gas, horiz = TRUE, col = c("blue", :
'height' must be a vector or a matrix
I'm lost now. What should I do? Thanks a lot1

What barplot wants is INTERVALS.
data[,"end_date"] <- c(data[-1,1], as.POSIXct("2015-01-01 01:54:45")) # I deciced a last value arbitrarily
data[,"interval"] <- difftime(data$end_date, data$date)
difftime(data$date[1], tail(data$end_date, n=1), units="min") # total 114 min
barplot(matrix(data$interval, ncol=1), horiz=T, col=c(2,4)[data$cur.gas], axes=F)
axis(1, at=seq(0,114,10), las=2, cex.axis=0.8, # If you don't need border, add border=NA
labels=format(seq(data[1,1], tail(data$end_date, n=1), by="10 min"),"%H:%M:%S"))
But it is more easy to use geom_rect() (this code needs end_date)
ggplot(data) +
geom_rect(aes(xmin=date, xmax=end_date, ymin=0, ymax=1, fill=cur.gas), colour="black") +
theme(axis.text.y=element_blank(), axis.ticks.y=element_blank()) + labs(x="time")
# if you don't need border, delete colour="black".

Related

How to use geom_rect to highlight specified facets

I have a facet plot that I need to place a rectangle in or highlight 3 specific facets. Facets 5, 6, and 10. See Below:
I found some code referring to "geom_rect" that seems like it may work but it won't show up, also doesn't give me any error message. Here is the code:
weekly_TS_PDF<- ggplot(TS_stack, aes(x= TS_log, y = TS_depth, color= sentiment)) +
scale_y_reverse(limits= c(16,2), breaks= seq(16,2)) +
geom_rect(data = data.frame(Week = 5), aes(xmin = -65, xmax = -55, ymin = 1, ymax = 16), alpha = .3, fill="grey", inherit.aes = F) +
geom_point() + facet_grid(.~ Week) + geom_hline(data = week_avg_15E, aes(yintercept = x), linetype = "solid") +
ylab("Target Depth (m)") + xlab("Mean Target Strength (dB)") + ggtitle("Mean TS by Depth by Week (12 hour resolution)") +
guides(color=guide_legend("Year"))
Reprex data:
X TS_depth Group.1 x TS_log Date_time AMPM Week sentiment
1 1 9.593093 2020-12-01 18:00:00 5.390264e-07 -62.68390 2020-12-01 18:00:00 PM 5 Year 1
2 2 9.550032 2020-12-02 06:00:00 4.022841e-07 -63.95467 2020-12-02 06:00:00 AM 6 Year 1
3 3 9.677069 2020-12-02 18:00:00 6.277191e-07 -62.02235 2020-12-02 18:00:00 PM 7 Year 1
4 4 9.679256 2020-12-03 06:00:00 3.501608e-07 -64.55732 2020-12-03 06:00:00 AM 8 Year 1
5 5 9.606380 2020-12-03 18:00:00 6.698625e-07 -61.74014 2020-12-03 18:00:00 PM 9 Year 1
6 6 9.548408 2020-12-04 06:00:00 4.464622e-07 -63.50215 2020-12-04 06:00:00 AM 10 Year 1
I just need to highlight or put a rectangle in facets 5,6, and 10. Any help is appreciated.

geom_contour mark specific contour (isobar) value

I am attempting to plot sea level pressure (isobars) contour on an spatial area with 2mb spacing and want a specific isobar (1015) plotted as thicker line than the others and wonder if it is possible with other function and/or with ggplot/geom_conour related function.
Below the command I sued to plot the isobar. Now any idea on how to add a oommand for the 1015 isobar?
syn_plot <- ggplot() +
geom_tile(data = synclas_gather_df, aes(x=x, y=y, fill=value)) +
geom_sf(data = map_bg, fill="transparent")+
geom_contour2(data = synclas_gather_df, aes(x=x,y=y,z=value), binwidth = 2, color = "black") +
scale_fill_gradientn(colours = colorRamps::matlab.like2(100), name = "hPa",breaks=0:5) +
scale_colour_gradient(guide = 'none') + facet_wrap(~key, ncol = 4) +
scale_x_continuous(limits = c(-34,29), expand = c(0, 0))+
scale_y_continuous(limits = c(-9,34), expand = c(0,0))+
theme_bw() + theme(axis.title = element_blank(),
axis.text = element_blank(),
axis.ticks = element_blank())
syn_plot + geom_text_contour(data= synclas_gather_df,aes(x,y,z = value), stroke = 0.10,binwidth = 4,size=3)
data format:
time lon lat slp
1 1978-12-30 12:00:00 0 40 1015.
2 1978-12-30 12:00:00 2.5 40 1013.
3 1978-12-30 12:00:00 5 40 1012.
4 1978-12-30 12:00:00 7.5 40 1010.
5 1978-12-30 12:00:00 10 40 1007.
6 1978-12-30 12:00:00 12.5 40 1005.
7 1978-12-30 12:00:00 15 40 1004.
8 1978-12-30 12:00:00 17.5 40 1003.
9 1978-12-30 12:00:00 20 40 1002.
10 1978-12-30 12:00:00 22.5 40 1001.

Trying to remove an axis below x-axis using ggplot

I am new to ggplot and is trying to plot two lines using it. But my x-axis appeared to be very weird, and now i want to remove it. Here is my code.
ggplot(BJ11, aes(Date, mean,group=1)) +
geom_line(aes(color = "stateair daily values")) +
geom_line(data = bjvalue2,
aes(color = "CNEMC values"))
Here are my data:
> head(BJ11)
Date min max mean
1 2015-01-01 6 154 54.58333
2 2015-01-02 12 157 63.54167
3 2015-01-03 147 322 209.25000
4 2015-01-04 106 360 201.16667
5 2015-01-05 9 186 90.87500
6 2015-01-06 10 121 43.16667
> head(bjvalue2)
Date mean
1 2015-01-01 43
2 2015-01-02 52
3 2015-01-03 150
4 2015-01-04 176
5 2015-01-05 92
6 2015-01-06 40
what should i do to remove both the thick black axis above "Date" and the x-axis?
ggplot(BJ11, aes(Date, mean, group=1))+
geom_line(aes(color = "stateair daily values"))+
geom_line(data = bjvalue2, aes(color = "CNEMC values"))+
theme(axis.title.x = element_blank(),
axis.text.x = element_blank(),
axis.ticks.x = element_blank(),
axis.line.x = element_blank())
Another option would be to fix your x-axis instead of removing it. I know it is not your question, but ggplot is very good in handling date-axis, so I'm wondering if you have dates as characters? If you have then eg. library(lubridate) with ymd() can be used.
I'm guessing your group=1 could be omitted for simplicity.
Also, in your last line I'd personally prefer defining the x and y axis inside the aes to make sure R handles the data the way you want.

ggTimeSeries Manual Continuous Colour

My df:
prod
# A tibble: 695 × 3
REPORT_DATE UNIT PROD
<date> <chr> <dbl>
1 2015-03-28 DEP11 2.043962
2 2015-03-29 DEP11 2.788490
3 2015-03-30 DEP11 2.795274
4 2015-03-31 DEP11 3.100589
5 2015-04-01 DEP11 2.882843
6 2015-04-02 DEP11 2.987861
7 2015-04-03 DEP11 3.123047
8 2015-04-04 DEP11 3.264180
9 2015-04-05 DEP11 2.987729
10 2015-04-06 DEP11 3.222573
# ... with 685 more rows
I created a ggTimeSeries plot as below:
I want to change the colour scheme...and want to divide the colour into 3 categories:
below 3.0 = red
3.0 - 3.2 = amber
greater than 3.2 = green
I have tried the following:
ggplot_calendar_heatmap(
prod,
'REPORT_DATE',
'PROD'
) +
xlab('') +
ylab('') +
scale_fill_continuous(low = 'red', high = 'green') +
facet_wrap(~Year, ncol = 1)
also tried to use scale_colour_gradientn and scale_colour_manuel but no luck... any ideas?
Something like this should work:
set.seed(1)
# generate some random data
prod <- data.frame(REPORT_DATE=seq.Date(as.Date('2015/01/03'), as.Date('2017/02/28'), by='day'))
prod$PROD <- runif(nrow(prod), 0, 5)
prod <- transform(prod, PROD.cut=cut(PROD, breaks=c(-Inf,3, 3.2,Inf))) # bin data
library(ggTimeSeries)
ggplot_calendar_heatmap(
prod,
'REPORT_DATE',
'PROD.cut'
) +
xlab('') +
ylab('') +
scale_fill_manual(values = c("red", "orange", "green")) +
#scale_fill_continuous(low = 'red', high = 'green') +
facet_wrap(~Year, ncol = 1)

fill a heat map (24h by 7days) in ggplot2

I have bike data that looks like this - the dimensions of the data frame are large.
> dim(All_2014)
[1] 994367 10
> head(All_2014)
X bikeid end.station.id start.station.id diff.time stoptime starttime
1 1 16379 285 356 338387 2014-01-02 15:22:28 2014-01-06 13:22:15
2 2 16379 361 146 47631 2014-01-09 22:45:34 2014-01-10 11:59:25
3 3 16379 268 327 5089 2014-01-10 12:35:22 2014-01-10 14:00:11
4 4 16379 398 324 715924 2014-01-22 14:34:55 2014-01-30 21:26:59
5 5 15611 536 445 716031 2014-01-02 15:30:44 2014-01-10 22:24:35
6 6 15611 348 433 68544 2014-01-12 14:03:01 2014-01-13 09:05:25
midtime Hour Day
1 2014-01-04 14:22:21 14 Saturday
2 2014-01-10 05:22:29 5 Friday
3 2014-01-10 13:17:46 13 Friday
4 2014-01-26 18:00:57 18 Sunday
5 2014-01-06 18:57:39 18 Monday
6 2014-01-12 23:34:13 23 Sunday
My aim is to create a heat map using ggplot2 (or another package if it is better suited) that looks like this one, where day of the week is on the y-axis and hour is on the x-axis (the hour does not have to be in AM/PM, it can remain as is on the 24-hour scale.:
The fill of the boxes is a percentage that represents the amount of rides taken within a given hour-interval/the total rides on that day of the week. I have managed to get this far with the data, but would like to know the easiest way to find percentages and then, how to create a heat map with them.
Using dplyr to do the calculations, and ggplot2 to do the chart:
library(dplyr)
library(ggplot2)
## First siimulate some data
rider_num <- 1:10000
days <- factor(c("Sun", "Mon", "Tues", "Wed", "Thur", "Fri", "Sat"),
levels = rev(c("Sun", "Mon", "Tues", "Wed", "Thur", "Fri", "Sat")),
ordered = TRUE)
day <- sample(days, 10000, TRUE,
c(0.3, 0.5, 0.8, 0.8, 0.6, 0.5, 0.2))
hour <- round(rbeta(10000, 1, 2, 6) * 23)
df <- data.frame(rider_num, hour, day)
## Use dplyr functions to summarize on days and hours to get the
## percentage of riders per hour each day:
df2 <- df %>%
group_by(day, hour) %>%
summarise(n=n()) %>%
mutate(percent_of_riders=n/sum(n)*100)
## Plot using ggplot and geom_tile, tweaking colours and theme elements
## to your liking:
ggplot(df2, aes(hour, day)) +
geom_tile(aes(fill = percent_of_riders), colour = "white") +
scale_fill_distiller(palette = "YlGnBu", direction = 1) +
scale_x_discrete(breaks = 0:23, labels = 0:23) +
theme_minimal() +
theme(legend.position = "bottom", legend.key.width = unit(2, "cm"),
panel.grid = element_blank()) +
coord_equal()
Using #andyteucher's df2, here's a lattice approach:
library(lattice)
library(RColorBrewer)
levelplot(percent_of_riders~hour+day, df2,
aspect='iso', xlab='', ylab='', border='white',
col.regions=colorRampPalette(brewer.pal(9, 'YlGnBu')),
at=seq(0, 12, length=100), # specify breaks for the colour ramp
scales=list(alternating=FALSE, tck=1:0, x=list(at=0:23)))
One simple way to replace missing data (e.g. Sunday at midnight) with zero is to pass an xtabs object to levelplot instead:
levelplot(xtabs(percent_of_riders ~ hour+day, df2), aspect='iso', xlab='', ylab='',
col.regions=colorRampPalette(brewer.pal(9, 'YlGnBu')),
at=seq(0, 12, length=100),
scales=list(alternating=FALSE, tck=1:0),
border='white')
You can also use d3heatmap for interactivity:
library(d3heatmap)
xt <- xtabs(percent_of_riders~day+hour, df2)
d3heatmap(xt[7:1, ], colors='YlGnBu', dendrogram = "none")

Resources