Specifying the orientation of the axes labels in scatterplot3d - r

I was wondering if it is possible to specify the orientation of the axes labels in scatterplot3d? I'd like the y axis label (wt) to be parallel to the y axis and not parallel to the z axis as it is now:
library(scatterplot3d)
with(mtcars, {
scatterplot3d(disp, wt, mpg, main="")
})

At the moment it is hard-coded. You can create a new scatterplot3d function and replace the mtext2 function definition with a slightly modified version that will accept a 'las' argument and then give the call to that function for 'ylab' a different value (2).
......
mytext2 <- function(lab, side, line, at, las=0) mtext(lab, side = side,
line = line, at = at, col = col.lab, cex = cex.lab,
font = font.axis, las = las) # shift hard coding to a default value
lines(c(x.min, x.max), c(z.min, z.min), col = col.axis,
lty = lty.axis)
mytext2(xlab, 1, line = 1.5, at = mean(x.range))
lines(xx[1] + c(0, y.max * yx.f), c(z.min, y.max * yz.f +
z.min), col = col.axis, lty = lty.axis)
mytext2(ylab, if (angle.1)
2
else 4, las=2, line = 0.5, at = z.min + y.max * yz.f) # 2nd change
.....

This answer is stolen and slightly tweaked from #JorisMeys answer to a similar question about changing the label position.
with(mtcars, {
scatterplot3d(disp, wt, mpg, main="", ylab="")
})
dims <- par("usr")
x <- dims[1]+ 0.97*diff(dims[1:2])
y <- dims[3]+ 0.4*diff(dims[3:4])
text(x, y, "wt", srt=0)
There is certainly more playing you can do, especially with the margins. For example:
with(mtcars, {
scatterplot3d(disp, wt, mpg, main="", ylab="",
y.margin.add=0.5)
})
dims <- par("usr")
x <- dims[1]+ 0.97*diff(dims[1:2])
y <- dims[3]+ 0.4*diff(dims[3:4])
text(x, y, "wt")

Related

How to draw two curves in one plot / graph

I have two functions, with a range-specific argument. I can’t get them on one chart in any way.
f1 = function(x1){
return (sqrt(64-x1^2))
}
f2 = function(x2){
return (cos(x2) - x2)
}
plot(f1,-5, 1)
plot(f2,-pi/2, pi/2)
I just started to learn this language, and I do not quite understand how this process can be performed.
If I execute the code, I get the following:
I need these curves to be on the same graph
You can use ggplot2 and stat_function to draw multiple functions and to restrict the range of each of them:
library(ggplot2)
ggplot() +
stat_function(fun = function(x) cos(x) - x, color = "red", xlim = c(-pi/2,pi/2)) +
stat_function(fun = function(x) sqrt(64-x^2), xlim = c(-5,1)) +
ylim(-10,10)
You wan still add ylim (as I did) and xlim to restrict the main panel range, but the inside-functions xlim will restrict the computation of the functions to theses ranges
You can try the lines() argument to add to an existing plot:
f1 = function(x1){
return (sqrt(64-x1^2))
}
f2 = function(x2){
return (cos(x2) - x2)
}
x <- c(-5:5) # choose your x value range here
y1 <- mapply(FUN = f1,x1 = x) # lets get the y values before plotting
y2 <- mapply(FUN = f2,x2 = x) # lets get the y values before plotting
plot(x,y1, type = "l", col = "red", ylim = c(-5,10))
lines(x, y2, col = "blue", type = "l")
Giving you this:
Using curve might be quite efficient.
curve(sqrt(64 - x^2), col=2, xlim=c(-5, 1), ylim=c(-5, 10))
curve(cos(x) - x, col=4, add=TRUE)
f1 = function(x1){
return (sqrt(64-x1^2))
}
f2 = function(x2){
return (cos(x2) - x2)
}
x = seq(-5, 1, len=20)
y = cbind(y1=f1(x), y2=f2(x))
matplot(x, y, col=1:2, type="l", lty=1)
legend('topright', legend=c(expression(f[1]), expression(f[2])), col = 1:2, lty=1, bty = "n")

GGplot second y axis without the transformation of y axis

