Adding Points to filled.contour in R - at the right place - r

I'd like to add a point to an existing filled.contour plot, using the following code:
MyFunction <- function(x,y){
return(dnorm(sqrt(x^2+y^2)))
}
wrapper <- function(x, y, my.fun, ...) {sapply(seq_along(x), FUN = function(i) my.fun(x[i], y[i], ...))}
meshstep <- 0.5
x<- seq(-20,20,meshstep)
y <-seq(-20,20,meshstep)
z <- outer(x,y,FUN = wrapper, my.fun=MyFunction)
filled.contour(x,y,z, col=rev(heat.colors(n=20, alpha=0.7)), nlevels=15)
points(0,0)
I'm pretty surprised that points(0,0) didn't put a point into the origin of the plot, but roughly located at x=10,y=0. Also, locator() seems to be prompting coordinates with respect to that 'new' coordinate system as well. Why is that?

You can find a detailed answer here :
Plotting a box within filled.contour plots in R?
In short, filled.contour use two different coordinates system, one for the filled contour and one for the legend. To solve your problem, you either have to use another function, or to put your points into the plot.axes argument :
filled.contour(x,y,z, col=rev(heat.colors(n=20, alpha=0.7)), nlevels=15,
plot.axes={points(0,0)})

The best option is to use the plot.axes argument as mentioned by #juba. But, if you really need to add something after the plot has finished then you can use locator to click on 2 points in the plot where you know the values of the points in the coordinate system you want to use (opposite corners), then use the updateusr function from the TeachingDemos package to modify the current coordinate system to the one that you want to use. You can then add to the plot using the new coordinate system (you may need to set par(xpd=NA)).

Related

Range and increment of data in Matlab

Lets consider I am given a plot and I do not have its x and y vectors but I would like to extract them from the plot in Matlab. Also I am interested to know the increment of data (step size) in both horizontal and vertical axis(x and y axis).
I was thinking of using :
h=gca % Get current axis
X=get(h,'xdata');
Y=get(h,'ydata');
stepsize=X(2)-X(1);
But these command produce an error message that :
xdata and ydata are not accessible property of axis. Any suggestion how to find the x and y vectors for any given curve.
If I understand correctly, these are the two things you want to know:
You have a figure containing a plot of some arbitrary 2d line, whose x_vec, y_vec are unknown to you and you want to extract them from the figure\axes.
You want to get the xtick and ytick positions used in the figure you have.
The reason your code does not work, is because you're trying to access a property of the axes, whereas what you want to access is the property of the line (i.e. the curve in the plot).
To solve your first problem, you can resort to the following methods:
Manual: using the edit plot figure tool you can get to the XData and YData properties of the line, in the following manner:
Programmatic: you need to find the handle (i.e. pointer) to the line, and then use your code on that handle (and not on gca):
%// If there's only one entity (child) in the axes:
hLine = get(gca,'Children');
%// If there's more than one child:
hChildren = findobj(gca,'Type','line');
hLine = hChildren(1); %// Or any other logic you need to pick the correct line
%// Then comes your code:
xD = get(hLine,'XData'); yD = get(hLine,'YData');
For the second problem you can use gca to get XTick and YTick:
xT = get(gca,'XTick'); yT = get(gca,'YTick');
To get the step size I'd suggest simply using diff().
I'm not sure I quite understand your question. You mean get x and y data of a curve? If yes, then maybe it'll help looking into 'ginput'.
For example, picking 10 points from a figure window you can use the following command
[x,y] = ginput(10)

Plotting straight surface with lattice::wireframe()

Assume I want to plot the following dataframe:
df <- data.frame(expand.grid(1:10,1:10),rep(10,100))
colnames(df) <- c("x","y","z")
with the lattice wireframe() function:
wireframe(z~x*y,df,colorkey=TRUE,drape=TRUE)
How do I get it to plot the given coordinates? I would assume it has something to do with having to scale/adjust the z-axis as the automatic scaling within wireframe is probably confused by all z-coordinates being equal.
This is from the help page scales section: "The most common use for this argument is to set arrows=FALSE, which causes tick marks and labels to be used instead of arrows being drawn (the default)." So just add that as a list value to 'scales':
wireframe(z~x*y,df,colorkey=TRUE,drape=TRUE,
scales=list(arrows=FALSE), zlim=c(0,10.1))
The failure of wireframe to display anything when the plotted plane is at one of the extremes seems to be at least "unexpected behavior" if not a bug. I suspect you would not see this in real data. Your use of drape doesn't make much sense since the entire data-plane plane gets displayed at the white midpoint. (Again this is probably not a problem if you have something other than this pathological example.)
Just add a zlim argument.
wireframe(z~x*y,df,colorkey=TRUE,drape=TRUE, zlim=c(0,20))

Displaying Points in Scatterplot

Currently trying to write a simple r script that when passed in 2 vectors of values would calculate some relationship between them (in the given case, r_square) and display it in a graph with the best fit line.
temp1 <- sample(20000,1367,replace=F,prob=NULL)
temp2 <- sample(20000,1367,replace=F,prob=NULL)
fit <- lm(temp1 ~temp2)
plot(temp1,temp2,ann="true")
abline(fit)
(here using sample in lack of real data).
The problem is that i'm trying to add interactivity which would display point's value (X/Y coordinates of sort) on hover.
I've managed to find a few functions that identify them by the their order in the vectors (HWidentify, identify, etc). But none of them give the actual value (x,y) so i was wondering if it's possible to print out coordinates that aren't permanent.
If you're trying to print the coordinates, you could use the labels argument to the identify() function.
identify(temp1, temp2, labels=paste(temp1, temp2, sep=","))
The HWidentify function also has a labels argument that you can set to whatever you want, using the paste function like #JeanV.Adams works similarly and then you have the hover functionability.

