Fail to add a linear trend line on a barplot in R - r

I have created a barplot using barplot and then I want to show the linear trend. I use abline but the linear trend line does not show in the figure. I wonder what the problem is. Thanks.
set.seed(100)
Mydata=rnorm(65)
Year=1950:2014
barplot(Mydata)
fit=lm(Mydata~Year)
abline(fit)
As #G5W points out, fit=lm(Mydata~I(Year-1950)). But the new problem is that the trend line is too "long". As shown in the second figure, the trend line goes beyond the barplot. Is there any advice?

If you can use ggplot:
library(ggplot2)
df <- data.frame(Mydata, Year)
ggplot(df, aes(x = Year, y = Mydata)) +
geom_bar(stat = "identity") +
geom_smooth(method = "lm")

To expand on #bouncyball's comment, use a higher value of line width (lwd) to resemble barplot if you want.
plot(Year, Mydata, type = 'h',lwd=5,col = "grey")
abline(fit, lty =2)
EDIT
First copy this function
barplot2 <- function(x, y, lty = 1, lwd = 1, col = "grey", border = "black"){
w = ((max(x) - min(x))/length(x)) * 0.75
plot(x, y, type = 'p', pch = NA, yaxt = "n", xaxt = "n", xlab = "", ylab = "")
for (i in 1:length(x)){
x1 = x[i] - w/2
x2 = x[i] + w/2
y1 = 0
y2 = y[i]
polygon(x = c(x1,x2,x2,x1), y = c(y1,y1,y2,y2), lty = lty, lwd = lwd, col = col, border = border)
}
}
Then make the barplot
barplot2(Year,Mydata)
Then add the ablineclip from plotrix library
ablineclip(fit, x1 = min(Year), x2 = max(Year), y1 = min(Mydata), y2 = max(Mydata))

Related

How to specify breaks for y axis in R plot