Does any one know how do you apply this
set.seed(101)
x <- 1:10
y <- rnorm(10)
## second data set on a very different scale
z <- runif(10, min=1000, max=10000)
par(mar = c(5, 4, 4, 4) + 0.3) # Leave space for z axis
plot(x, y) # first plot
par(new = TRUE)
plot(x, z, type = "l", axes = FALSE, bty = "n", xlab = "", ylab = "")
axis(side=4, at = pretty(range(z)))
mtext("z", side=4, line=3)
but using ggplot.
In ggplot you can only create sec.axis() or dup.axis() using a transformation of y axis. What about a whole new independent y axis which will be applied only for z variable and the simple y axis to be applied for the y variable.
ggplot2::sec_axis provides only one mechanism for providing a second axis, and it took a lot of convincing to get that into the codebase. You are responsible for coming up with the transformation. This transform must be linear in some way, so if either axis needs to be non-linear (e.g., exponential, logarithmic, etc), then your expert math skills will be put to the test.
If you can use scales, then this process becomes trivial:
dat <- data.frame(x, y, z)
ggplot(dat, aes(x, y)) +
geom_point() +
geom_line(
aes(y = zmod),
data = ~ transform(., zmod = scales::rescale(z, range(y), range(z)))
) +
scale_y_continuous(
sec.axis = sec_axis(~ scales::rescale(., range(dat$z), range(dat$y)),
breaks = c(2000,4000,6000,8000))
)
Unless I've missed something (I just checked ggplot2-3.3.5's NEWS.md file), this has not changed.

Fail to add a linear trend line on a barplot in 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))

Reverse the scale of the x axis in a plot

I have created a plot in R and my own custom x and y axes. I would like the x axis to be displayed in a reverse order (1-0 by -.02). I have read numerous posts and threads that suggest using xlim and reverse range but I just can't seem to make it work. Once plotted I am also converting the axes labels to percentages by multiplying by 100 (as you will see in the code). Here is what I have so far;
plot(roc.val, xlab = "Specificity (%)", ylab = "Sensitivity (%)", axes = FALSE)
axis(2, at = seq(0,1,by=.2), labels = paste(100*seq(0,1, by=.2)), tick = TRUE)
axis(1, at = seq(0,1,by=.2), labels = paste(100*seq(0,1, by=.2)), tick = TRUE)
How can I reverse the x axis scale so that the values begin at 100 and end at 0 with increments of 20?
I think this creates a plot in which the y-axis is in reverse order:
x <- seq(-4, 4, length = 10)
y <- exp(x) / (1 + exp(x))
plot(x,y, ylim = rev(range(y)))
This removes the axis values:
x <- seq(-4, 4, length = 10)
y <- exp(x) / (1 + exp(x))
plot(x,y, ylim = rev(range(y)), labels = FALSE)
I guess you can assign the axis values you want then with a variation of your lines:
axis(2, at = seq(0,1,by=.2), labels = paste(100*seq(0,1, by=.2)), tick = TRUE)
axis(1, at = seq(0,1,by=.2), labels = paste(100*seq(0,1, by=.2)), tick = TRUE)
df <- data.frame(x=seq(0,1, length.out=50), y=seq(0, 1, length.out=50))
plot(df)
df$x1 <- (max(df$x) - df$x)/ (max(df$x) - min(df$x))
plot(df$x1, df$y, axes=F, xlab = "Specificity (%)", ylab = "Sensitivity (%)")
axis(2, at = seq(0,1,by=.2), labels = paste(100*seq(0,1, by=.2)), tick = TRUE)
axis(1, at = seq(0,1,by=.2), labels = paste(100*seq(1,0, by=-.2)), tick = TRUE)
Adapting Mark Miller's answer to solve a similar problem (I found this topic by looking for the solution) and I found a variation of his solution in https://tolstoy.newcastle.edu.au/R/help/05/03/0342.html.
Basically if you want to reverse the X-axis values in the plot, instead of using ylim=rev(range(y)), you can use xlim=rev(c(-4,4)).
x <- seq(-4, 4, length = 10)
y <- exp(x) / (1 + exp(x))
par(mfrow=c(1,2))
plot(x, y, ylim=range(y), xlim=c(-4, 4))
plot(x, y, ylim=range(y), xlim=rev(c(-4, 4)))
plot1
And if you want to keep the x-axis values in the true order, you can use this:
par(mfrow=c(1,1))
plot(x, y, ylim=range(y), xlim=c(-4, 4), axes=FALSE)
par(new=TRUE)
plot(-100, -100, ylim=range(y), xlim=c(-4, 4), axes=FALSE, xlab="", ylab="", main="")
axis(1, at = seq(-4,4,by=1), labels = seq(-4,4,by=1), tick = TRUE)
axis(2, at = seq(0,1,by=.2), labels = paste(100*seq(0,1, by=.2)), tick = TRUE)
plot2
I'm posting this solution because I needed something very straightforward to solve my problem. And the solution for it needed the plot with the X-axis value in the correct order (and not reversed).
First, check out the ggplot2 library for making beautiful and extendable graphics. It is part of the Tidyverse approach to R and a gamechanger if you have not been exposed to it.
For example, to solve your issue using ggplot, you simply add the term scale_x_reverse() to your graphic.
See: http://ggplot.yhathq.com/docs/scale_x_reverse.html

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