Creating a secondary y-axis in histogram - r

I have found multiple ways to create a secondary y-axis in plot but I couldn't find a way to create a secondary y-axis in histogram.
Here is a sample code:
a <- sample(90:110, 50, replace=TRUE)
b <- runif(50, min=0, max=1)
hist(a)
lines(b)
b is too small to show in hist(a) so is there any way that I can see both in the histogram?

Technically a solution may be quite an identical to the approach proposed for the plots in this answer. The idea is to use overlapping of two plots as proposed by #r2evans.
It makes sense to use color coding:
# set color rules
col_a <- "red"
col_b <- "darkblue"
col_common <- "black"
Then let's draw the histogram and the plot:
# draw a histogram first
par(mar = c(5, 5, 5, 5) + 0.3)
hist(a, col = col_a, axes = FALSE, xlab = "", ylab = "", main = "")
# add both axes with the labels
axis(side = 1, xlim = seq(along.with = b), col = col_a, col.axis = col_a)
mtext(side = 1, text = "a_value", col = col_a, line = 2.5)
axis(side = 2, col = col_a, col.axis = col_a, ylab = "")
mtext(side = 2, text = "a_Frequency", col = col_a, line = 2.5)
# ... and add an overlaying plot
par(new=TRUE)
plot(b, ylim = c(0, 1), axes = FALSE, col = col_b, type = "l", xlab = "", ylab = "")
points(b, col = col_b, pch = 20, xlab = "", ylab = "")
axis(side = 3, xlim = seq(along.with = b), col = col_b, col.axis = col_b)
mtext(side = 3, text = "b_index", col = col_b, line = 2.5)
axis(side = 4, ylim = c(0, 1), col = col_b, col.axis = col_b)
mtext(side = 4, text = "b_value", col = col_b, line = 2.5)
box(col = col_common)

Related

Factor variable on x-axis for double y-axis

Right now on the x-axis it plots numerical variable "1,2,3,4" etc. when instead I want it to graph the game. As you can see in line 85, axis(1,Champ$game) I want the game name on the x-axis, but instead it just numbers the game rather than putting the game name. How do I fix this?
par(mar=c(5, 4, 4, 6) + 0.1)
plot(Champ$daily_max_vel, pch = 16, axes = FALSE, ylim =
c(3.0,3.9),type = "b", col = "black", ylab = "", xlab = "",
main = "Athlete")
##Creates y-axis for graph 1
axis(2, ylim = c(0,1), col = "black", las = 1)
mtext("Velocity (m/s)", side = 2, line = 2.5)
box()
## Allows for second plot on same graph
par(new = TRUE)
#Plotting second graph
plot(Champ$daily_peak_power, pch = 1, xlab = "", ylab = "",
ylim = c(1000,1600), axes = FALSE, type = "b",
col = "orange")
#Creating Second Axis
mtext("Power (W)", side = 4, col = "orange", line = 4)
axis(4,ylim = c(1200,1600), col = "orange", col.axis =
"orange", las = 1)
axis(1,Champ$game)
Using the labels function should do what you are looking for - here is an example of what I think your issue is. If this doesn't work, edit your post to provide your data structure.
# create sample data
df <- data.frame(game = sample(c(1, 2, 3), 150, replace = TRUE),val = rgamma(150, 50))
plot(df)
# label factors
df$game <- factor(df$game, levels = 1:3, labels = c("Game A", "Game B", "Game C"))
# plot
plot(df, axes = F, type = "b")
axis(1, df$game, labels = df$game) # shows game A, game b, game c instead of 1, 2, 3

How to remove the zero labels in Histogram plot in R?

Any tips to remove the zero labels in between the histogram bars?
hist(links$Survey_Duration, breaks = seq(0,50,5), main = "Survey Duration",
labels = TRUE, border = "black",
xlab = "Survey", ylim = c(0, 15), col = "gray", las = 1, xaxt='n')
axis(side=1, at=seq(0,50,5), labels=seq(0,50,5))
abline(v = mean(links$Survey_Duration), col = "royalblue", lwd = 1.5)
abline(v = median(links$Survey_Duration), col = "red", lwd = 1.5)
legend(x = "topright", c("Mean", "Median"), col = c("royalblue","red"),
lwd = c(1.5,1.5))
How about this?
# modify data so there's zero in one of the bins
mtcars$mpg <- ifelse(mtcars$mpg >= 25 & mtcars$mpg <= 30, NA, mtcars$mpg)
# save plot parameters
h <- hist(mtcars$mpg, plot = FALSE)
# produce plot
plot(h, ylim = c(0, 14))
# add labels manually, recoding zeros to nothing
text(h$mids, h$counts + 1, ifelse(h$counts == 0, "", h$counts))
A slightly different answer using the labeling in hist instead of adding text afterwards.
You do not provide your data, so I will use some data that is handy to illustrate.
The labels argument can specify the individual labels
H1 = hist(iris$Sepal.Length, breaks = 3:8, plot=FALSE)
BarLabels = H1$counts
BarLabels[BarLabels == 0] = ""
hist(iris$Sepal.Length, breaks = 3:8, labels = BarLabels)
Thanks #Daniel Anderson, it Ok now (Thumbs Up)
links$Survey_Duration <- ifelse(links$Survey_Duration > 15 &
links$Survey_Duration <= 25,
NA,
links$Survey_Duration)
h <- hist(links$Survey_Duration, breaks = seq(0,50,5), plot = FALSE)
plot(h, ylim = c(0, 14), main = "Survey Duration", xlab = "Time", col = "gray", las = 1)
text(h$mids, h$counts + 1, ifelse(h$counts == 0, "", h$counts))
axis(side=1, at=seq(0,50,5), labels=seq(0,50,5))
abline(v = mean(links$Survey_Duration), col = "royalblue", lwd = 1.5)
abline(v = median(links$Survey_Duration), col = "red", lwd = 1.5)
legend(x = "topright",
c("Mean", "Median"),
col = c("royalblue","red"),
lwd = c(1.5,1.5))