I have created the following fanchart using the fanplot package. I'm trying to add axis ticks and labels to the y axis, however it's only giving me the decimals and not the full number. Looking for a solution to display the full number (e.g 4.59 and 4.61) on the y axis
I am also unsure of how to specify the breaks and number of decimal points for the labels on the y-axis using plot(). I know doing all of this in ggplot2 it would look something like this scale_y_continuous(breaks = seq(min(data.ts$Index),max(data.ts$Index),by=0.02)) . Any ideas on how to specify the breaks in the y axis as well as the number of decimal points using the base plot() feature in R?
Here is a reproductible of my dataset data.ts
structure(c(4.6049904235401, 4.60711076016453, 4.60980084146652,
4.61025389170935, 4.60544515681515, 4.60889021700954, 4.60983993107244,
4.61091608826696, 4.61138799159174, 4.61294431148318, 4.61167545843765,
4.61208284263432, 4.61421991328081, 4.61530485425155, 4.61471465043043,
4.6155992084451, 4.61195799200607, 4.61178486640435, 4.61037927954796,
4.60744590947049, 4.59979957741728, 4.59948551500254, 4.60078678080182,
4.60556092645471, 4.60934962087565, 4.60981147563749, 4.61060477704678,
4.61158365084251, 4.60963435263623, 4.61018215733317, 4.61209710959768,
4.61231368335184, 4.61071363571141, 4.61019496497916, 4.60948652606191,
4.61068813487859, 4.6084092003352, 4.60972706132393, 4.60866915174087,
4.61192565195909, 4.60878767339377, 4.61341471281265, 4.61015272152397,
4.6093479714315, 4.60750965935653, 4.60768790690338, 4.60676463096309,
4.60746490411374, 4.60885670935448, 4.60686846708382, 4.60688947889575,
4.60867708110485, 4.60448791268212, 4.60387348166032, 4.60569806689426,
4.6069320880709, 4.6087143894128, 4.61059688801283, 4.61065399116698,
4.61071421014339), .Tsp = c(2004, 2018.75, 4), class = "ts")
and here is a reproductible of the code I'm using
# # Install and Load Packages
## pacman::p_load(forecast,fanplot,tidyverse,tsbox,lubridate,readxl)
# Create an ARIMA Model using the auto.arima function
model <- auto.arima(data.ts)
# Simulate forecasts for 4 quarters (1 year) ahead
forecasts <- simulate(model, n=4)
# Create a data frame with the parameters needed for the uncertainty forecast
table <- ts_df(forecasts) %>%
rename(mode=value) %>%
mutate(time0 = rep(2019,4)) %>%
mutate(uncertainty = sd(mode)) %>%
mutate(skew = rep(0,4))
y0 <- 2019
k <- nrow(table)
# Set Percentiles
p <- seq(0.05, 0.95, 0.05)
p <- c(0.01, p, 0.99)
# Simulate a qsplitnorm distribution
fsval <- matrix(NA, nrow = length(p), ncol = k)
for (i in 1:k)
fsval[, i] <- qsplitnorm(p, mode = table$mode[i],
sd = table$uncertainty[i],
skew = table$skew[i])
# Create Plot
plot(data.ts, type = "l", col = "#75002B", lwd = 4,
xlim = c(y0 - 2,y0 + 0.75), ylim = range(fsval, data.ts),
xaxt = "n", yaxt = "n", ylab = "",xlab='',
main = '')
title(ylab = 'Log AFSI',main = 'Four-Quarter Ahead Forecast Fan - AFSI',
xlab = 'Date')
rect(y0 - 0.25, par("usr")[3] - 1, y0 + 2, par("usr")[4] + 1,
border = "gray90", col = "gray90")
fan(data = fsval, data.type = "values", probs = p,
start = y0, frequency = 4,
anchor = data.ts[time(data.ts) == y0 - .25],
fan.col = colorRampPalette(c("#75002B", "pink")),
ln = NULL, rlab = NULL)
# Add axis labels and ticks
axis(1, at = y0-2:y0 + 2, tcl = 0.5)
axis(1, at = seq(y0-2, y0 + 2, 0.25), labels = FALSE, tcl = 0.25)
abline(v = y0 - 0.25, lty = 1)
abline(v = y0 + 0.75, lty = 2)
axis(2, at = range(fsval, data.ts), las = 2, tcl = 0.5)
range(blah) will only return two values (the minimum and maximum). The at parameter of axis() requires a sequence of points at which you require axis labels. Hence, these are the only two y values you have on your plot. Take a look at using pretty(blah) or seq(min(blah), max(blah), length.out = 10).
The suggestions of #Feakster are worth looking at, but the problem here is that the y-axis margin isn't wide enough. You could do either of two things. You could round the labels so they fit within the margins, for example you could replace this
axis(2, at = range(fsval, data.ts), las = 2, tcl = 0.5)
with this
axis(2, at = range(fsval, data.ts),
labels = sprintf("%.3f", range(fsval, data.ts)), las = 2, tcl = 0.5)
Or, alternatively you could increase the y-axis margin before you make the plot by specifying:
par(mar=c(5,5,4,2)+.1)
plot(data.ts, type = "l", col = "#75002B", lwd = 4,
xlim = c(y0 - 2,y0 + 0.75), ylim = range(fsval, data.ts),
xaxt = "n", yaxt = "n", ylab = "",xlab='',
main = '')
Then everything below that should work. The mar element of par sets the number of lines printed in the margin of each axis. The default is c(5,4,4,2).

R: Two graphs (boxplot and barplot) sharing one X-Axis

I am trying to match two graphs in such a way that the two graphs are located vertically above each other sharing one x Axis
I already tried to use ggplot but didn't succeed. I did not manage to rewrite the commands barplot() and plot() to ggplot() in such a way that the graphs still come out right.
I would be very grateful for any help!
That's the first plot:
plot(as.factor(DauerK_mcpM$Kulturkategorie),
DauerK_mcpM$Electivity,
ylim = c(-1,1),
ylab="Elektivitätsindex",
col = DauerK_mcpM$Farbe, xaxt = "n",
main = "Elektivität Männchen mit Dauer")
abline(h = 0, lty = 2)
x.labels <- gsub("^.*?)","",levels(as.factor(DauerK_mcpM$Kulturkategorie)))
breaks <- seq(1,length(x.labels), 1)
axis(1, labels = x.labels, at = breaks, las = 2, cex.axis = 1)
dev.off()
That's the second plot:
barplot(Dauer_pro_Kultur_prozentM,
beside = TRUE,
xaxt = "n", ylab="verbrachte Zeit [%]",
main = "Männchen", col = Dauer_pro_KulturW$Farbe)
x.labels <- gsub("^.*?)", "", levels(as.factor(Dauer_pro_KulturW$Kulturkategorie)))
length <- length(x.labels)*1.2
breaks <- seq(from = 0.7, to = length, 1.2)
axis(1, labels = x.labels, at = breaks, las = 2, cex.axis = 1)
dev.off()
This can be done in ggplot by adding an indicator column for the plot type and then faceting by that indicator:
library(tidyverse)
#create some data
set.seed(20181022)
data <- data.frame(x = letters[ceiling(runif(100, 0, 10))],
y = runif(100),
stringsAsFactors = FALSE)
#duplicate the data and add an indicator for the Plot Type
data <- data %>%
bind_rows(data) %>%
mutate(PlotType = rep(1:2, each = nrow(data)))
#Facet by the plot type and subset each geom
data %>%
ggplot(aes(x, y)) +
facet_grid(PlotType~., scales = "free")+
geom_boxplot(data = filter(data, PlotType == 1)) +
geom_bar(data = filter(data, PlotType == 2), stat = "identity")

