plotting smooth line for data of very small magnitude - r

The command you suggested serves the purpose to some extent But I am still looking for a command/function to give smoother curves. I am giving a reproducible code below which is drawing rather sharp edges or more crudely: the line joining the points is too sharp especially at the moment it starts from one point to another. Sorry for non-technical language as I am still unfamiliar with the field. Thanks for the help provided on this issue. Please suggest the modifications in the code below to get smoother curves.
xdata1<-c(6:11)
ydata1<-c(-0.75132894, -1.71909555, -0.62653171, 0.49512191, 0.29201836, 0.31094460)
plot(NULL,NULL,xlim=xlims,ylim=ylims,axes=FALSE, ann=FALSE)
axis(1,cex.axis=0.7,mgp=c(3, .3, 0))
axis(2, las=1,cex.axis=0.7,at=c(-2,-1,0,1,2), mgp=c(3, .7, 0))
mtext(side = 1, text =expression('Year'), line = 1,font=15)
mtext(side = 2, text = expression('Variable'), line = 1.5,font=15)
lines(smooth.spline(xdata1,ydata1, df=5), col='red',type="l", pch=22, lty=1, lwd=1)
#######Updated Query Finishes Here
I have to plot very small magnitude data against time steps of 1. Please see the sample data below:
xdata<-c(1:48)
ydata<- c(0.325563413,0.401913414,0.221939845,0.19881055,
-0.05918293,-1.108143815,-0.220563332,-0.148715078,
-0.14998762,0.131610695,0.249923598,0.246891873,
0.656812019,0.524436114,0.23875397,0.200695075,
-0.015974087,-0.611863249,0.121994831,-0.143103421,
-0.142109609,0.101451935,0.160242421,0.232404601,
0.348305745,0.231109382,0.334988321,0.263046902,-0.058154333,
-1.032276818,-0.352068888,-0.13082767,-0.134611511,0.116967421,
0.268706409,0.232776855,0.39515544,0.540317537,0.424281195,
0.3061158,-0.210735495,0.023705618,0.473338271,0.270527033,
-0.165394174,0.268773501,0.202437269,0.305577906)
Please help me in plotting a smooth line without highlighting individual points for the data.
Thanks in advance,

Not sure what "without highlighting individual points" means, but here's one way to get a smooth line:
plot(xdata,ydata)
lines(smooth.spline(xdata,ydata, df=10), col = "red")
See also: ?loess.smooth, apropos("smooth"). Searching for "[r] smooth plot" finds How to fit a smooth curve to my data in R? ...

Specifying the type to "l" in plot will just give you lines.
plot(xdata, ydata, type = "l")

Related

Contour plot via Scatter plot

