I tried to use NetCDF file to draw a raster map in R using raster and ncdf4 packages.
The range of my data is too large, but almost my data distributes within 0-2000. You can look at the histogram of my data:
So I want to draw a plot with the interval of 200, like seq(0, 2000, 200).
But when I used these intervals, the values which are larger than 2000 were recognized by R as NA when drawing the plot. These large values are printed as transparent when drawing.
The plot using even intervals:
I tried to give large intervals to the plot, like breaks = c(seq(0, 1500, 100), 40000), but the legend of the plot looks ugly.
In a word, I want a plot with even interval and legend. Something like an open range, not a closed range.
The following plot is my desirable plot realized by other software. How can I resolve my problems using R?
My code is here:
library(rgdal)
library(raster)
library(ncdf4)
library(rasterVis)
library(sp)
ncname <- "output.nc"
ncdata <- nc_open(ncname)
bb <- raster(ncname)
hist(bb)
hist(bb, xlim = c(0, 2000), breaks = seq(0, 40000, 500))
plot(bb)
plot(bb, xlim = c(25, 53), asp = 1.5, breaks = c(seq(0, 1500, 100), 40000), col = topo.colors(20))
plot(bb, legend.only = FALSE, zlim = c(0, 2000), col = topo.colors(20), asp = 1.5,
legend.width = 1, legend.shrink = 1.0,
axis.args = list(at = seq(0, 2000, 100),
labels = seq(0, 2000, 100)))
Related
I made a Temperature-Salinity plot and need to scale the size of the points to a different variable. A temperature-salinity plot is a plot that takes the temperature and salinity and finds the density and plots it based on three values. In the example picture, the curved lines represent density.
Here is what a row of my data looks like:
Temperature
Salinity
pCO2
23.253
36.929
352.7
Heres my code of my plot (this code basically makes an empty graph and you have to manually make each point an object and apply it to the graph):
#FORMING GRAPH FRAME:
library(shape)
library(marelac)
library(plot3D)
S.seq <- seq(from = 20, to = 40, length.out = 100)
t.seq <- seq(from = 20, to = 40, length.out = 100)
sig.mat <- outer(S.seq, t.seq, FUN = function(S, t) sw_dens(S = S, t = t) - 1000)
#GRAPH FRAME:
contour2D(x = S.seq, y = t.seq, z = sig.mat, lwd = 3,
xlab = 'Salinity', ylab = 'Temperature (°C)',main = 'Surface T-S')
Here is an example of making the objects for the graph:
t2s = 23.253
S2s = 36.929
And then apply those objects to the graph:
scatter2D(S2s, t2s, pch=20, col ='darkgreen', cex= 1, add= TRUE,
clim = range(sig.mat), colkey = FALSE)
Here is an example of a final product with all the points on it:
plot
But I need the points to be scaled to the pCO2 value.
Or if you know an easier way to do this type of plot, any feedback is helpful.
I am trying to plot a chunk size in relation to run time with the different chunk sizes on the x-axis being 1000, 10000, 100000, and 1000000. However, when I create the plot using the plot() and axis commands.
plot(chunk, totTime, main="Runtime with Different Chunks", xaxt = "n",ylim = c(4,5),ylab="Runtime (sec)", xlab = "Size of Chunk", type="l")
axis(side = 1, c(1000,10000,100000,1000000))
I get a plot that looks like this.
I've tried axp in plot() and at in the axis function but it still has the same spacing. So, I wonder if there was a way to change how the graph spaces the data in the plot so the graph will look cleaner.
Try converting to the log scale but labeling your x-axis according to the set values you want (here, xvalues). This will put equal spacing between orders of magnitude:
# Sample data
totTime <- c(4.4, 4.01, 4.01, 4.8)
chunk <- c(1000, 10000, 100000, 1000000)
# Values desired on the x-asis
xvalues <- c(1000, 10000, 100000, 1000000)
# Plot
plot(
log(chunk), # note the log scale
totTime,
main = "Runtime with Different Chunks",
xaxt = "n",
ylim = c(4, 5),
ylab = "Runtime (sec)",
xlab = "Size of Chunk",
type = "l"
)
axis(side = 1,
at = log(xvalues), # note the log scale
label = xvalues)
Output:
For the following boxplot:
How can I modify the y-axis and remove the range 0.1 to 0.8? The reason I want to do so is that I want to make each boxplot clear (that start from the range of 0.81 - 1).
For this boxplot, I wrote the following R script:
dataset <- read.csv("/boxplot.csv")
x <- boxplot(dataset)
This is generally discouraged and considered bad practice, as it leads to misleading visualizations. But you can do this using gap.boxplot() from the package plotrix.
Here is an arbitrary example:
library(plotrix)
test_data <- c(rnorm(100, 1000, 20), 10, 20)
par(mfrow = c(1, 2))
boxplot(test_data, main = "boxplot")
gap.boxplot(test_data, gap = list(bottom = c(50, 900), top = c(NA, NA)),
main = "gap.boxplot")
I am trying to plot rose diagrams/ circular histograms on specific coordinates on a map analogous to drawing pie charts on a map as in the package mapplots.
Below is an example generated with mapplots (see below for code), I'd like to replace the pie charts with rose diagrams
The package circular lets me plot the rose diagrams, but I am unable to integrate it with the mapplots package. Any suggestions for alternative packages or code to achieve this?
In response to the question for the code to make the map. It's all based on the mapplots package. I downloaded a shapefile for the map (I think from http://www.freegisdata.org/)
library(mapplots)
library(shapefiles)
xlim = c(-180, 180)
ylim = c(-90, 90)
#load shapefile
wmap = read.shapefile ("xxx")
# define x,y,z for pies
x <- c(-100, 100)
y <- c(50, -50)
z1 <- c(0.25, 0.25, 0.5)
z2 <- c(0.5, 0.2, 0.3)
z <- rbind(z1,z2)
# define radii of the pies
r <- c(5, 10)
# it's easier to have all data in a single df
plot(NA, xlim = xlim, ylim = ylim, cex = 0.75, xlab = NA, ylab = NA)
draw.shape(wmap, col = "grey", border = "NA")
draw.pie(x,y,z,radius = r, col=c("blue", "yellow", "red"))
legend.pie (x = -160, y = -70, labels = c("0", "1", "2"), radius = 5,
bty = "n", cex = 0.5, label.dist=1.5, col = c("blue", "yellow", "red"))
the legend for the pie size can then be added using legend.bubble
Have a look at this example, you can use the map as background an plot your rose diagrams withPlotrix or ggplot2. In either case you would want to overlay multiple of these diagrams on top of your map which is easy to do in ggplot, just have a look at the example.
I discovered subplot() in the package Hmisc, which seems to do exactly what I wanted. Below is my solution (without the map in the background, which can be plotted using mapplots). I am open to suggestions on how to improve this though...
library(Hmisc)
library (circular)
dat <- data.frame(replicate(2,sample(0:360,10,rep=TRUE)))
lat <- c(50, -40)
lon <- c(-100, 20)
# convert to class circular
cir.dat <- as.circular (dat, type ='angles', units = 'degrees', template = 'geographic', modulo = 'asis', zero = 'pi/2', rotation = 'clock')
# function for subplot, plots relative frequencies, see rose.diag for how to adjust the plot
sub.rose <- function(x){
nu <- sum(!is.na(x))
de <- max(hist(x, breaks = (seq(0, 360, 30)), plot = FALSE)$counts)
prop <- nu/de
rose.diag(x, bins = 12, ticks = FALSE, axes = FALSE,
radii.scale = 'linear',
border = NA,
prop = prop,
col = 'black'
)
}
plot(NA, xlim = xlim, ylim = ylim)
for(i in 1:length(lat)){
subplot(sub.rose(cir.dat[,i]), x = lon[i], y = lat[i], size = c(1, 1))
}
The data for some of these types graphs that I'm graphing in R,
http://graphpad.com/faq/images/1352-1(1).gif
has outliers that are way out of range and I can't just exclude them. I attempted to use the axis.break() function from plotrix but the function doesn't rescale the y axis. It just places a break mark on the axis. The purpose of doing this is to be able to show the medians for both groups, as well as the data points, and the outliers all in one plot frame. Essentially, the data points that are far apart from the majority is taking up a chunk of space and the majority of points are being squished, not displaying much differences. Here is the code:
https://gist.github.com/9bfb05dcecac3ecb7491
Any suggestions would be helpful.
Thanks
Unfortunately the code you link to isn't self-contained, but possibly the code you have for gap.plot() there doesn't work as you expect because you are setting ylim to cover the full data range rather than the plotted sections only. Consider the following plot:
As you can see, the y axis has tickmarks for every 50 pg/ml, but there is a gap between 175 and 425. So the data range (to the nearest 50) is c(0, 500) but the range of the y axis is c(0, 250) - it's just that the tickmarks for 200 and 250 are being treated as those for 450 and 500.
This plot was produced using the following modified version of your code:
## made up data
GRO.Controls <- c(25, 40:50, 60, 150)
GRO.Breast <- c(70, 80:90, 110, 500)
##Scatter plot for both groups
library(plotrix)
gap.plot(jitter(rep(0,length(GRO.Controls)),amount = 0.2), GRO.Controls,
gap = c(175,425), xtics = -2, # no xtics visible
ytics = seq(0, 500, by = 50),
xlim = c(-0.5, 1.5), ylim = c(0, 250),
xlab = "", ylab = "Concentrations (pg/ml)", main = "GRO(P=0.0010)")
gap.plot(jitter(rep(1,length(GRO.Breast)),amount = 0.2), GRO.Breast,
gap = c(175, 425), col = "blue", add = TRUE)
##Adds x- variable (groups) labels
mtext("Controls", side = 1, at= 0.0)
mtext("Breast Cancer", side = 1, at= 1.0)
##Adds median lines for each group
segments(-0.25, median(GRO.Controls), 0.25, median(GRO.Controls), lwd = 2.0)
segments(0.75, median(GRO.Breast), 1.25, median(GRO.Breast), lwd = 2.0,
col = "blue")
You could be using gap.plot() which is easily found by following the link on the axis.break help page. There is a worked example there.