Can I change the color of the surv.median.line in my Kaplan Meier plot using R ggsurvplot?

I use the script below to plot a Kaplan-Meier curve.
I think that the median survival line is a great tool. However, the median survival line is drawn as a dashed black line, which is graphically overwhelming. Can I change the color or the opacity of the survival line to decrease the graphic output from the surv.median.line function?
If not, can I manually add a vertical/horizontal median survival line in which I can change the color or the opacity?
j <- ggsurvplot(
fit,
data = p,
#fun="cumhaz",
risk.table = "abs_pct", #risk.table.col="strata",
pval = TRUE,
pval.coord = c(0, 0.25),
conf.int = T,
#legend.labs=c("0-4%", "5-9%", "\u226510%"),
cumevents.title = "Cumulative number of recurrences",
size=c(0.8,0.8,0.8,0.8),
xlim = c(0,10),
alpha=0.8,
break.x.by = 1,
xlab="Time in years",
ylab="Probability of progression-free survival",
ggtheme = theme_gray(),
risk.table.y.text.col = T,
risk.table.y.text = TRUE,
surv.median.line = "hv",
ylim=c(0,1),
cumevents=TRUE,
#palette=c("#222a37","darkred"),
surv.scale="percent")
j
I have tried to add the following, but I get this warning: Error in max(surv_median) : invalid 'type' (closure) of argument
surv_median <- as.vector(summary(fit)$table[, "median"])
df <- data.frame(x1 = surv_median, x2 = surv_median,
y1 = rep(0, length(surv_median)), y2 = rep(0.5, length(surv_median)))
j$plot <- j$plot +
geom_segment(aes(x = 0, y = 0.5, xend = max(surv_median), yend = 0.5),
linetype = "dashed", size = 0.5)+ # horizontal segment
geom_segment(aes(x = x1, y = y1, xend = x2, yend = y2), data = df,
linetype = "dashed", size = 0.5) # vertical segments
print(j)
As of today, there would appear to be no straightforward way of changing anything with regards to survival median line.
This is a snippet from above code which plots the line.
if(nrow(df)>0){
if(type %in% c("hv", "h"))
p <- p +
geom_segment(aes(x = 0, y = max(y2), xend = max(x1), yend = max(y2)),
data = df, linetype = "dashed", size = 0.5) # horizontal segment
if(type %in% c("hv", "v"))
p <- p + geom_segment(aes(x = x1, y = y1, xend = x2, yend = y2), data = df,
linetype = "dashed", size = 0.5) # vertical segments
}
else warning("Median survival not reached.")
}
What you could do is not plot the line and add it manually, learning from the code how to calculate it. There is also a way to hack the function to work outside of the ggsurvplot function. I would go about this by gaining access to the data being plotted and then adding my own geom_segment.
I made edits to the source shown by Roman Luštrik, which is found on GitHub in the survminer package's R folder and is titled "ggsurvplot_core.R".
I made a fork in GitHub that has a solid line instead but you can also make a fork that has color and alpha changes. Let me know if you are still trying to this even though it's been three years!
My fork with a solid line instead of dashed https://github.com/brandonerose/survminer.git

Changing the colour of the regression line and data points to an XY Plot