Scatter plots are useless when number of plots is large.
So, e.g., using normal approximation, we can get the contour plot.
My question: Is there any package to implement the contour plot from scatter plot.
Thank you #G5W !! I can do it !!
You don't offer any data, so I will respond with some artificial data,
constructed at the bottom of the post. You also don't say how much data
you have although you say it is a large number of points. I am illustrating
with 20000 points.
You used the group number as the plotting character to indicate the group.
I find that hard to read. But just plotting the points doesn't show the
groups well. Coloring each group a different color is a start, but does
not look very good.
plot(x,y, pch=20, col=rainbow(3)[group])
Two tricks that can make a lot of points more understandable are:
1. Make the points transparent. The dense places will appear darker. AND
2. Reduce the point size.
plot(x,y, pch=20, col=rainbow(3, alpha=0.1)[group], cex=0.8)
That looks somewhat better, but did not address your actual request.
Your sample picture seems to show confidence ellipses. You can get
those using the function dataEllipse from the car package.
library(car)
plot(x,y, pch=20, col=rainbow(3, alpha=0.1)[group], cex=0.8)
dataEllipse(x,y,factor(group), levels=c(0.70,0.85,0.95),
plot.points=FALSE, col=rainbow(3), group.labels=NA, center.pch=FALSE)
But if there are really a lot of points, the points can still overlap
so much that they are just confusing. You can also use dataEllipse
to create what is basically a 2D density plot without showing the points
at all. Just plot several ellipses of different sizes over each other filling
them with transparent colors. The center of the distribution will appear darker.
This can give an idea of the distribution for a very large number of points.
plot(x,y,pch=NA)
dataEllipse(x,y,factor(group), levels=c(seq(0.15,0.95,0.2), 0.995),
plot.points=FALSE, col=rainbow(3), group.labels=NA,
center.pch=FALSE, fill=TRUE, fill.alpha=0.15, lty=1, lwd=1)
You can get a more continuous look by plotting more ellipses and leaving out the border lines.
plot(x,y,pch=NA)
dataEllipse(x,y,factor(group), levels=seq(0.11,0.99,0.02),
plot.points=FALSE, col=rainbow(3), group.labels=NA,
center.pch=FALSE, fill=TRUE, fill.alpha=0.05, lty=0)
Please try different combinations of these to get a nice picture of your data.
Additional response to comment: Adding labels
Perhaps the most natural place to add group labels is the centers of the
ellipses. You can get that by simply computing the centroids of the points in each group. So for example,
plot(x,y,pch=NA)
dataEllipse(x,y,factor(group), levels=c(seq(0.15,0.95,0.2), 0.995),
plot.points=FALSE, col=rainbow(3), group.labels=NA,
center.pch=FALSE, fill=TRUE, fill.alpha=0.15, lty=1, lwd=1)
## Now add labels
for(i in unique(group)) {
text(mean(x[group==i]), mean(y[group==i]), labels=i)
}
Note that I just used the number as the group label, but if you have a more elaborate name, you can change labels=i to something like
labels=GroupNames[i].
Data
x = c(rnorm(2000,0,1), rnorm(7000,1,1), rnorm(11000,5,1))
twist = c(rep(0,2000),rep(-0.5,7000), rep(0.4,11000))
y = c(rnorm(2000,0,1), rnorm(7000,5,1), rnorm(11000,6,1)) + twist*x
group = c(rep(1,2000), rep(2,7000), rep(3,11000))
You can use hexbin::hexbin() to show very large datasets.
#G5W gave a nice dataset:
x = c(rnorm(2000,0,1), rnorm(7000,1,1), rnorm(11000,5,1))
twist = c(rep(0,2000),rep(-0.5,7000), rep(0.4,11000))
y = c(rnorm(2000,0,1), rnorm(7000,5,1), rnorm(11000,6,1)) + twist*x
group = c(rep(1,2000), rep(2,7000), rep(3,11000))
If you don't know the group information, then the ellipses are inappropriate; this is what I'd suggest:
library(hexbin)
plot(hexbin(x,y))
which produces
If you really want contours, you'll need a density estimate to plot. The MASS::kde2d() function can produce one; see the examples in its help page for plotting a contour based on the result. This is what it gives for this dataset:
library(MASS)
contour(kde2d(x,y))

R: How do I scale this plot?

In the plot resulting from this next code:
plot(poll$reality, poll$seker,xlab = "reality", ylab = "poll")
text(poll$reality, poll$seker, rownames(poll), cex=0.7, pos=3)
abline(0,1)
I can't seem to be able to scale the to axes to look the same, an so I get the feeling that the 'abline' (which is supposed to be a simple x=y) is misplaced.
I tried using 'plot.window' but couldn't quite understand how it worked as it had no affect.
Try plot(..., asp = 1). This should force the 1:1 ratio of axes.

Building a logistic trend surface in R

