I have a matrix with three variables Row = Time, column = Date and the third variable Money which its value is an intersection of rows and columns. e.g. For Time = 5 and Date = 10, Money is 12 and for Time = 6 and Date = 15, Money is 15. I would like to draw the value of Money for the intersection of x_axis = Time and Y_axis = Date.
How to place Money in below?
plot.new()
matplot(Time,Date, type = "p", lty = 1:5, lwd = 1, lend = par("lend"),col = 1,
pch = 17 , xlab = "Time", ylab = "Date", xlim = range(0,40), ylim = range (0,120))
I think you could use geom_raster if you convert your data to a data.frame first:
ggplot(data, aes(Time, Date)) +
geom_raster(aes(fill = Money))
See more on this here: http://docs.ggplot2.org/current/geom_tile.html
edit:
see with random data here:
time <- c(1:100)
date <- c(1:100)
data <- expand.grid(TIME = time, DATE = date)
data$MONEY <- runif(1:10000, 0, 10)
ggplot(data, aes(TIME, DATE)) +
geom_raster(aes(fill = MONEY), interpolate = F)
Related
I am attempting to plot the blood test results for a patient in a time series. I have managed to do this and included a reference range between two shaded y-intercepts. My problem is that the annotate() or geom_segment() calls want me to specify, in the units of my independent variable, which is, unhelpfully, a date (YYYY-MM-DD).
Is it possible to get R to ignore the units of the x- and y-axis and specify the arrow co-ordinates as if they were on a grid?
result <- runif(25, min = 2.0, max = 3.5)
start_date <- ymd("2021-08-16")
end_date <- ymd("2022-10-29")
date <- sample(seq(start_date, end_date, by = "days"), 25, replace = TRUE)
q <- data.table(numbers, date)
ggplot(q, aes(x = date, y = result)) +
geom_line() +
geom_point(aes(x = date, y = result), shape = 21, size = 3) +
scale_x_date(limits = c(min(q$date), max(q$date)),
breaks = date_breaks("1 month"),
labels = date_format("%b %Y")) +
ylab("Corrected calcium (mmol/L")+
xlab("Date of blood test") +
ylim(1,4)+
geom_ribbon(aes(ymin=2.1, ymax=2.6), fill="grey", alpha=0.2, colour="grey")+
geom_vline(xintercept=as.numeric(q$date[c(3, 2)]),
linetype=4, colour="black") +
theme(axis.text.x = element_text(angle = 45)) + theme_prism(base_size = 10) +
annotate("segment", x = 1, y = 2, xend = 3, yend = 4, arrow = arrow(length = unit(0.15, "cm")))
The error produced is Error: Invalid input: date_trans works with objects of class Date only.
I can confirm that:
> class(q$date)
[1] "Date"
I've just gone with test co-ordinates (1,2,3,4) for the annotate("segment"...), ideally I want to be able to get the arrow to point to a specific data point on the plot to indicate when the patient went on treatment.
Many thanks,
Sandro
You don't need to convert to points or coordinates. Just use the actual values from your data frame. I am just subsetting within annotate using a hard coded index (you can also automate this of course), but you will need to "remind" R that you are dealing with dates - thus the added lubridate::as_date call.
library(ggplot2)
library(lubridate)
result <- runif(25, min = 2.0, max = 3.5)
start_date <- ymd("2021-08-16")
end_date <- ymd("2022-10-29")
date <- sample(seq(start_date, end_date, by = "days"), 25, replace = TRUE)
q <- data.frame(result, date)
## I am arranging the data frame by date
q <- dplyr::arrange(q, date)
ggplot(q, aes(x = date, y = result)) +
geom_line() +
## for start use a random x and y so it starts whereever you want it to start
## for end, use the same row from your data frame, in this case row 20
annotate(geom = "segment",
x = as_date(q$date[2]), xend = as_date(q$date[20]),
y = min(q$result), yend = q$result[20],
arrow = arrow(),
size = 2, color = "red")
I am trying to generate a scatter plot where the x-axis is several categories of a continuous variable. The closest thing to it would be a Manhattan plot, where the x-axis is split by chromosome (categorical), but within each category the values are continuous.
Data:
chr <- sample(x = c(1,2), replace = T, size = 1000)
bp <- as.integer(runif(n = 1000, min = 0, max = 10000))
p <- runif(n = 1000, min = 0, max = 1)
df <- data.frame(chr,bp,p)
Starting Point:
ggplot(df, aes(y = -log10(p), x =bp)) + geom_point(colour=chr)
The red and black points should be separate categories along the x-axis.
I am not sure if I have understood your question. Probably you are looking for facets. See the example.
require(ggplot2)
chr <- sample(x = c(1,2), replace = T, size = 1000)
bp <- as.integer(runif(n = 1000, min = 0, max = 10000))
p <- runif(n = 1000, min = 0, max = 1)
df <- data.frame(chr,bp,p)
ggplot(df, aes(y = -log10(p), x = bp)) +
geom_point(aes(colour = factor(chr))) +
facet_wrap("chr")
If you really want to do this in a single plot instead of facets, you could conditionally rescale your x variable and then manually adjust the labels, e.g.:
df %>%
mutate(bp.scaled = ifelse(chr == 2, bp + 10000, bp)) %>%
ggplot(aes(y = -log10(p), x = bp.scaled)) + geom_point(colour=chr) +
scale_x_continuous(breaks = seq(0,20000,2500),
labels = c(seq(0,10000,2500), seq(2500,10000,2500)))
Result:
I am trying to display the daily and weekly RSI on the daily charts but have no success
getSymbols('JNUG')
chartSeries(JNUG, subset = 'last 4 months', dn = 'red', TA = 'addRSI(n=14); addLines(h = c(30, 70), on = 2, col = "red"); addTA(RSI(Cl(to.weekly(JNUG)), n =2))')
I also tried the following:
chartSeries(JNUG, subset = 'last 4 months', dn = 'red', TA = 'addRSI(n=14); addLines(h = c(30, 70), on = 2, col = "red")')
addTA(RSI(Cl(to.weekly(JNUG)), n =14))
The weekly RSI does not appear on the plot. Can someone help.
When you plot the weekly points, NA values are filled in between on the merge to the original daily data. The weekly RSI plot wants to join together points and NAs as a line plot, but no line is drawn where there are NAs, no line gets drawn in the end.
Try this:
chartSeries(JNUG, subset = 'last 4 months', dn = 'red', TA = 'addRSI(n=14); addLines(h = c(30, 70), on = 2, col = "red"); addTA(RSI(Cl(to.weekly(JNUG)), n =2), type = "p")')
Or, if you want lines instead, try this (see lowest add_TA call):
library(quantmod)
chart_Series(JNUG, subset = '2016-11/')
add_RSI(n= 14)
v <- to.weekly(JNUG)
add_TA(merge(xts(order.by = index(JNUG)), RSI(Cl(v))), type = 'p')
#na.spline interpolates between points smoothly. Could also use fill = na.locf (produces a step function), etc ...
add_TA(merge(xts(order.by = index(JNUG)), RSI(Cl(v)), fill = na.spline), type = 'l')
which produces this:
EDIT: One way to add horizontal lines on add_TA subplots:
chart_Series(JNUG, subset = '2016-01/')
add_RSI(n= 14)
v <- to.weekly(JNUG)
# Note: na.locf does not introduce 'lookforward bias' in visualised technical indicator plots, while na.spline does.
add_TA(merge(xts(order.by = index(JNUG)), RSI(Cl(v)), fill = na.locf), type = 'l')
low_rsi <- 30
hi_rsi <- 70
xrsi_low <- xts(order.by = index(JNUG), x = rep(low_rsi, NROW(JNUG)))
xrsi_hi <- xts(order.by = index(JNUG), x = rep(hi_rsi, NROW(JNUG)))
add_TA(xrsi_low, col = "purple", type = 'l', on = 3, lty = 2)
add_TA(xrsi_hi, col = "purple", type = 'l', on = 3, lty = 4)
I have a plot like this:
Which was created with this code:
# Make data:
set.seed(42)
n <- 1000
df <- data.frame(values = sample(0:5, size = n, replace = T, prob = c(9/10, rep(0.0167,5))),
group = rep(1:100, each = 10),
fill2 = rep(rnorm(10), each = 100),
year = rep(2001:2010, times = 100)
)
df$values <- ifelse(df$year %in% 2001:2007 == T, 0, df$values)
# Plot
require(ggplot2)
p <- ggplot(data = df, aes(x = year, y = values, colour = as.factor(group))) + geom_line()
p
Since there are so many groups, the legend is really not helpfull.
Ideally I would like just two elements in the legend, one for group = 1 and for all the other groups (they should all have the same color). Is there a way to force this?
you can define a new variable that has only two values, but still plot lines according to their original group,
ggplot(data = df, aes(x = year, y = values, group = group,
colour = ifelse(group == 1, "1", "!1"))) +
geom_line() +
scale_colour_brewer("groups", palette="Set1")
I'm trying to "capture" some points within a bar.
The points represent 36 values on a monthly basis for 3 years.
The bars represent 3 values on a yearly basis for the same 3 years.
If you run the code you can see that some point of the first year are maybe captured by the bar of the second year and that the points of the 3rd year are "running out" of the last bar.
How can I align the bars and the points?
library(ggplot2)
set.seed(1)
df.year <- data.frame(yeardate = seq(as.Date("2010-01-01"), by = "year", length.out = 3), datevalue = abs(rnorm(3)))
df.month <- data.frame(monthdate = seq(as.Date("2010-01-01"), by = "month", length.out = 36), datevalue = abs(rnorm(36)))
df.month$inyear <- format(df.month$monthdate, "%Y")
df.month
p <- ggplot()
p <- p + geom_point(
data = df.month
,aes(x = monthdate, y = datevalue, color=inyear)
)
p <- p + geom_bar(
data = df.year
,aes(x = yeardate, y = datevalue)
,alpha=0.7
,stat = "identity"
)
p + scale_x_date(labels = date_format("%Y"), breaks = date_breaks("years"))
geom_bar is centering the bars on the dates given. Since the given dates are the first of the year, it is centered around the first of the year, and so much of 2012 lies outside the bar centered on 2012-01-01 (and much of that bar lies in 2011). So either center the bars in the middle of the year:
df.year <- data.frame(yeardate = seq(as.Date("2010-07-01"),
by = "year",
length.out = 3),
datevalue = abs(rnorm(3)))
which gives
or draw rectangles with the exact extent that you want them to be
df.year <- data.frame(yearstart = seq(as.Date("2010-01-01"),
by = "year", length.out = 3),
yearend = seq(as.Date("2010-12-31"),
by = "year", length.out = 3),
datevalue = abs(rnorm(3)))
and replace the geom_bar call with
p <- p + geom_rect(
data = df.year
,aes(xmin = yearstart, xmax = yearend,
ymin = 0, ymax = datevalue)
,alpha=0.7
)
giving