Plotting density points on a map in R - r

I've been trying to plot the number of tourists from different regions in Canada on a map in R using ggplot2 and openstreet map, but I seem to be missing a step as my points all end up in the bottom right corner of the map and my map shrinks in size.
Here are some of the data I used in the dataset map.tourists.
id Nb.Touristes Nb.Nuitees
1001 939.9513 1879.903
1004 1273.4336 2546.867
1006 776.5203 3882.602
1010 3118.4872 18598.194
1102 921.7354 3971.677
1103 622.8770 1245.754
And here is the code I have until now. The data with the coordinates is in the Statistic Canada file that I download in the code below.
download.file("http://www12.statcan.gc.ca/census-recensement/2011/geo/bound-limit/files-fichiers/gcd_000b11a_e.zip", destfile="gcd_000b11a_e.zip")
unzip("gcd_000b11a_e.zip")
library(maptools)
canada<-readShapeSpatial("gcd_000b11a_e")
library(GISTools)
CDCenters <- coordinates(canada)
CDCenters <- SpatialPointsDataFrame(coords=canada, data=canada#data,
proj4string=CRS("+proj=longlat +ellps=clrk66"))
CDCenters=data.frame(CDCenters, row.names=NULL , id=CDCenters$CDUID)
canada_map <- merge(CDCenters, map.tourists, by="id")
list <- ls()
list <- list[-grep("canada_map", list)]
rm(list=list)
rm(list)
Sys.setenv(NOAWT=1)
library(OpenStreetMap)
library(rgdal)
library(stringr)
library(ggplot2)
mp <- openmap(c(71, -143), c(40, -50), zoom=4, type="osm",mergeTiles=TRUE)
library(ggplot2)
autoplot(mp) +
geom_point(data=canada_map, alpha = I(8/10), aes(x=coords.x1,y=coords.x2, size=Nb.Touristes, color=Nb.Touristes)) +
theme(axis.line=element_blank(), axis.text.x=element_blank(), axis.text.y=element_blank(), axis.ticks=element_blank(), axis.title.x=element_blank(), axis.title.y=element_blank()) +
scale_size_continuous(range= c(1, 25)) +
scale_colour_gradient(low="blue", high="red") +
labs(title="Nombre de touristes à Montréal en 2010 selon la division de recensement d’origine")
I'd post the image that I get, but I don't have enough reputation yet !
I get two legends, the map is concentrated in the top left corner and all the points seem to be in the bottom right corner...
What can I do?
Thank you!!