R Shiny plot won't render

Hi can anyone see what is the problem with the code below?
output$zscore_chart <- renderPlot({
xvals <- 2:186
req(input$countrySelectZScore)
idx_country = which(input$countrySelectZScore == esiCountries)
max_comp_z <- max(esiData_DF[idx_country, 2:186], na.rm = TRUE)
overall_max_z <- max(max_comp_z, na.rm = TRUE)
foo = ts(esiData_DF[idx_country, 2:186], frequency = 12, start = 2001)
dates = seq(as.Date("2001-01-01"), by = "month", along = foo)
plot(x = 2:186, y = esiData_DF[idx_country, 2:186], type = "l",
xlab = "", ylab = "", col = "grey20", ylim = c(-2, overall_max_z),
lwd=3,las=2)
mtext("Quarterly percentage changes", side = 3, adj = 0, line = 0.1,
cex = 1, font = 0.5)
axis(1, at = xvals, label = dates, cex.axis = 1, las = 2)
mtext("Economic Sentiment Indicators", side = 3, adj = 0,
line = 1.2, cex = 2, font = 2)
legend(
"bottom",
lty = c(1,1),
lwd = c(3,3),
col = c("grey20", "green2"),
legend = c("Economic Sentiment Indicator", "GDP growth"),
bty = "n",
xjust = 0.5,
yjust = 0.5,
horiz = TRUE
)
}, height = 525)
esiData_DF is the DF used to index and plot the correct data. The dataframe has the country names down the left hand side with the dates, monthly across the top. I need the plot to render but it wont when I run the app. Any ideas?
The data continues to the right, up to May 2017 monthly.

regresio line didn't display correctly

