I'm creating a correlation heatmap in R with levelplot (lattice).
I'd like borders between the boxes, but not along the outside since it interferes with the plot border.
How can I remove the outer borders from the boxes?
Here is my code:
levelplot(matrix, border="black",
colorkey=list(height=.25, space="right", at=seq(-1, 1, .25), cuts=7),
scales=list(y=(list(cex=1)), tck = c(1,0), x=list(cex=1, rot=90)),
main="Leaf Correlations", xlab="", ylab="",
col.regions=scalebluered)
and here is what it looks like.. I don't like the double lines on the edges..
EDIT: here is a reproducible example:
data(mtcars)
cars.matrix <- as.matrix(mtcars[c(2:8)])
cars.corr <- cor(cars.matrix)
levelplot(cars.corr, border="black", colorkey=list(height=.25, space="right",
at=seq(-1, 1, .25), cuts=7),
scales=list(y=(list(cex=1)), tck = c(1,0), x=list(cex=1, rot=90)),
xlab="", ylab="")
OK, the fix for this is simple if a bit obscure.
Just use lattice.options() to reset the value of axis.padding used for factors, changing it from its default value of 0.6 (a little padding) to 0.5 (no padding), and you should be fine:
lattice.options(axis.padding=list(factor=0.5))
## An example to show that this works
data(mtcars)
cars.matrix <- as.matrix(mtcars[c(2:8)])
cars.corr <- cor(cars.matrix)
levelplot(cars.corr, border="black", colorkey=list(height=.25, space="right",
at=seq(-1, 1, .25), cuts=7),
scales=list(y=(list(cex=1)), tck = c(1,0), x=list(cex=1, rot=90)),
xlab="", ylab="")
For possibly-useful-future-reference, I figured this out by taking a quick look at the code used by prepanel.default.levelplot(). (The various prepanel.*** functions are responsible, among other things, for determining the coordinates and minimal area that should be allocated to each panel so that the objects to be plotted into it will all fit nicely.)
head(prepanel.default.levelplot, 4)
1 function (x, y, subscripts, ...)
2 {
3 pad <- lattice.getOption("axis.padding")$numeric
4 if (length(subscripts) > 0) {
A bit of digging shows that a lot of the par commands may not make it to Lattice package graphics. For example, par(bty = 'n') won't work in this levelplot example.
Unlike base R graphs, lattice graphs are not effected by many of the options set in the par( ) function. To view the options that can be changed, look at help(xyplot). It is frequently easiest to set these options within the high level plotting functions ... you can write functions that modify the rendering of panels.
Try passing the axis color directly into the graphic ala the method suggested by Yangchen Lin here: R lattice 3d plot: ticks disappear when changing panel border thickness
axis.line = list(col='transparent')
Related
If you call function hist on r, you will note that the box that usually surrounds plotting region doesn't appear, instead, only rulers indicating plot scale appear on the bottom and on the left. If you use r a lot you may probably have noticed this already. my question is: there is some graphical parameter or workaround to make this happen on any other plot of basic r (like in a scatterplot, a line plot, a qq plot or whatever)?
The only parameter I found was axes, but setting it to FALSE makes it disappear not only the box, but also the rulers.
You are looking for box().
op <- par(mfrow=c(1, 2))
hist(mtcars$mpg, sub="w/o box")
hist(mtcars$mpg, sub="w/ box")
box() ## <-- this
par(op)
the answer is bty graphical parameter:
x= matrix(rnorm(100), ncol= 2)
plot(x, bty= 'n')
I have a plot as shown below. To this plot i would like to add a similar kind of line plot somewhere within the plot (bottomright or bottomleft). The command for the subplot i am using is
plot( 1:121, sample(1:121),type='l' )
It plots right on the top of the first one. I need it as a small plot either at the bottomleft or bottomright. COuld someone help to do this in R?
op <- par(no.readonly = TRUE)
set.seed(42)
plot(rnorm(100), runif(100))
par(new=TRUE, oma=c(3,1,1,2))
layout(matrix(1:4,2))
plot(rnorm(100), runif(100), col="blue", xlab="", ylab="")
par(op)
If you set the parameter new to TRUE, the canvas will not be cleaned before the next plotting command:
par( new= TRUE )
I leave it to your ingenuity to create a suitable white background and position the new plot :-) Hint: take a look at the omd parameter in the manual for par.
I am swimming backwards in my R knowledge. Please help!
ExampleData:
Site, Aluminum_Dissolved, Federal_Guideline
M1, 0.1, 0.4
M1, 0.2, 0.4
M1, 0.5, 0.4
M2, 0.6, 0.4
M2, 0.4, 0.4
M2, 0.3, 0.4
I have a simple function:
boxplot(ExampleData$Aluminum_Dissolved ~ ExampleData$Site, col="purple",
par (cex.axis=2, las=2), mar=c(7,4,4,2)+0.1
X and Y axis Labels:
Once I increase the values on the axis so much, my xlab and ylab are obscured by axis text.
I have tried using:
`mpg=c(3,1,0)`
and altering values but that seems to get mess up with margin increase
`mar=c(7,4,4,2)+0.1`
I tried scrapping the xlab and ylab altogether and using mtext, but I can't get that to give me labels outside my axis text that are parallel to the y-axis. I have tried:
`mtext("Dissolved Aluminum", side=2, adj=0, las)` etc....
45 degree text on x-axis:
And, finally, I have tried reconstructing my x and y-axis with no avail and I can't seem to rotate my x-axis labels 45 degrees using SRT function. I have tried:
boxplot(ExampleData$Aluminum_Dissolved ~ ExampleData$Site, col="purple",
xaxt='n', yaxt='n', axis(2, cex.axis=2, xlab="Dissolved Aluminum"),
axis(1, cex.axis=2, srt=45)
and this doesn't work. What am I missing. Is there a simple way to do this I am missing...
A quick tutorial:
The way that plotting works in base R graphics is general thought of as a "pen on paper" model. This means that each function you call draws "on top" of what you've created up to that point. Graphical parameters can either be set beforehand via a call to par, or passed directly to the plotting function directly (with some caveats). So for example, I would have done this as:
par(cex.axis=2, las=2,mar=c(7,4,4,2)+0.1)
boxplot(Aluminum_Dissolved ~ Site,data = dat,
col="purple",ylab = "Dissolved Aluminum",xlab = "Dissolved Aluminum")
If you wanted custom axes, you would have done something like:
par(cex.axis=2, las=2,mar=c(7,4,4,2)+0.1)
boxplot(Aluminum_Dissolved ~ Site,data = dat,
col="purple",ylab = "Dissolved Aluminum",xlab = "Dissolved Aluminum",axes = FALSE)
axis(...)
Subsequent call (on separate lines) to things like points or lines would add points or lines to the graph, respectively.
The caveat with par is that some parameters can only be set by calling par directly, not by passing them as named arguments to plotting functions. There is a list of those (which includes mar) located at ?par.
#joran was right -- i think i just messed up the order of the function. I get the axis labels working despite greater size in text using this code:
boxplot(ExampleData$Aluminum_Dissolved ~ ExampleData$Site, col="purple", par(cex.axis=2, cex.lab=1.8), ylab="Dissolved Aluminum")
The only problem with this is that the label is very close to text, but it is alright.
I have a series of plots that I want on a single page. I first use the command layout to specify my plot layout:
layout(matrix(c(1,1,2,2,1,1,2,2,3,4,5,6),3,4,byrow=TRUE))
For plot 1, I have something like:
plot(Easting,Northing, pch=16, col=grey(cex.size)) #The cex.size colours my dots according to some value
I now want to draw an inset plot on plot 1, but not move to plot 2 yet.
I tried following the code :
par(fig=c(0.75, 1, 0, 0.25), new = T)
plot(spp.tmp[,1:2], col=cols[spp.tmp[,3]+1], pch=16)
par(fig=c(0,1,0,1))
But this doesnt work, as par(fig()) command overwrites my layout, and the inset plot appears on the bottom corner of my overall figure, not just in the bottom corner of plot 1.
Two options,
You coul try and include the inset within your layout command (if you were to stick with layout
Here is a case where the first plot spans two rows and column, the second is an inset in the bottom right corner of the first. The third plot is below, the same size as the first, but without an inset.
layout( matrix(c(1,1,1,2,3,3,3,3), 4, 2, byrow = TRUE) )
## show the regions that have been allocated to each plot
layout.show(3)
An alternative is to use subplot from the TeachingDemos package
library(TeachingDemos)
layout(matrix(c(1,1,0,2),2,2,TRUE))
plot(1)
subplot(plot(1), x = c(1.2),y=0.8)
plot(2)
This is my hatchet approach using base graphics. Because your messing around with par(), why dont you change around the order in matrix and plot the tricky one last. This way the par settings do not affect any more plots in your layout, if you were to plot the tricky one first. It seems simplistic in this example, but when you have lots of plots and you want an inset in only 1, it works.
##generate some data
x<-rnorm(50)
y<-rnorm(50)
##set the layout
##so your first plot is plotted last
layout(matrix(c(2,2,0,1), 2,2, byrow=T))
#plot 1 is on the bottom right
plot(x,y, col="grey30", xlab="", ylab="")
#plot 2 is across the top
plot(x,y, col="grey30", xlab="", ylab="")
##set par to place the next plot in the existing plotting area
## and use fig to position it
par(fig=c(.65, .95, .55, .85), new = TRUE)
#inset 3rd plot int top plot, this effectively gives you a blank plot to populate
plot(x,y, col="white", xlab="", ylab="")
#and make the background white
rect(par("usr")[1],par("usr")[3],par("usr")[2],par("usr")[4],col = "white")
##then just add your points afterwards
points(x,y,col="tomato")
I'm trying to attach a legend to a plot in R.
I tried the following code ( taken from http://www.harding.edu/fmccown/r/ )
# Define cars vector with 5 values
cars <- c(1, 3, 6, 4, 9)
# Define some colors ideal for black & white print
colors <- c("white","grey70","grey90","grey50","black")
# Calculate the percentage for each day, rounded to one
# decimal place
car_labels <- round(cars/sum(cars) * 100, 1)
# Concatenate a '%' char after each value
car_labels <- paste(car_labels, "%", sep="")
# Create a pie chart with defined heading and custom colors
# and labels
pie(cars, main="Cars", col=colors, labels=car_labels,
cex=0.8)
# Create a legend at the right
legend(1.5, 0.5, c("Mon","Tue","Wed","Thu","Fri"), cex=0.8,
fill=colors)
However, this does not work really well. After the pie(cars, main="Cars", col=colors, labels=car_labels,cex=0.8) line , the plot is shown without a legend :-) .......Every example I see on the Internet seems to have the legend function after the plotting function so it seems very weird..............
When I try to execute the legend function I get
legend(1.5, 0.5, c("Mon","Tue","Wed","Thu","Fri"), cex=0.8,
+ fill=colors)
Error in strwidth(legend, units = "user", cex = cex) :
plot.new has not been called yet
You are off the coordinate system. Try this instead
# Create a legend at the right
legend("topleft", c("Mon","Tue","Wed","Thu","Fri"), cex=0.8, fill=colors)
which produces the chart below:
See the help page for legend for different placement options.
I think the position 1.5, 0.5 puts it off the page. Try
legend("right", c("Mon","Tue","Wed","Thu","Fri"), cex=0.8, fill=colors)
After the pie function it appears with no legend; the legend function adds the legend to the current plot.
PS. You may also consider other types of plots. Pie charts are notorious for being visually misleading.