This is probably a very basic question, but I am struggling to change the graphics parameters in the xyplot (below). The objective is to change the colour of the regression line to red and the data-points to blue.
I have basicaly tried the code below but when I add pch=19, and col="blue" to the code the colours don't change.
If anyone can help, I would be deeply appreciative.
R code for the XY plot
##Create a vector
Z3 <- as.vector(as.matrix(Pairs[, c("Lighting",
"Distance_Coast",
"Temp_Canopy",
"Temp_Open",
"T.max.open",
"T.min.open",
"T.min.canopy",
"T.max.canopy")]))
#Setup the data in vector format for the xyplot
Y10 <- rep(Pairs$Canopy_index, 8)
MyNames <-names(Pairs[,c("Lighting",
"Distance_Coast",
"Temp_Canopy",
"Temp_Open",
"T.max.open",
"T.min.open",
"T.min.canopy",
"T.max.canopy")])
ID10 <- rep(MyNames, each = length(Pairs$Canopy_index))
ID11 <- factor(ID10, labels = c("Lighting",
"Distance_Coast",
"Temp_Canopy",
"Temp_Open",
"T.max.open",
"T.min.open",
"T.min.canopy",
"T.max.canopy"),
levels = c("Lighting",
"Distance_Coast",
"Temp_Canopy",
"Temp_Open",
"T.max.open",
"T.min.open",
"T.min.canopy",
"T.max.canopy"))
##XY Plot
xyplot(Y10 ~ Z3 | ID11, col = 1,
strip = function(bg='white',...) strip.default(bg='white',...),
scales = list(alternating = T,
x = list(relation = "free"),
y = list(relation = "same")),
xlab = "Explanatory Variables",
par.strip.text = list(cex = 0.8),
ylab = "Canopy Index",
panel=function(x, y, subscripts,...){
panel.grid(h =- 1, v = 2)
panel.points(x, y, col = 1, pch = 16)
if(ID10[subscripts][1] != "Minutes.After.Sunset") {panel.loess(x,y,col=1,lwd=2)}
})
XY Plot
Heres the answer:
##XY Plot
xyplot(Y10 ~ Z3 | ID11, col = 1,
strip = function(bg='white',...) strip.default(bg='white',...),
scales = list(alternating = T,
x = list(relation = "free"),
y = list(relation = "same")),
xlab = "Explanatory Variables",
par.strip.text = list(cex = 0.8),
ylab = "Canopy Index",
panel=function(x, y, subscripts,...){
panel.grid(h =- 1, v = 2)
panel.points(x, y, col = "blue", pch = 19)
if(ID10[subscripts][1] != "Minutes.After.Sunset"){panel.loess(x, y, col="red", lwd=2)}
})
XY Plot

Zoom in and zoom out for R graph

I know the question was already asked, but i couldn't solve my problem.
I get a graph unreadale when i choose the text argument for my graph and when i choose the identify argument it's not better.
This is what i get whith this script :
VehiculeFunction <- function(data, gamme, absciss, ordinate, label, xlim, ylim){
my.data <- data[data$GAMME == gamme,]
ma.col = rgb(red = 0.1,blue = 1,green = 0.1, alpha = 0.2)
X <- my.data[[absciss]]
Y <- my.data[[ordinate]]
Z <- my.data[[label]]
X11()
plot(X, Y, pch=20, las = 1, col = ma.col, xlab = absciss, ylab = ordinate, xlim = xlim, ylim = ylim)
text(X, Y, labels = Z, pos=3, cex = 0.7, col = ma.col)
#identify(X, Y, labels = Z, cex = 0.7)
}
VehiculeFunction(data.vehicule, "I", "GMF.24", "Cout.24", "NITG", c(0,0.2), c(0,0.2))
I used iplot, but i couldn't add the identify and text argument...
I never used ggplot, so i don't know if it's could solve my problem.
Thank you for help.
A tool that might help with is facet_zoom from the ggforce package.
I don't have access to the data.vehicule object, so I will use the mtcars data.frame for an example of zooming in on a region of the graphic.
library(ggplot2)
library(ggforce)
library(dplyr)
mtcars2 <- mtcars %>% mutate(nm = rownames(mtcars))
ggplot(mtcars2) +
aes(x = wt, y = mpg, label = nm) +
geom_text()
last_plot() +
theme_bw() +
facet_zoom(x = dplyr::between(wt, 3, 4),
y = dplyr::between(mpg, 12, 17))

Resources