I went through your code and did my best to see what is happening here. In short, I would recommend you to use the ggmap package. I am not an expert in GIS, but it seems to me that the map you got (i.e., mp) is not something ggplot likes.
library(maptools)
library(GISTools)
library(ggmap)
library(ggplot2)
### Following the OP here
download.file("http://www12.statcan.gc.ca/census-recensement/2011/geo/bound-limit/files-fichiers/gcd_000b11a_e.zip", destfile="gcd_000b11a_e.zip")
unzip("gcd_000b11a_e.zip")
canada<-readShapeSpatial("gcd_000b11a_e")
CDCenters <- coordinates(canada)
CDCenters <- SpatialPointsDataFrame(coords=canada, data=canada#data,
proj4string=CRS("+proj=longlat +ellps=clrk66"))
CDCenters <- data.frame(CDCenters, row.names=NULL , id=CDCenters$CDUID)
### Tourist data
dat <- structure(list(id = c(1001L, 1004L, 1006L, 1010L, 1102L, 1103L
), Nb.Touristes = c(939.9513, 1273.4336, 776.5203, 3118.4872,
921.7354, 622.877), Nb.Nuitees = c(1879.903, 2546.867, 3882.602,
18598.194, 3971.677, 1245.754)), .Names = c("id", "Nb.Touristes",
"Nb.Nuitees"), class = "data.frame", row.names = c(NA, -6L))
### Merge the map data and tourist data
canada_map <- merge(CDCenters, dat, by="id")
### OK, now I want to get maps in two different ways.
### This is by the OP
mp <- openmap(c(71, -143), c(40, -50), zoom=4, type="osm",mergeTiles=TRUE)
#str(mp)
#List of 2
# $ tiles:List of 1
# ..$ :List of 5
# .. ..$ colorData : chr [1:701964] "#B5D0D0" "#B5D0D0" "#B5D0D0" "#B5D0D0" ...
# .. ..$ bbox :List of 2
# .. .. ..$ p1: num [1:2] -15918687 11402272
# .. .. ..$ p2: num [1:2] -5565975 4865942
# .. ..$ projection:Formal class 'CRS' [package "sp"] with 1 slots
# .. .. .. ..# projargs: chr "+proj=merc +a=6378137 +b=6378137 +lat_ts=0.0 +lon_0=0.0 +x_0=0.0 +y_0=0 +k=1.0 +units=m +nadgrids=#null +no_defs"
# .. ..$ xres : int 666
# .. ..$ yres : int 1054
# .. ..- attr(*, "class")= chr "osmtile"
# $ bbox :List of 2
# ..$ p1: num [1:2] -15918687 11402272
# ..$ p2: num [1:2] -5565975 4865942
# - attr(*, "zoom")= int 4
# - attr(*, "class")= chr "OpenStreetMap"
Here I do not see lon and lat like 40,50, and 60. This somehow makes me think that ggplot may not like the values.
Here is another map using ggmap When I printed out the image, lon and lat are in numbers I expected.
### Get openstreetmap using ggmap
ca.map2 <- get_openstreetmap(bbox= c(left = -143, bottom = 40, right = -50, top = 71),
scale = 69885283, format = "png")
#str(ca.map2)
#chr [1:334, 1:529] "#B5D0D0" "#B5D0D0" "#B5D0D0" "#B5D0D0" "#B5D0D0" "#B5D0D0" "#B5D0D0" ...
#- attr(*, "class")= chr [1:2] "ggmap" "raster"
#- attr(*, "bb")='data.frame': 1 obs. of 4 variables:
#..$ ll.lat: num 40
#..$ ll.lon: num -143
#..$ ur.lat: num 71
#..$ ur.lon: num -50
So, I am guessing that coords.x1 and coords.x2 in canada_map are probably not matching with the numbers in the object, mp. At least, there is something screwy happening due to the difference in lon and lat values between mp and canada_map. In order to make lon and lat values consistent in your data (canada_map) and a map, I used the ggmap object (ca.map2) and drew a graphic. If you want to have colour and size in one legend this is the way you do it. In summary, you may want to stick to ggmap and ggplot in order to avoid similar problems in the future.
ggmap(ca.map2) +
geom_point(data = canada_map,
aes(x=coords.x1,y=coords.x2, size = Nb.Touristes, color = Nb.Touristes)) +
guides(colour = guide_legend())

Related

Colouring brain surface with heat map

library(rgl)
library(brainR)
template <- readNIfTI(system.file("MNI152_T1_2mm_brain.nii.gz",
package = "brainR"), reorient = FALSE)
misc3d::contour3d(template, level = 4500, alpha = .7, draw = T)
With the above code one can can generate a 3D model of the brain.
The argument draw = FALSE asks contour3d to compute and return the contour surface as a triangle mesh object without drawing it.
a <- misc3d::contour3d(template, level = 4500, alpha = .7, draw = F)
str(a)
List of 10
$ v1 : num [1:110433, 1:3] 45 45 46 46 47 47 43 43 44 44 ...
$ v2 : num [1:110433, 1:3] 44.1 46 46 47 47 ...
$ v3 : num [1:110433, 1:3] 45 45 45 46 46 ...
$ color : chr "white"
$ color2 : logi NA
$ fill : logi TRUE
$ material: chr "default"
$ col.mesh: logi NA
$ alpha : num 0.7
$ smooth : num 0
- attr(*, "class")= chr "Triangles3D"
I would like to use the external surface of the above object to project heat maps, or say, colouring the surface... I also wonder how to determine certain positions in this model, e.g. EEG channel positions. Is it possible to generate only the surface with a$v1, a$v2 ... using function rgl:::surface3d? Thank you in advance,
I was able to draw the triangle mesh in colors with rgl. Some considerations:
I'm using rgl::triangles3d With this function, points are taken in consecutive triplets, each point v1 v2 v3 a triangle vertex (see
?triangles3d) so i had to extract the points and reorder them.
colors are mapped to vertex, taken in groups of three also. I created a simple color_map based on the x position of each vertex. Of course you must create your desired color map.
Hope this will help you.
data<-misc3d::contour3d(template, level = 4500, alpha = .7, draw = F)
points <- rbind(data$v1, data$v2, data$v3)
points <- points[order(rep(1:(nrow(points)/3),3), rep(1:3, nrow(points)/3)),]
color_map <- c("red","blue","green")[cut(points[,1], 3, labels=F)]
rgl::open3d()
rgl::triangles3d(points, alpha=.7, color = color_map)
Edit
Coordinates x, y, z are in the scale of the positions of the array template i.e. point c(5.4, 10.8, 30.1) is related to the level of the array around [5, 10, 30], that is, that point should be around level=4500

