Contour plot x-labeling - r

My question is very similar to this question but I wish to write special values on the x-axis.
I have the following code:
x <- c(1:12)
y <- c(1:12)
filled.contour(c(2,4,7,10,14,21,30,60,90,120,180,365), y, outer(x,y))
Gives the following plot :
My problem is that I don't want the plot to be squeezed on the left but want all values in c(2,4,7,10,14,21,30,60,90,120,180,365) to be equally spaced on the x-axis.
How can I do this?
As an extension, how can I put characters "two", "four", ... instead of 2, 4, ... on the x-axis?
Thanks

This is a start:
x <- 1:12
y <- 1:12
xvals <- c(2,4,7,10,14,21,30,60,90,120,180,365)
fx <- as.numeric(as.factor(xvals))
filled.contour(fx, y, outer(x,y),
plot.axes= {
axis(2) ## plain
axis(1,at=fx,labels=xvals)
})
However, you can see that the '180' label is already getting omitted, which means that things are going to be even worse if you translate the x-axis labels into words (do you really want the last tick label to read "three hundred sixty-five")? (You can use par(las=3) to turn the labels vertical, but that's ugly too.)
This question points us to qdap::replace_number(), but it doesn't seem to work for single-digit numbers ...
library(qdap)
filled.contour(fx, y, outer(x,y),
plot.axes= {
axis(2) ## plain
axis(1,at=fx,labels=replace_number(xvals))
})
update: the qdap maintainer has already fixed this bug; if you need the latest version you could try devtools::install_github("qdap","trinker")
If you're in a big hurry you could just fix the result by hand.

Related

R rasterVis levelplot: a white line erroneously appears

I am plotting maps of atmospheric pollutant fields, or meteorological field, difference between such fields, often overlayed with orography.
My fields are gridded.
A white line misteriously appears, sometimes two.
This seems to happen a bit randomly. I mean: same code and fields, same line; but when I change fields, or color scales, it changes position, or it disappears, or another one appears. Sometimes horizontal, sometimes vertical.
Here is my code
#!/usr/bin/env Rscript
library(rasterVis)
library(RColorBrewer)
NX <- 468
NY <- 421
hgt <- matrix(0.,NX,NY)
# read from file:
ucon <- file("hgt.dat", open="rb")
for (n in seq(1,NX)) {
hgt[n,] <- readBin(ucon, "numeric", n=NY, size=4)
}
close(ucon)
hgtbks <- c(-100,10,500,1000,1500,2000,2500,3000,3500)
hgtcols <- colorRampPalette(c("gray30","white"))(length(hgtbks)-1)
tit <- "Orography"
bkstart=50.0; bkmax=1500.; bkby=100.
bks <- seq(bkstart, bkmax, bkby)
nbks <- length(bks)
cols <- rev(colorRampPalette(brewer.pal(11,"Spectral"))(nbks-2))
cols <- c("white",cols)
legendbreaks <- seq(1,nbks)
legendlabels <- formatC(bks,digits=3)
legendlabpos <- legendbreaks
rpl <-
levelplot(hgt, margin=FALSE , col.regions= hgtcols, at= hgtbks
, main= list(label=tit, cex=1.8)
, colorkey=list(draw= TRUE, col=cols, at=legendbreaks
, labels=list(labels=legendlabels, at=legendlabpos, cex=1.2))
, xlab=NULL, ylab=NULL, scales= list(draw= FALSE))
png("whiteline.png", width=800, height=840)
plot(rpl)
graphics.off()
I would really like to upload a file with my data, but for the moment
I could not find a way to do it (I don't think I can do it, not even an ASCII file). The data matrix (468x421) is too big to be explicitly included in the code, but it really is the orography file
shown in the picture (elevation in meters above mean sea level).
And here is the resulting "white line" map:
Really, I think this might be a levelplot bug. It seems to happen both when hgt is a matrix and when it is a proper raster object: this doesn't seem to make a difference.
Any idea?
I think I found a workaround.
By setting zero padding on the 4 sides, I managed to make the whiteline disappear from a series of maps.
First I defined:
zpadding <- list(layout.heights= list(top.padding=0, bottom.padding=0),
layout.widths= list(left.padding=0, right.padding=0))
then I added, among the parameters of the levelplot call:
par.settings=zpadding
As I said, I don't think this is a proper solution, but a workaround.
The problem seems related to any rescaling of the plot area.
In fact, when a rescaling is forced by, for example, having 4 or 5 digits (instead of 2 or 3) in the colorbar labels, a white line may reappear.
I hope this may point in the right direction other people, either users or developers of levelplot and related software.

How to cumulate/preserve old frames using the Animation package?

The code below plots 10 dots on the x-axis, one at a time. At any one point in time, the animation displays only one dot. I am looking to end up with a plot with all 10 dots. I would like the second dot to be added to the plot showing the first dot; the third to be added to the plot showing the first two dots, etc. I looked at the documentation for saveGIF for a parameter that would somehow cumulate the frames, but could not find a relevant parameter there. It looks like it should be possible. Yihui Xie, the creator of the animation package, did exactly that in the top right plot of this example https://yihui.org/animation/example/buffon-needle/
library(animation)
saveGIF({
for (i in 1:10) {
x <- rnorm(1,0,1)
plot(x,0,xlim=c(0,1),ylim=c(-1,1))
}
})
You can generate the 10 numbers in advance, and plot them incrementally, e.g.,
library(animation)
saveGIF({
n <- 10
x <- rnorm(n, 0, 1)
for (i in seq_len(n)) {
plot(head(x, i), 0, xlim = c(1, n), ylim = c(-1, 1))
}
})

Bar plot with Y-axis break [duplicate]

I found a lot of SO question and answers addressing break and gaps in axis. But most of them are of low quality (in an SO meaning) because of no example code, no picture or to complex codes. This is why I asking.
I try to use library(plotrix). If there is a solution without it and/or another library it would be ok for me, too.
This is a normal R-barplot.
barplot(c(10,20,500))
To break the axis and add gap I tried this.
gap.barplot(c(10,20,500),gap=c(50,400), col=FALSE)
The result is not beautiful.
There is no space between the bars. space parameter from barplot() is not accepted by gap.barplot().
The bars have different widths.
The position of the tics are not in the middle of the bar.
Can I control that parameters with plotrix? I don't see something about it in the documentation.
Is there another library or solution for my problem?
There are so many different answers because of a lot of individual problems. For your problem you can try the following. But there is always a better solution out there. And IMO its always better to show your complete data instead of cropping it.
# Your data with names
library(plotrix)
d <- c(10,20,500)
names(d) <- letters[1:3]
# Specify a cutoff where the y.axis should be splitted.
co <- 200
# Now cut off this area in your data.
d[d > co] <- d[d > co] - co
# Create new axis label using the pretty() function
newy <- pretty(d)
newy[ newy > co] <- newy[ newy > co] + co
# remove values in your cutoff.
gr <- which(newy != co)
newy <- newy[ gr ]
# plot the data
barplot(d, axes=F)
# add the axis
axis(2, at = pretty(d)[gr], labels = newy)
axis.break(2, co, style = "gap")
As an alternative you can try to log your axis using log="y".

How to break axis in a barplot (maybe using plotrix gap.barplot)?

I found a lot of SO question and answers addressing break and gaps in axis. But most of them are of low quality (in an SO meaning) because of no example code, no picture or to complex codes. This is why I asking.
I try to use library(plotrix). If there is a solution without it and/or another library it would be ok for me, too.
This is a normal R-barplot.
barplot(c(10,20,500))
To break the axis and add gap I tried this.
gap.barplot(c(10,20,500),gap=c(50,400), col=FALSE)
The result is not beautiful.
There is no space between the bars. space parameter from barplot() is not accepted by gap.barplot().
The bars have different widths.
The position of the tics are not in the middle of the bar.
Can I control that parameters with plotrix? I don't see something about it in the documentation.
Is there another library or solution for my problem?
There are so many different answers because of a lot of individual problems. For your problem you can try the following. But there is always a better solution out there. And IMO its always better to show your complete data instead of cropping it.
# Your data with names
library(plotrix)
d <- c(10,20,500)
names(d) <- letters[1:3]
# Specify a cutoff where the y.axis should be splitted.
co <- 200
# Now cut off this area in your data.
d[d > co] <- d[d > co] - co
# Create new axis label using the pretty() function
newy <- pretty(d)
newy[ newy > co] <- newy[ newy > co] + co
# remove values in your cutoff.
gr <- which(newy != co)
newy <- newy[ gr ]
# plot the data
barplot(d, axes=F)
# add the axis
axis(2, at = pretty(d)[gr], labels = newy)
axis.break(2, co, style = "gap")
As an alternative you can try to log your axis using log="y".

add labels to lattice barchart

I would like to place the value for each bar in barchart (lattice) at the top of each bar. However, I cannot find any option with which I can achieve this. I can only find options for the axis.
Create a custom panel function, e.g.
library("lattice")
p <- barchart((1:10)^2~1:10, horiz=FALSE, ylim=c(0,120),
panel=function(...) {
args <- list(...)
panel.text(args$x, args$y, args$y, pos=3, offset=1)
panel.barchart(...)
})
print(p)
I would have suggested using the new directlabels package, which can be used with both lattice and ggplot (and makes life very easy for these labeling problems), but unfortunately it doesn't work with barcharts.
Since I had to do this anyway, here's a close-enough-to-figure it out code sample along the lines of what #Alex Brown suggests (scores is a 2D array of some sort, which'll get turned into a grouped vector):
barchart(scores, horizontal=FALSE, stack=FALSE,
xlab='Sample', ylab='Mean Score (max of 9)',
auto.key=list(rectangles=TRUE, points=FALSE),
panel=function(x, y, box.ratio, groups, errbars, ...) {
# We need to specify groups because it's not actually the 4th
# parameter
panel.barchart(x, y, box.ratio, groups=groups, ...)
x <- as.numeric(x)
nvals <- nlevels(groups)
groups <- as.numeric(groups)
box.width <- box.ratio / (1 + box.ratio)
for(i in unique(x)) {
ok <- x == i
width <- box.width / nvals
locs <- i + width * (groups[ok] - (nvals + 1)/2)
panel.arrows(locs, y[ok] + 0.5, scores.ses[,i], ...)
}
} )
I haven't tested this, but the important bits (the parts determining the locs etc. within the panel function) do work. That's the hard part to figure out. In my case, I was actually using panel.arrows to make errorbars (the horror!). But scores.ses is meant to be an array of the same dimension as scores.
I'll try to clean this up later - but if someone else wants to, I'm happy for it!
If you are using the groups parameter you will find the labels in #rcs's code all land on top of each other. This can be fixed by extending panel.text to work like panel.barchart, which is easy enough if you know R.
I can't post the code of the fix here for licencing reasons, sorry.

Resources