I am plotting polygon in R and saving it.Problem, I am facing is that the whole plot is saved as png file but I want to save only the filled area in the polygon.
Is there a way for that ?
x<-c(0.000000000,0.010986328,0.006351471,-0.004634857)
y<-c(0.000000000,0.007232612,0.012841203,0.006199415)
file_name = paste("~/Downloads/Plot", ".png", sep="")
png(file_name,width=1280,height = 720,units="px",res=200)
plot(x,y,axes=FALSE,ylab='',xlab='')+polygon(x,y,col="#FF0000FF")
dev.off()
If you're drawing a monofigure plot (which is the default), then I believe there are three possible sources of spacing that can cause a plot element to not extend to the edges of the graphics device:
1: data coordinate limits that are larger than the extent of the plot element.
2: "internal spacing", which is best thought of as an expansion of the plot area that sits inside the margins.
3: margins. This is normally where axes, ticks, tick labels, axis labels, titles, and sometimes legends are drawn.
All of these sources of spacing can be eliminated with the following customizations:
1: set the xlim and ylim graphics parameters to perfectly fit the target plot element.
2: set xaxs='i',yaxs='i', which can be done with either a preemptive par() call or on the initial plot() call.
3: zero the margins with mar=c(0,0,0,0). This must be done with par() prior to the initial plot() call.
Example:
## generate data
pts <- data.frame(x=c(0.2,0.4,0.9,0.7),y=c(0.5,0.4,0.5,0.6));
## precompute plot parameters
xlim <- range(pts$x);
ylim <- range(pts$y);
## draw plot
par(mar=c(0,0,0,0));
plot(NA,xlim=xlim,ylim=ylim,xaxs='i',yaxs='i',axes=F,ann=F);
points(pts$x,pts$y,pch=21L);
polygon(pts$x,pts$y,col='red',pch=21L);
Multifigure plots can incur one additional source of spacing, namely outer margins, but it looks like that doesn't concern you for this problem. In any case, I'm pretty sure outer margins always default to zero anyway.
See par() for the relevant documentation.
It looks like I misunderstood the question. What you want is a transparent background, which is different from simply fitting the image size to the plot element.
You can use the png() function to set the background to be transparent by passing bg='transparent', as explained on the documentation page.
For example, here's my fitted image saved with a transparent background:
Note that not all image viewers will correctly detect and/or clearly depict the transparency of the background. I would highly recommend GIMP, which is basically a free Photoshop knockoff, albeit markedly lighter in features. GIMP depicts transparent regions as a kind of checkerboard of grey squares, which looks like this:
Related
So I've been running a DCA analysis on a species/site count spreadsheet (DCA file made using Vegan and decorana command). I'm having a bit of overlap with my points, so I'm trying to extend DCA 1 axis. I keep trying to use the xlim value to narrow it down to -2,2, but it just won't do it. For some reason, it seems tied to the ylim value. If I drop the ylim to -1,1, that will force the xlim to -2,2, but I can't actually have the ylim that small.
> plot(DCA, type = "n", xlim = c(-2,2))1
First plot shows result of this command. Trying to include a ylim of (-2,2) didn't change it either. Second plot shows result of this command:
> plot(DCA, type = "n", xlim = c(-2,2)), ylim = c(-2,2)2
I'm not exactly an expert at this, and I feel like I might be making a stupid mistake. Anyone got any ideas?
The plot is enforcing equal aspect ratio, and if you insist on having full range on y-axis (you do not set ylim), the x-axis will be set to accommodate the range you want to show on y-axis. You must either change the shape of your graphics display for a shorter x-axis, or then you also must set the range on y-axis with ylim Your choice. If you draw on square graphics window, the output will be square and it will be taken care that both the x and y scale (xlim, ylim) will fit the square. Changing the shape of the graphics window or setting both limits will help. Function locator() can be used to query coordinates in an existing plot, and these can be used to set up the new limits.
It is better to start again from a clean table. My intention was not to be rude, but trying to complement the answer in comments leads into terse messages where details and special cases are hard to handle. So I try to explain here how you can control the display and the axis limits in vegan ordination graphics. This answer has two main parts: (1) why we insist on equal aspect ratio, and (2) how to survive with equal aspect ratio. The latter can indeed be tricky, but we have not made it tricky because we are evil, but it is necessarily tricky.
First about the equal aspect ratio. This means that the numeric scales is equal on vertical (y) and horizontal (x) axes. In ordination the "importance" of an axis is normally reflected by its length: important axes are long, minor axes are short. In eigenvector methods this is determined by eigenvalues (which actually define the scatter of points along axes). In DCA (decorana) it should be the SD scaling so that one unit is equal to average width of species responses. We pay great attention in scaling axes accordingly, and we want to show this in the plot so that long x axis remains long and short y axis remains short even when the graph is designed for a portrait printer page shape. In this way the axis scaling (tic values) are equally spaced on both axes, and distances in the graph are equal horizontally, vertically or diagonally. Also if you draw a circle in the plot, it will remain a circle and not flattened or elongated to an ellipse. So this is something that we insist as a necessary feature of an ordination graph.
Insistence on equal scaling of equal axes comes with a price. One obvious price is that the ordination plot may not fill the graph area, but there can be a plenty of empty space in the graph for shorter axes. You can get rid of this adjusting graph shape – typically making it flatter. Another price that must be paid is the one that bit you: setting axis limits is tricky. However, this is not a vegan invention, but we use base R plot command with option asp = 1 for equal aspect ratio of axes.
To see how we can set axis limits with equal ratio, let us generate a regular rectangular grid and plot it:
x <- seq(-2, 2, by=0.2)
xy <- expand.grid(x, x)
plot(xy, asp=1)
This is a square grid on a square plot and nothing very special. However, if we plot the same grid on rectangle the aspect ratio remains equal, numeric scales are equal and the points remain equidistant on a square, but there is a lot of empty space and x-axis has longer numeric scale (but the points have unchanged numeric scale). If we try reduce only the x-scale, we face a disappointment:
plot(xy, asp=1, xlim=c(-1,1), main="xlim=c(-1,1)")
The graph is essentially similar as the first unlimited case with unchanged x. Setting xlim does not remove any points, but it only tells plot that do not reserve space but for that range on x-axis. However, y-scale is still longer and with equal aspect ratio it will also set the scale for x-axis and since there is empty space in the graph, the points are plotted there (this is analogous to having empty space even when there is nothing to plot there). To really limit the x-axis, you must simultaneously limit the y-axis accordingly:
plot(xy, asp=1, xlim=c(-1,1), ylim=c(-1,1), main="xlim=c(-1,1), ylim=c(-1,1)")
This give the desired x-limits .
Like I wrote, we did not invent that nastiness, but this is base R plot(..., asp=1) behaviour. I know this can be tricky (I have used that myself and sometimes I get irritated). I have been thinking could we be more user-friendly and by-pass base R. It is pretty easy to do this in a way that works in many normal use cases, but it is much harder to do this so that it works in most cases, and I don't know how to do this in all possible cases. If anybody knows, pull requests are welcome in vegan.
Finally, there is one tool that may help: vegan has an interactive dynamic plotting tool orditkplot where you can zoom into a plot by selecting a rectangle with left mouse button. However, this function may not work in all R systems, but if it works it gives an easy way of studying details of the plot (but if you have Mac with one-button mouse, don't ask me how it works: I don't know). You can start this with
orditkplot(mod, display="sites") # or "species", but only one
Even without orditkplot you can use base R function locator(): click the diagonally opposite corners of the rectangle you want to focus on, and this give you the xlim and ylim you need to set to zoom into this rectangle.
I am trying to simply plot a raster map and a legend barr, but i cannot seem to get it at the right distance from the raster. Is either over it or too far. Also, despite i indicate a fixed width and height to the SVG printing function, the final size does not look similar. Would it be a way to control the exact position of the legend barr when plotting legend.only=T? By the way, stack overflow does not allow me to upload an SVG image, so i am uploading a screen capture that looks similar.
here is how i see it in R
Here is how i get it from the file generated
Here is the script used to generate that image, region and range are polygons, and hill and tmax are rasters. The plotting in R works fine-I just want to know how avoid the changes in the image from the R window to the file. There seems to be something in the exporting function that is creating a high white space between the map and the barr, and it express only when exporting the graph.
svg(paste("/Users/",spp[i],"filename", ".svg",sep=""),
bg="transparent", width = 5,height=5)
plot(region)
plot(hill,col=grey(0:100/100), add=T, legend=F)
plot(range,add=T, border="turquoise")
plot(Tmaxc>tmaxsp,col=heat.colors(100),add=T,legend=F)
plot(Tmaxc>tmaxsp,col=heat.colors(100),legend.only=TRUE, horizontal = TRUE,
legend.args = list(text='Warming tolerance\u00B0C', side = 1, line = 2))
dev.off()
I have 4 maps to plot and would like to plot them in a single plot area so I use the code
par(mfrow=c(2,2), bty="n")
However, the result is lots of useless blank space around my maps (which become also too small).
The image below shows how much space is taken up by each map (blue rectangle) relative to the plot area.
Is it possible to go from the current situation (cf. 2 x 2 plot fit) to the desired situation (cf. Desired better fit)?
I tried changing width and height parameters (dev.new(width=x, height=y)) but with no luck.
I would suggest using the layout function, though using par is fine too. I give a simple example below, in which you can adjust par(mar=c()) settings for each individual plot, bringing them closer together. layout allows you to adjust relative heights of plots with the height parameter, which might be useful when trying to get panel plots to be all the same height, when you have the x-axis only for the lower tier plots.
y=runif(100)
x=runif(100)
layout(matrix(c(1,2,3,4), byrow=TRUE, ncol=2,nrow=2))
par(mar=c(3,3,0.5,0.5))
plot(y,x, xaxt='n')
par(mar=c(3,3,0.5,0.5))
plot(y,x, xaxt='n')
par(mar=c(3,3,0.5,0.5))
plot(y,x)
par(mar=c(3,3,0.5,0.5))
plot(y,x, yaxt='n')
Hi I am trying to plot and overlay multiple kernel density estimates into a single plot (using KS library). Since I want to overlay multiple kernels I am "playing" with the transparency color settings so that the final plot is easier to understand. However, for some reason when I plot it, it shows a grid pattern with the color color/transparency filling which I don't know how to remove so that the color is all uniform...
These are the options that I use to export my plot as a PDF,
pdf(paste(database$species[1],".pdf",sep=""),width=11,height=8,paper="a4r",pointsize=15)
par(mfrow=c(1,1))
par(mar=c(5,4,4,3))
This is the code that I use to make the plot and overlay it with others,
# plot of KUD-Depth utilization
plot(ddhat.day,cont=c(95),lwd=1,add=F,display="filled.contour2",col=c(NA,"#8B000040"),xaxs="i",yaxs="i",
plot(ddhat.night,cont=c(95),lwd=1.5,add=TRUE,display="filled.contour2",col=c(NA,"#00008020"),
xlab="",ylab="",las=1,ann=F,bty="l",cex=0.6,yaxs="i",xaxs="i")
xlab="",ylab="",las=1,ann=F,bty="l",cex=0.6,xlim=c(0,max(dd[,1]+dd[,1]*0.6)),ylim=c(50,-10))
plot(ddhat.day,cont=c(50),add=T,display="filled.contour2",col=c(NA,"#FF000040"),lty=2,lwd=1,
xlab="",ylab="",cex=0.6)
plot(ddhat.night,cont=c(50),add=TRUE,display="filled.contour2",col=c(NA,"#00BFFF40"),lwd=1.5,
xlab="",ylab="",cex=0.6)
plot(ddhat.day,cont=c(0,0),drawpoints=TRUE,col="black",ptcol="grey15",cex=0.45,add=TRUE)
plot(ddhat.night,cont=c(0,0),drawpoints=TRUE,col="black",ptcol="grey15",cex=0.45,add=TRUE,pch=4)
dev.off()
If anybody has an idea why when I use this transparency option for color it shows a grid too and ho to remove it so it shows a smooth surface that would be fantastic!
You have a really weird way of specifying col. Instead of those NAs which I'm pretty sure aren't supposed to be there, try using the rgb function. It takes (at least) 4 arguments, which are the red, green, blue and alpha (transparency) channels, expressed as fractions.
col=rgb(0, 0, 0, 1) # black
col=rgb(0, 1, 1, .5) # green + blue = cyan, 50% opaque
col=rgb(1, 0, 0, .2) # red, 20% opaque = 80% transparent
This is a pretty old question but I thought I'd throw my response out there for future reference. The grid that you are seeing (if it's the grid I think you are referring to) is the result of creating a raster graphic in a pdf file. The pdf does a poor job of rendering the raster. If you want to make the grid (really thin white lines, right?) go away, try saving the file as a native raster file type (eg., jpeg(),tiff).
In most cases, outputting an R graphic as a pdf() works great because then you have a nice, scalable vector graphic for which you don't have to worry about resolution. However, when you create figures like an image plot sometimes it gets wonky (this only happens on my Mac though and not on my PC).
Some code below may illustrate. If you run the pdf version (on a mac) you will get the figure below. If you run the jpg version it will go away.
library(MASS)
library(ks)
data(iris)
fhat <- kde(x=iris[,1:2])
jpeg("test.jpg")
plot(fhat, display="filled.contour2", cont=seq(10,90,by=10))
dev.off()
pdf("test.pdf")
plot(fhat, display="filled.contour2", cont=seq(10,90,by=10))
dev.off()
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