Create a frequency table and stacked bar chart for airport station codes

My objective is to take a subset of a data log that recorded airport station codes over time.
I am trying to plot a frequency table based on the number of times a station code is entered, then I would like to build a stacked bar chart, using the 'fill' function. Additionally, I am trying to divide these bases into 4 even groups.
The subset of the data looks like this:
OPSLOG2016$Base <- c("yyc", "yyc", "ylw", "yvr", "lax", "hnl", "yvr", "yow", "yyz","yyz", "lga", "yyz", "yyz", "YYZ", "yow", "YYC", "YYZ", NA, "hux","yvr", ... <truncated>
Some frequencies of some bases:
#List of 49
$ bos: num 134
$ cun: num 205
$ fll: num 114
$ hnl: num 95
$ las: num 288
$ lax: num 218
$ lga: num 456
$ lgw: num 169
$ mbj: num 71
$ mco: num 223
$ ogg: num 99
My code up to this point:
corpus = Corpus(VectorSource(OPSLOG2016$Base))
corpus = tm_map(corpus, PlainTextDocument)
basefreq = DocumentTermMatrix(corpus)
sparseBase = removeSparseTerms(basefreq, 0.999)
dfBase = as.data.frame(as.matrix(sparseBase))
qplot(dfBase, y = scale(dfBase,center = TRUE, scale = frequency())
**#Error: ggplot2 doesn't know how to deal with data of class list Error during wrapup: cannot open the connection**
dfVecSum = lapply(dfBase, sum)
plot(dfVecSum)
**#Error in xy.coords(x, y, xlabel, ylabel, log) : 'x' is a list, but does not have components 'x' and 'y Error during wrapup: cannot open the connection**
ggplot(dfVecSum, aes(x = dfVecSum, y = Frequency, fill = fill)) +
geom_bar(position = "fill")
**#Error: ggplot2 doesn't know how to deal with data of class list Error during wrapup: cannot open the connection**
It's likely obvious that I am new to this, and am committing many errors. But I'm hoping to be put in the right direction, as I can't seem to get any of this to work on my own.
It looks like you are starting out with a list. Maybe this can help you in the right direction:
library(ggplot2)
yourlist = list(bos= 134,cun=205,fll= 114,hnl = 95)
df = as.data.frame(do.call(rbind,yourlist))
df$name = rownames(df)
colnames(df)[colnames(df)=="V1"] = "total"
ggplot(df, aes(x = name, y = total))+ geom_bar(stat="identity")

Adding point locations to a 3D DEM plot in R

I have some point locations which include UTMs and Elevation as a data frame
I also have a DEM layer.
I have figured out how to plot the DEM in 3D using plot3D in rgl.
I can also plot the points in 3D using points3d.
I have been able to put them in the same plot using points3d with add=TRUE
however the points and DEM are radically far away from each other.
In the code below I also tried to change this to a spatial data frame but rgl doesn't seem to like that.
Is it possible to plot them together with the points laying over the DEM?
I have searched and searched for a solution to this.
Here is the R code I have used so far:
> library(raster)
> library(rgdal)
> library(maptools)
> library(rgeos)
> library(lattice)
> library(latticeExtra)
> library(sp)
> library(rasterVis)
> library(rgl)
>
> # taking data read from a .csv of UTM and elevation values
>
> Points.Sp <- data.frame(Points=Rawdata$PointName, UTM.N=Rawdata$UTM.N, UTM.W=Rawdata$UTM.W, Elevation=Rawdata$Elevation)
> Points.Sp <- unique(Points.Sp) #weeding out duplicates
> Points.Sp <- Points.Sp[,c(3,2,4)] #getting rid of point names # I realize this looks messy but it gets what I want
> head(Points.Sp)
UTM.W UTM.N Elevation
1 275815 3879223 1340
8 274813 3879727 1325
29 275312 3879727 1258
45 275812 3879724 1169
66 276313 3879727 1067
75 276813 3879727 1208
>
> dem.in <- raster("D:/Thesis/SouthernApps/Coweeta/Coweeta/DEM_30m_wgs84.img") # reading in DEM
> plot(dem.in) # check in 2D # takes a long time very large, need to crop
>
> dem.crop <- crop(dem.in, c(272000, 282000, 3878000, 3884000))
> plot(dem.crop) # check in 2D, looks good.
>
> plot3D(dem.crop) # plot in 3D looks like exactly what I want
>
> points3d(Points.Sp, pch=19, cex=2, col="black", add=TRUE) # adds the points to plot but in wrong place
>
> #attempting to set a CRS in case this is the problem.
> coordinates(Points.Sp)=c(1,2)
> proj4string(Points.Sp)=CRS("++proj=utm +zone=17") # set CRS
> str(Points.Sp)
Formal class 'SpatialPointsDataFrame' [package "sp"] with 5 slots
..# data :'data.frame': 71 obs. of 1 variable:
.. ..$ Elevation: int [1:71] 1340 1325 1258 1169 1067 1208 1256 1089 1031 959 ...
..# coords.nrs : num [1:2] 1 2
..# coords : num [1:71, 1:2] 275815 274813 275312 275812 276313 ...
.. ..- attr(*, "dimnames")=List of 2
.. .. ..$ : chr [1:71] "1" "8" "29" "45" ...
.. .. ..$ : chr [1:2] "UTM.W" "UTM.N"
..# bbox : num [1:2, 1:2] 274309 3878440 279876 3883732
.. ..- attr(*, "dimnames")=List of 2
.. .. ..$ : chr [1:2] "UTM.W" "UTM.N"
.. .. ..$ : chr [1:2] "min" "max"
..# proj4string:Formal class 'CRS' [package "sp"] with 1 slot
.. .. ..# projargs: chr "+proj=utm +zone=17 +ellps=WGS84"
>
> # trying this a different way after setting CRS
> x <- Points.Sp#coords[1:71,1]
> y <- Points.Sp#coords[1:71,2]
> z <- Points.Sp#data$Elevation
> m <- data.frame(x=x,y=y,z=z)
>
> plot3D(dem.crop) #again, plot in 3D looks like exactly what I want
> points3d(m, pch=19, cex=2, col="black", add=TRUE) # still adds the points to plot but in wrong place
This code reproduces the problem.
## define a Raster object
data(volcano)
r <- raster(volcano)
extent(r) <- c(0, 610, 0, 870)
## extract sample points
xy <- sampleRandom(r1, 100, xy = TRUE)
r1<-data.frame(x=seq(0, 500, length=(71)), y=seq(0, 500, length=(71)), z=seq(0,500, length=(71)))
## display them
plot3D(r, adjust = FALSE)
points3d(r1, add=TRUE)
As documented in the help page, both the x-axis and y-axis are adjusted with the z values. You can disable this default setting with adjust = FALSE:
library(rgl)
library(rasterVis)
## define a Raster object
data(volcano)
r <- raster(volcano)
extent(r) <- c(0, 610, 0, 870)
## extract sample points
xy <- sampleRandom(r, 100, xy = TRUE)
## display them
plot3D(r, adjust = FALSE)
points3d(xy)
## define a Raster object
data(volcano)
r <- raster(volcano)
extent(r) <- c(0, 610, 0, 870)
## extract sample points
xy <- sampleRandom(r1, 100, xy = TRUE)
#must extract the data from the raster and recombine with the xy data.
#I don't know why this is different than simply using the raw values but it
#provides the desired effect.
r1<-data.frame(x=seq(0, 500, length=(71)), y=seq(0, 500, length=(71)))
z<-extract(r, r1)
r1$z<-z
## display them
plot3D(r, adjust = FALSE)
points3d(r1, add=TRUE)
#points now lie flat on 3d image.
Points flush to 3d Image
Image for original problem

Why does as.data.frame give error when converting a raster with factors as data and specifying xy=T?

I would like to convert a raster layer into a dataframe and get the coordinates as well.
This works just fine, but doesn't give xy values:
as.data.frame(raster_layer)
as.data.frame(x = naip_svm_cropped)
category
1 forest_broadleafdark
2 forest_broadleafdark
3 forest_broadleafdark
4 grassland
5 grassland
6 grassland
This throws an error:
as.data.frame(raster_layer, xy = T)
The error is:
Error in match(round(v), rat$ID) : error in evaluating the argument
'x' in selecting a method for function 'match': Error in v[, i] :
incorrect number of dimensions
I suspect the problem lies somewhere with the Raster Attribute Table, but am unsure how to proceed. I suppose I could convert the factors to numeric and try going from there (xy=T works for non factor rasters), but I'd like to find out why adding xy=T gives this error. So my question is really "Why does this happen, and how can I get it to work (return xy values with cell values)?"
The raster layer has factors as data (I'm not sure exactly how to call it, here is the str statement):
str(naip_svm_cropped#data)
Formal class '.SingleLayerData' [package "raster"] with 13 slots
..# values : logi(0)
..# offset : num 0
..# gain : num 1
..# inmemory : logi FALSE
..# fromdisk : logi TRUE
..# isfactor : logi TRUE
..# attributes:List of 1
.. ..$ :'data.frame': 5 obs. of 2 variables:
.. .. ..$ ID : num [1:5] 0 1 2 3 4
.. .. ..$ category: Factor w/ 5 levels "forest_broadleafdark",..: 4 1 2 3 5
..# haveminmax: logi TRUE
..# min : num 0
..# max : num 4
..# band : int 1
..# unit : chr ""
..# names : chr "madison_classcombine"
The behavior on a dataframe with a structure like this:
str(mad_veg_cropped#data)
Formal class '.SingleLayerData' [package "raster"] with 13 slots
..# values : logi(0)
..# offset : num 0
..# gain : num 1
..# inmemory : logi FALSE
..# fromdisk : logi TRUE
..# isfactor : logi FALSE
..# attributes: list()
..# haveminmax: logi TRUE
..# min : num -0.719
..# max : num 1.04
..# band : int 1
..# unit : chr ""
..# names : chr "PercentVeg"
head(as.data.frame(mad_veg_cropped, xy = T))
x y PercentVeg
1 291855.5 4775116 0.7182595
2 291856.5 4775116 0.7402779
3 291857.5 4775116 0.7601378
4 291858.5 4775116 0.7702084
5 291859.5 4775116 0.7774438
6 291860.5 4775116 0.7574666
I'd like to be able to get a column of "category", "x", and "y".
sessionInfo()
R version 3.1.2 (2014-10-31)
Platform: x86_64-apple-darwin13.4.0 (64-bit)
other attached packages:
[1] raster_2.3-24 sp_1.0-17
dput(naip_svm_cropped)
new("RasterLayer"
, file = new(".RasterFile"
, name = "/private/var/folders/yj/vjkj1yyx1n510rf_rggqdb640000gr/T/R_raster_tedward/2015-06-04_122215_4840_06850.grd"
, datanotation = "INT2S"
, byteorder = structure("little", .Names = "value")
, nodatavalue = -32768
, NAchanged = FALSE
, nbands = 1L
, bandorder = structure("BIL", .Names = "value")
, offset = 0L
, toptobottom = TRUE
, blockrows = 0L
, blockcols = 0L
, driver = "raster"
, open = FALSE
)
, data = new(".SingleLayerData"
, values = logical(0)
, offset = 0
, gain = 1
, inmemory = FALSE
, fromdisk = TRUE
, isfactor = TRUE
, attributes = list(structure(list(ID = c(0, 1, 2, 3, 4), category = structure(c(4L,
1L, 2L, 3L, 5L), .Label = c("forest_broadleafdark", "grassland",
"shadow1_tree", "Unclassified", "urban_buildings"), class = "factor")), .Names = c("ID",
"category"), row.names = c(NA, -5L), class = "data.frame"))
, haveminmax = TRUE
, min = 0
, max = 4
, band = 1L
, unit = ""
, names = "madison_classcombine"
)
, legend = new(".RasterLegend"
, type = character(0)
, values = logical(0)
, color = logical(0)
, names = logical(0)
, colortable = c("#000000", "#008B00", "#FF0000", "#FFFF00", "#FF00FF")
)
, title = character(0)
, extent = new("Extent"
, xmin = 291855
, xmax = 311023
, ymin = 4768423
, ymax = 4775116
)
, rotated = FALSE
, rotation = new(".Rotation"
, geotrans = numeric(0)
, transfun = function ()
NULL
)
, ncols = 19168L
, nrows = 6693L
, crs = new("CRS"
, projargs = "+proj=utm +zone=16 +datum=NAD83 +units=m +no_defs"
)
, history = list()
, z = list()
)
'raster' expects that the first column of the raster attribute table is an integer variable named 'ID'. How did you get this layer? Perhaps this is a bug that needs to be fixed, or perhaps you made a mistake when you created it.
Either way, here is a work around that should work:
xy <- xyFromCell(raster_layer, 1:ncell(raster_layer))
v <- as.data.frame(raster_layer)
xyv <- data.frame(xy, v)
Here is a self-contained example
library(raster)
r <- raster(nrow=10, ncol=10)
r[] = 1
r[51:100] = 2
r[3:6, 1:5] = 3
r <- ratify(r)
rat <- levels(r)[[1]]
rat$landcover <- c('Pine', 'Oak', 'Meadow')
rat$code <- c(12,25,30)
levels(r) <- rat
xy <- xyFromCell(r, 1:ncell(r))
v <- as.data.frame(r)
xyv <- data.frame(xy, v)
head(xyv)
# x y landcover code
#1 -162 81 Pine 12
#2 -126 81 Pine 12
#3 -90 81 Pine 12
although in this example, you can also do:
vv <- as.data.frame(r, xy=TRUE)

Plot from package "lomb" in ggplot2

I am using the package "lomb" to calculate Lomb-Scargle Periodograms, a method for analysing biological time series data. The package does create a plot if you tell it to do so. However, the plots are not too nice (compared to ggplot2 plots). Therefore, I would like to plot the results with ggplot. However, I do not know how to access the function for the curve plotted...
This is a sample code for a plot:
TempDiff <- runif(4033, 3.0, 18) % just generate random numbers
Time2 <- seq(1,4033) % Time vector
Rand.LombScargle <- randlsp(repeats=10, TempDiff, times = Time2, from = 12, to = 36,
type = c("period"), ofac = 10, alpha = 0.01, plot = T,
trace = T, xlab="period", main = "Lomb-Scargle Periodogram")
I have also tried to find out something about the function looking into the function randlsp itself, but could not really find anything that seemed useful to me there...
getAnywhere(randlsp)
A single object matching ‘randlsp’ was found
It was found in the following places
package:lomb
namespace:lomb
with value
function (repeats = 1000, x, times = NULL, from = NULL, to = NULL,
type = c("frequency", "period"), ofac = 1, alpha = 0.01,
plot = TRUE, trace = TRUE, ...)
{
if (is.ts(x)) {
x = as.vector(x)
}
if (!is.vector(x)) {
times <- x[, 1]
x <- x[, 2]
}
if (plot == TRUE) {
op <- par(mfrow = c(2, 1))
}
realres <- lsp(x, times, from, to, type, ofac, alpha, plot = plot,
...)
realpeak <- realres$peak
pks <- NULL
if (trace == TRUE)
cat("Repeats: ")
for (i in 1:repeats) {
randx <- sample(x, length(x))
randres <- lsp(randx, times, from, to, type, ofac, alpha,
plot = F)
pks <- c(pks, randres$peak)
if (trace == TRUE) {
if (i/10 == floor(i/10))
cat(i, " ")
}
}
if (trace == TRUE)
cat("\n")
prop <- length(which(pks >= realpeak))
p.value <- prop/repeats
if (plot == TRUE) {
mx = max(c(pks, realpeak)) * 1.25
hist(pks, xlab = "Peak Amplitude", xlim = c(0, mx), main = paste("P-value: ",
p.value))
abline(v = realpeak)
par(op)
}
res = realres[-(8:9)]
res = res[-length(res)]
res$random.peaks = pks
res$repeats = repeats
res$p.value = p.value
class(res) = "randlsp"
return(invisible(res))
Any idea will be appreciated!
Best,
Christine
PS: Here an example of the plot with real data.
The key to getting ggplot graphs out of any returned object is to convert the data that you need in to some sort of data.frame. To do this, you can look at what kind of object your returned value is and see what sort of data you can immediately extract into a data.frame
str(Rand.LombScargle) # get the data type and structure of the returned value
List of 12
$ scanned : num [1:2241] 12 12 12 12 12 ...
$ power : num [1:2241] 0.759 0.645 0.498 0.341 0.198 ...
$ data : chr [1:2] "times" "x"
$ n : int 4033
$ type : chr "period"
$ ofac : num 10
$ n.out : int 2241
$ peak : num 7.25
$ peak.at : num [1:2] 24.6908 0.0405
$ random.peaks: num [1:10] 4.99 9.82 7.03 7.41 5.91 ...
$ repeats : num 10
$ p.value : num 0.3
- attr(*, "class")= chr "randlsp"
in the case of randlsp, its a list, which is usually what is returned from statistical functions. Most of this information can also be obtained from ?randlsp too.
It looks as if Rand.LombScargle$scanned and Rand.LombScargle$power contains most of what is needed for the first graph:
There is also a horizontal line on the Periodogram, but it doesn't correspond to anything that was returned by randlsp. Looking at the source code that you provided, it looks as if the Periodogram is actually generated by lsp().
LombScargle <- lsp( TempDiff, times = Time2, from = 12, to = 36,
type = c("period"), ofac = 10, alpha = 0.01, plot = F)
str(LombScargle)
List of 12
$ scanned : num [1:2241] 12 12 12 12 12 ...
$ power : num [1:2241] 0.759 0.645 0.498 0.341 0.198 ...
$ data : chr [1:2] "Time2" "TempDiff"
$ n : int 4033
$ type : chr "period"
$ ofac : num 10
$ n.out : int 2241
$ alpha : num 0.01
$ sig.level: num 10.7
$ peak : num 7.25
$ peak.at : num [1:2] 24.6908 0.0405
$ p.value : num 0.274
- attr(*, "class")= chr "lsp"
I am guessing that, based on this data, the line is indicating the significance level LombScargle$sig.level
Putting this together, we can create our data to pass to ggplot from lsp:
lomb.df <- data.frame(period=LombScargle$scanned, power=LombScargle$power)
# use the data frame to set up the line plot
g <- ggplot(lomb.df, aes(period, power)) + geom_line() +
labs(y="normalised power", title="Lomb-Scargle Periodogram")
# add the sig.level horizontal line
g + geom_hline(yintercept=LombScargle$sig.level, linetype="dashed")
For the histogram, it looks like this is based on the vector Rand.LombScargle$random.peaks from randlsp:
rpeaks.df <- data.frame(peaks=Rand.LombScargle$random.peaks)
ggplot(rpeaks.df, aes(peaks)) +
geom_histogram(binwidth=1, fill="white", colour="black") +
geom_vline(xintercept=Rand.LombScargle$peak, linetype="dashed") +
xlim(c(0,12)) +
labs(title=paste0("P-value: ", Rand.LombScargle$p.value),
x="Peak Amplitude",
y="Frequency")
Play around with these graphs to get them looking to your taste.

Resources