Is it possible to rotate a plot in R (base graphics)?

I searched for this and found that with {grid} there are ways to rotate an image, and that for some plots you can play with their rotation (for example plot(x,y) instead of plot(y,x)).
However, I want to know if there is a generic method to rotate a plot in R (one that would work for ANY plot generated in base graphics) ?
you could export the graphic, read it back in, and display it rotated as a rasterGrob, say, (or a rasterImage after rotating the matrix, or a grImport grob if you want vector paths)
plot(1:10, rnorm(10))
library(grid)
cap <- grid.cap()
grid.newpage()
grid.raster(cap, vp=viewport(angle=30))
The new gridGraphics package may now be a better alternative.
Note: this doesn't seem to work with Rstudio's graphics device, presumably they haven't implemented grid.cap.
It's kind of possible via the gridGraphics package, although it feels a bit rough on the edges (the examples in ?grid.echo don't all work for me),
plot(1:10, rnorm(10))
library(gridGraphics)
grab_grob <- function(){
grid.echo()
grid.grab()
}
g <- grab_grob()
grid.newpage()
pushViewport(viewport(width=0.7,angle=30))
grid.draw(g)
I'm reasonably certain that there isn't a way with base graphics itself to do this generically. There is however the gridBase package which allows one to mix base graphics and grid graphics in a 'plot'. The vignette for the package has a section on embedding base graphics in grid viewports, so you might look there to see if you can cook up a grid wrapper around your plots and use grid to do the rotation. Not sure if this is a viable route but is, as far as I know, the on only potential route to an answer to your Q.
gridBase is on CRAN and the author is Paul Murrell, the author of the grid package.
After browsing the vignette, I note one of the bullets in the Problems and Limitations section on page, which states that it is not possible to embed base graphics into a rotated grid viewport. So I guess you are out of luck.
Spinning 3D Scatterplots
You can also create an interactive 3D scatterplot using the plot3D(x, y, z) function in the rgl package. It creates a spinning 3D scatterplot that can be rotated with the mouse. The first three arguments are the x, y, and z numeric vectors representing points. col= and size= control the color and size of the points respectively.
# Spinning 3d Scatterplot
library(rgl)
plot3d(wt, disp, mpg, col="red", size=3)
A function rotate_plot to be used like
rotate_plot(some_base_plot(x, y, ...))
isn't possible because most of the base plot don't return a value.
Some of the plots contain a horiz argument to allow you to choose which way round you want the plot drawing. Take a look at barplot.default to see how to implement this. (Warning: it's messy.)
#ucfagls's suggestion to use gridBase is your best bet. There are some examples of its use in Appendix B of Murrell's R Graphics.
Given that its possible to write your own plot functions using base graphics, I can't see how a single solution could exist. Is what you want really just a way to rep lace x data with y data? What exactly do you mean by "rotate"?
Yes it is possible to rotate the the plot in R
by using the function Coord flip() in r
you can flip the graph from horizontal to vertical and from vertical to horizontal.

Plotting a box within filled.contour plots in R?

I'm trying to plot a box within a filled.contour plot, but unfortunately, when I plot the lines() after the filled.contour plot is created, the figure is shifted to the right because the scale forces the image to the left, but the box stays at the same coordinates. Here's what my code looks like:
dev.new(width=6,height=7)
mypredict<-matrix(data=mypredict,nrow=20,ncol=25)
filled.contour(x=seq(from=-1.5,to=1.5,length=20),
y=seq(from=1,to=3.75,length=25),
z=mypredict,
col=hsv(h=seq(from=2/3,to=0,length=20),s=1,v=1)
)
top <- 3.42
bot <- 1.56
lines(c(-1,-1),c(bot,top))
lines(c(1,1),c(bot,top))
lines(c(-1,1),c(top,top))
lines(c(-1,1),c(bot,bot))
Does anyone know how I can plot those lines within the filled.contour function? Otherwise, the lines do not plot correctly onto the main image, since the scale/legend of the graph is placed on the right.
Thanks!
The manual page for filled.contour explains the problem (and gives a solution)
This function currently uses the ‘layout’ function and so is restricted
to a full page display. As an alternative consider the ‘levelplot’
and ‘contourplot’ functions from the ‘lattice’ package which work in
multipanel displays.
The output produced by ‘filled.contour’ is actually a combination
of two plots; one is the filled contour and one is the legend.
Two separate coordinate systems are set up for these two plots,
but they are only used internally - once the function has returned
these coordinate systems are lost. If you want to annotate the
main contour plot, for example to add points, you can specify
graphics commands in the ‘plot.axes’ argument. An example is
given below.
So essentially you pass some instructions as the plot.axes parameters to override standard behaviour.
In your example:
filled.contour(x = seq(from=-1.5,to=1.5,length=20),
y = seq(from=1,to=3.75,length=25), z = mypredict,
col = hsv(h=seq(from=2/3,to=0,length=20),s=1,v=1),
plot.axes = {axis(1); axis(2); rect(left, bottom, right, top);})
Note that you have to recreate the two axes otherwise they will not be drawn. Also, no need to use the lines statement, when there is a rect function! :)
Hope this helps

Resources