lab <- data.frame( Month = c("2016-01-01", "2016-02-01", "2016-03-01", "2016-04-01", "2016-05-01", "2016-06-01"), AccNumber = c(5683,5418,6001,6184,6001,6184), OCTAT = c(40.20,50.52,47.15,45.03,47.15,45.03), Default = c(30,30,30,30,30,30))
id <- rownames(lab)
lab <- cbind(id = id, lab)
max <- max(lab$AccNumber)
max2 <- max(lab$OCTAT)
p <- barplot(lab$AccNumber, names.arg = lab$Month, xlab = "Month", col = "blue" ,ylim = c(0, max + 2000))
par(new=TRUE)
plot(x = id, y = lab$OCTAT, type = "l", col = "red", axes = FALSE, ylim = c(0, 60), ann = FALSE)
plot(x = id, y = lab$OCTAT, type = "l", col = "green", axes = FALSE, ylim = c(0, 60), ann = FALSE, lwd = 2)
p <- barplot(lab$AccNumber, names.arg = lab$Month, xlab = "Month", col = "blue" ,ylim = c(0, max + 2000))
par(new=TRUE)
plot(x = id, y = lab$OCTAT, type = "l", col = "green", axes = FALSE, ylim = c(0, 60), ann = FALSE, lwd = 2)
axis(4, at=seq(0, max2 + 10, 10))
abline(h = 30, lwd = 2) # Default blue line (30)
abline(lm(lab$OCTAT ~ lab$id), col = "red", lty = 2) #Regression line trend
After running the code this is what I got below. I am totally new to R. How can I get a regression line that look like the second pic.
If you want the dashed red line to span from the left axis to the right axis, change the last line of code to:
abline(lm(lab$OCTAT ~ as.numeric(lab$id)), col = "red", lty = 2)
This is because lab$id is of class character.
If you want the red dashed line to span the same width as the green line, change the last line of code to:
lines(x = c(1,6), y = c(44.9953, 46.6983), col = 'red', lty = 2)
The values 44.9953 and 46.6983 are obtained from putting id = 1 and id = 6 into the model fitted from lm(lab$OCTAT ~ as.numeric(lab$id).
Hope this is what you were looking for.

Plotting mean in R at specific X-axis

In R, is there a way to add means to a plot at specific x-axis. For example, I want to do something like:
plot(1, 1, xlim = c(0, 6.5), ylim = c(0,300), type = 'n', xlab = '', ylab = '', xaxt = 'n') #xaxs="i",yaxs="i")
boxplot(dataset,at = 0.5, add = T, range = 6,yaxt = 'n')
points(mean(dataset), at = 0.5, add = T)
I get a message saying "at" and "add" are 'not a graphical parameter'. Is there a workaround?
So I am using RStudio. There are six different values (data_a, data_b, data_c, data_d, data_e, and data_f) each with 11 numbers. My current code looks like follows:
par(xpd = FALSE)
par(mar=c(8,4.5,2,1))
plot(1, 1, xlim = c(0, 6.5), ylim = c(0,300), type = 'n', xlab = '', ylab = '', xaxt = 'n') #xaxs="i",yaxs="i")
boxplot(data_a,at = 0.5, add = T, range = 6,yaxt = 'n')
boxplot(data_b,at = 1.5, add = T, range = 6,yaxt = 'n')
boxplot(data_c,at = 2.5, add = T, range = 6,yaxt = 'n')
boxplot(data_d,at = 4, add = T, range = 6,yaxt = 'n')
boxplot(data_e,at = 5, add = T, range = 6,yaxt = 'n')
boxplot(data_f,at = 6, add = T, range = 6,yaxt = 'n')
axis(2, at = 150, pos = -0.65, tck = 0, labels = 'X axis label',cex.axis=1.1)
axis(1, at = c(0.5,1.5,2.5,4,5,6),labels=c('','','','','',''))
axis(1, at = c(1.5,5),pos= -25,labels=c('label 1','labe 2'),tick=FALSE)
axis(1, at = c(3.25),labels=c(''),tck=-0.15)
axis(1, at = c(3.25),pos = -50,labels=c('Y axis label'),tick=FALSE)
abline(v=3.25)
par(xpd = NA)
text(0.5,-30, expression("a))
text(1.5,-30, expression("b"))
text(2.5,-30,"c")
text(4,-30, expression(d))
text(5,-30, expression("e"))
text(6,-30,"f")
Now I want to be able to add mean.
You can try this to get the desired plot (with randomly generated data_a, data_b etc.):
par(xpd = FALSE)
par(mar=c(8,4.5,2,1))
plot(1, 1, xlim = c(0, 6.5), ylim = c(0,300), type = 'n', xlab = '', ylab = '', xaxt = 'n') #xaxs="i",yaxs="i")
data_a <- runif(11, 0, 300)
data_b <- runif(11, 0, 300)
data_c <- runif(11, 0, 300)
data_d <- runif(11, 0, 300)
data_e <- runif(11, 0, 300)
data_f <- runif(11, 0, 300)
boxplot(data_a,at = 0.5, add = T, range = 6,yaxt = 'n')
boxplot(data_b,at = 1.5, add = T, range = 6,yaxt = 'n')
boxplot(data_c,at = 2.5, add = T, range = 6,yaxt = 'n')
boxplot(data_d,at = 4, add = T, range = 6,yaxt = 'n')
boxplot(data_e,at = 5, add = T, range = 6,yaxt = 'n')
boxplot(data_f,at = 6, add = T, range = 6,yaxt = 'n')
axis(2, at = 150, pos = -0.65, tck = 0, labels = 'X axis label',cex.axis=1.1)
axis(1, at = c(0.5,1.5,2.5,4,5,6),labels=c('','','','','',''))
axis(1, at = c(1.5,5),pos= -25,labels=c('label 1','label 2'),tick=FALSE)
axis(1, at = c(3.25),labels=c(''),tck=-0.15)
axis(1, at = c(3.25),pos = -50,labels=c('Y axis label'),tick=FALSE)
abline(v=3.25)
par(xpd = NA)
text(0.5,-30, expression("a"))
text(1.5,-30, expression("b"))
text(2.5,-30,"c")
text(4,-30, expression("d"))
text(5,-30, expression("e"))
text(6,-30,"f")
points(c(0.5,1.5,2.5,4,5,6), c(mean(data_a), mean(data_b), mean(data_c), mean(data_d), mean(data_e), mean(data_f)), pch = 22, col = "darkgrey", lwd = 7)
With boxplots, the location of the plots on the x axis are at the units (1, 2, 3, etc.). You can check this using the function locator().
Here is an example to add means as a red circle to a boxplot using the iris dataset:
boxplot(Sepal.Length ~ Species, data = iris)
points(seq_along(levels(iris$Species)), with(iris, tapply(Sepal.Length, Species, mean)), col = "red")

Resources