I want to plot my points on a graph and then show the density distribution on the x-axis and on the y-axis at the same time.
I'm able to do it on the x axis but not on the y axis.
par(mfrow=c(1,1))
plot(rnorm(100))
par(new=TRUE)
plot(density(rnorm(100,10,123)), ann = FALSE, xlab = "", ylab ="",xaxt='n', yaxt='n')
par(new=TRUE)
plot(density(rnorm(100, 10,12)), col = "red", ann = FALSE, xlab = "", ylab ="",xaxt='n', yaxt='n')
There is no reason you can't.
set.seed(0)
d1 <- density(rnorm(100, 10, 123))
d2 <- density(rnorm(100, 10, 130))
## shared x, y, range / limit
xlim <- c(min(d1$x[1], d2$x[1]), max(d1$x[512], d2$x[512])) ## default: n = 512
ylim <- c(0, max(d1$y, d2$y))
## conventional plot
plot(d1$x, d1$y, type = "l", xlim = xlim, ylim = ylim)
lines(d2$x, d2$y, col = 2)
## rotated plot
plot(d1$y, d1$x, type = "l", xlim = ylim, ylim = xlim)
lines(d2$y, d2$x, col = 2)
Remarks:
never use par(new = TRUE); set xlim and ylim yourself;
customize the plot with title, axis display yourself.
Related
I'm a relative beginner in R so please forgive me if it's a noob question.
So, is there a package which provides an easy interface to plot (real-real, mathematical) functions? I need coordinate axis with arrows (and their intersection should be (0;0)) and ticks, grid, etc. I want similar plots as in this document.
Background: now I create function plots with LaTeX's tikzpicture and axis but I'm using R to generate randomized exams since few months (R creates tex-files and include them into document) and would be nice if R can create similar plots (png, jpg), because axis in LaTeX is very slow.
Thanks!
I made you a little function for this
math_plot <- function(f, xlim = c(-2,2), ylim = c(-2,2),
xlab = "x", ylab = "f(x)", ax.ext = .02,
frame.plot = F, grid.tick = .1, ...){
curve(f, from = xlim[1], to = xlim[2], ylim = ylim,
axes = F, xlab = "", ylab = "",
frame.plot = frame.plot, ...)
# x-axis
axis(1, pos = 0)
arrows(x0 = xlim[2], x1 = xlim[2] + diff(xlim)*ax.ext, y0 = 0, length = .1)
mtext(text = xlab, side = 4, line = 0, las = 2, at = 0)
# y-axis
axis(2, pos = 0, las = 2)
arrows(y0 = ylim[2], y1 = ylim[2] + diff(ylim)*ax.ext, x0 = 0, length = .1)
mtext(text = ylab, side = 3, line = 0, at = 0)
grid(nx = diff(xlim)/grid.tick, ny = diff(ylim)/grid.tick)
}
# give it a function
math_plot(function(x) 3*x + 2 - 2*x^2, ylim = c(-2,4))
With R graphic tools such as arrows, points, abline, etc. you can draw practically anything.
Example
op <- par(mar=c(1, 1, 1, 1)) ## adjust outer margins
plot(x, y, type="n", axes=F, asp=1, xlab="", ylab="") ## asp=1 to maintain 1:1 aspect ratio
lines(x, y, lwd=2)
arrows(par()$usr[1], 0, par()$usr[2], length=.05) ## par()$usr helps to find xlim and ylim
arrows(0, par()$usr[3], 0, par()$usr[4], length=.05)
points((-5:5)*10, rep(0, 11), pch=3, cex=.6) ## pch=3 for crosses
points(rep(0, 11), (-5:5)*10, pch=3, cex=.6)
mtext("y", 3, -1, adj=.55, font=8)
mtext("x", 4, -1, padj=-1, las=2, font=8)
abline(h=(-5:5)*10, lty=3, col="gray")
abline(v=(-5:5)*10, lty=3, col="gray")
text(10, -4, "10", font=7, cex=.8)
text(-4, 10, "10", font=7, cex=.8)
par(op) ## reset par
Data
x <- (-10):10; y <- x^2 - 50
par(mar=c(5,5,2,5), xpd=TRUE)
x <- seq(0,5,0.5)
y <- seq(0,5,0.5)
plot(x,y, xlab="", ylab="")
Is there a way to replace the x-axis labels (0,1,2,3,4,5) with symbols pch=2,pch=4,pch=6,pch=8,pch=10,pch=12?
A fairly manual solution, but that's often what you get with base graphics:
par(mar=c(5,5,2,5), xpd=TRUE)
x <- seq(0,5,0.5)
y <- seq(0,5,0.5)
plot(x,y, xlab="", ylab="",xaxt = "n")
axis(side = 1,at = 0:5,labels = FALSE)
points(x = 0:5,y = rep(-0.5,6),pch = c(2,4,6,8,10,12))
I am trying to plot a tornado graph for sensitivity analysis purposes. This is what I have so far.
OP <- par(mar = c(7,7,7,7))
data <- matrix(c(-0.10,0.15,-0.01,0.01,-0.03,0.08,-0.1,0.07), ncol = 4)
# Amount of Change in Variables
rownames(data) <- c('+25%','-25%')
# Names of Variables
colnames(data) <- c('Variable 1', 'Variable 2', 'Variable 3','Variable 4')
# For Plotting % on X-Axis
x <- seq(-0.30,0.30, length=13)
SEQUENTIAL <- RColorBrewer::brewer.pal(4, "YlOrRd")
barplot(data[1,], main="Tornado Graph", horiz = T, las=1, xlim = c(-0.30,0.30), xaxt='n', ylab = '', col=SEQUENTIAL)
barplot(data[2,], horiz = T, las=1, xlim = c(-0.30,0.30), xaxt='n', ylab = '', col=SEQUENTIAL, add = TRUE)
# Add x-axis
axis(1, at=x, labels=paste0(x * 100," %"), las=TRUE)
par(OP)
The bars of the tornado graph are not sorted like in a proper graph. How do I sort them in decreasing length?
Thanks
Just put the columns in order for plotting. Replace your two barplot statements with
ORD = order(data[2,] - data[1,])
barplot(data[1,ORD], main="Tornado Graph", horiz = T, las=1,
xlim = c(-0.30,0.30), xaxt='n', ylab = '', col=SEQUENTIAL)
barplot(data[2,ORD], horiz = T, las=1, xlim = c(-0.30,0.30), xaxt='n',
ylab = '', col=SEQUENTIAL, add = TRUE)
I am doing a plot with R, the code for stacked bar and axis 2 are simple, here is the code for line and axis 4:
lines(y,
theLineValues,
type = "o",
pch = 20,
lwd = 2,
cex = 1.2,
lty = 1,
col ="forestgreen")
axis(4,
at = getYaxis(0,1,0.01, 3), # function to get 3 values for axis
labels = getYaxis(0,1,0.01, 3),
col.axis= "forestgreen",
las = 1,
cex.axis= 0.7,
col = "forestgreen",
line = 0)
then I found the min and max value: 0.46, 0.68 , and want to use them as axis, so the changing of line can be seen more obviously(the red line).
labels = getYaxis(min(theLineValues),max(theLineValues),0.01,3),
How would I scale the 'theLineValues' to do this?
Thanks.
======================================================================
Update 1: the code for 'y':
y <- barplot(
combinedvalues, # it's list of 3-combined values.
col = c("slategray1","darkseagreen1","moccasin"),
beside = FALSE,
border = "grey80",
las = 1,
cex.axis= 1.0,
ann = FALSE,
ylim = c(0,1),
yaxt = "n")
======================================================================
Update 2: the combined values:
these values are in .csv file, and use the following to get the 'combinedvalues' and pass it to 'y':
rbind(csv$frame0,csv$frame1,csv$frame2)
# frame0+frame1+frame2 shoud be 1, theLineValues were calculated by some formulas.
the csv file:
frame0 frame1 frame2 theLineValues
------------------------------------------------------------
0.4460203874 0.2271394791 0.3268401336 0.4674583872
0.4473756948 0.2084173711 0.3442069341 0.4796977238
0.5296042291 0.1570493286 0.3133464423 0.570317484
0.5255498752 0.1234146373 0.3510354875 0.6095475721
0.5405768621 0.119299957 0.3401231808 0.6251561825
0.5657840709 0.0916650587 0.3425508703 0.6896446583
0.4826617968 0.0877739789 0.4295642243 0.6610089801
0.3588171226 0.122977733 0.5182051444 0.606129318
0.2608499204 0.1705417922 0.5686082874 0.595971676
0.2111782825 0.2040231107 0.5847986067 0.6057364576
0.1731616573 0.240909341 0.5859290016 0.6153720603
Thanks.
======================================================================
Update 3: the final plot:
Frames.txt is based on the three frame columns.
Data
frames <- read.table("/your-path/frames.txt",header=T,na.string="NA")
theLineValues<-c(0.4674583872, 0.4796977238, 0.570317484, 0.6095475721, 0.6251561825, 0.6896446583, 0.6610089801, 0.606129318, 0.595971676, 0.6057364576, 0.6153720603)
Plot
barplot(t(frames), , col = c("slategray1","darkseagreen1","moccasin"))
axis(2, ylim=c(0,1))
mtext("barplot values", side=2, line=2)
box()
par(new=TRUE)
plot(theLineValues, type = "l", pch = 20, xlab="", ylab="", col = "forestgreen", lwd=2, ylim=c(min(theLineValues), max(theLineValues)), axes=FALSE)
axis(4, ylim=c(min(theLineValues), max(theLineValues)))
mtext("lineValues", side=4, line=0.2)
box()
how to
Combine a bar chart and line in single plot in R (from different data sources)?
Say I have two data sources as:
barData<-c(0.1,0.2,0.3,0.4) #In percentage
lineData<-c(100,22,534,52,900)
Note that they may not be in the same scale.
Can I plot both barData and LineData in one plot and make them good looking ?
I cant use ggplot in this case so this is not a duplicated question..
Something like the following:
Maybe this helps as a starting point:
par(mar = rep(4, 4))
barData<-c(0.1,0.2,0.3,0.4) * 100
y <- lineData<-c(100,22,534,900);
x <- barplot(barData,
axes = FALSE,
col = "blue",
xlab = "",
ylab = "",
ylim = c(0, 100) )[, 1]
axis(1, at = x, labels = c("Julia", "Pat", "Max", "Norman"))
ats <- c(seq(0, 100, 15), 100); axis(4, at = ats, labels = paste0(ats, "%"), las = 2)
axis(3, at = x, labels = NA)
par(new = TRUE)
plot(x = x, y = y, type = "b", col = "red", axes = FALSE, xlab = "", ylab = "")
axis(2, at = c(pretty(lineData), max(lineData)), las = 2)
mtext(text="Lines of code by Programmer", side = 3, line = 1)
box()