I would like to build a very simple rectangular surface in R that would have a logistic trend. The values at the top would have the highest values (1) and at the bottom the lowest (0). I have drafted an image that shows example of the surface that I have in mind, with help of not the prettiest trend lines so you have an idea what is needed. I do not have any data, it is supposed to be a theoretical surface with logistic trend, that I am later going to modify.
Any help with how to start/approach it, or helpful packages in R would be highly appreciated!
Consider this as a hint.
library("graphics")
plot(0:1, type = "n",xaxt="n", ann=FALSE)
abline(h = c(seq(0,1,.1))
or
abline(h = c(0,.1,.2,.3,.6,.7,.8,.9))
abline(h = c(0.4,.5), col="red")
The only thing you have to do is place the variable, as you call it, with the “logistic trend,” in place of ‘0:1’
A second hint
df = as.matrix(c(0.131313131,0.111111111,0.090909091,
0.080808081,0.060606061,0.050505051,
0.060606061,0.080808081,0.090909091,
0.111111111,0.131313131))
barplot(prop.table(df, 2) )
this results in

R: Creating graphs with two y-axes

I'm looking to display two graphs on the same plot in R where the two graphs have vastly different scales i.e. the one goes from -0.001 to 0.0001 and the other goes from 0.05 to 0.2.
I've found this link http://www.statmethods.net/advgraphs/axes.html
which indicates how to display two y axes on the same plot, but I'm having trouble.
My code reads as follows:
plot(rateOfChangeMS[,1],type="l",ylim=c(-0.01,.2),axes = F)
lines(ratios[,1])
x = seq(-0.001,0.0001,0.0001)
x2 = seq(0.05,0.2,0.01)
axis(2,x)
axis(4,x2)
The problem I'm having is that, although R shows both axes, they are not next to each other as I would like, with the resulting graph attached. The left axis is measuring the graph with the small range, while the right is measuring the graph from 0.05 to 0.2. The second graph is, in fact, on the plot, but the scaling is so small that you can't see it.
Not sure if there is some etiquette rule I'm violating, never uploaded an image before so not quite sure how best to do it.
Any help would be greatly appreciated!
Thanks
Mike
Since you don't provide a reproducible example, or a representative dataset, this is a partial answer.
set.seed(1)
df <- data.frame(x=1:100,
y1=-0.001+0.002/(1:100)+rnorm(100,0,5e-5),
y2=0.05+0.0015*(0:99)+rnorm(100,0,1e-2))
ticks.1 <- seq(-0.001,0.001,0.0001)
ticks.2 <- seq(0.05,0.2,0.01)
plot(df$x, df$y1, type="l", yaxt="n", xlab="X", ylab="", col="blue")
axis(2, at=ticks.1, col.ticks="blue", col.axis="blue")
par(new=T)
plot(df$x, df$y2, type="l", yaxt="n", xlab="", ylab="", col="red")
axis(4, at=ticks.2, col.ticks="red", col.axis="red")
The reason your left axis is compressed is that both axes are on the same scale. You can get around that by basically superimposing two completely different plots (which is what having two axes does, after all). Incidentally, dual axes like this is not a good way to visualize data. It creates a grossly misleading visual impression.

How to get shaded background in xyplot in R?

using xyplot from the lattice package, I plot a time series over a number of years. I would to add a shaded area for some of these years to indicate that this time period was "special" (e.g. war).
Please apologize if this is trivial, but I could not figure out how to do that, so I would be happy if someone could help me out, or at least point me in the right direction. I think my main problem is that I don't really know how to approach this problem. I am still relatively new to R, and to lattice in particular.
Here a minimal example:
xyplot( rnorm(100) ~ 1:100, type="l", col="black")
In the corresponding plot, I would like the color of the background (from say x-values of 45 until 65) from the bottom to the top of the plotting area be shaded in, say, light grey.
Note that solutions that I have found so far use base graphics and the polygon-function, but there the intention is to shade the area under or above a curve, which is different from what I would like to do. I don't "just" want to shade the area below my line, or above my line. Instead I would like to shade the entire background for a given time interval.
If anyone could help me out here, I would be very grateful!
See ?panel.xblocks in the latticeExtra package:
library(latticeExtra)
x <- 1:100
xyplot( rnorm(100) ~ x, type="l", col="black") +
layer_(panel.xblocks(x, x > 20, col = "lightgrey"))
Try this:
xyplot(
rnorm(100) ~ 1:100, type="l", col="black",
panel=function (x,y,...){
panel.rect(xleft=45, xright=65,ybottom=-3, ytop=3,col="grey")
panel.xyplot(x,y,...)
}
)
The panel.rect() function controls the rectangle and is the lattice equivalent of the rect() function. It has a variety of settings that you may find useful. It is called first and then the xyplot() is put on top of it. You many need to play around a little to get your ybottom and ytop parameters to look as you like them.
trellis.focus("panel", 1, 1)
grid.rect(x =.55, , y=.5, w = .2, height=6,
gp = gpar(fill = "light grey"))
trellis.unfocus()
This differs from #JohnPaul's solution in a couple of ways (and I think his answer is better). This uses the center of the desired X-band for placement in "native coordinates" and calculates the width as 'range(xlim)/range(band)' and it modifies an existing plot. the grid.rect function is the grid packages lower level function that is used by panel.rect. I sometimes find this useful when integrating lattice panels inside the xyplot system defeats me.

Resources