Represent a colored polygon in ggplot2 - plot

I am using the statspat package because I am working on spatial patterns.
I would like to do in ggplot and with colors instead of numbers (because it is not too readable),
the following graph, produced with the plot.quadratest function: Polygone
The numbers that interest me for the intensity of the colors are those at the bottom of each box.
The test object contains the following data:
Test object
I have looked at the help of the function, as well as the code of the function but I still cannot manage it.
Ideally I would like my final figure to look like this (maybe not with the same colors haha):
Final object
Thanks in advance for your help.

Please provide a reproducible example in the future.
The package reprex may be very helpful.
To use ggplot2 for this my best bet would be to convert
spatstat objects to sf and do the plotting that way,
but it may take some time. If you are willing to use base
graphics and spatstat you could do something like:
library(spatstat)
# Data (using a built-in dataset):
X <- unmark(chorley)
plot(X, main = "")
# Test:
test <- quadrat.test(X, nx = 4)
# Default plot:
plot(test, main = "")
# Extract the the `quadratcount` object (regions with observed counts):
counts <- attr(test, "quadratcount")
# Convert to `tess` (raw regions with no numbers)
regions <- as.tess(counts)
# Add residuals as marks to the tessellation:
marks(regions) <- test$residuals
# Plot regions with marks as colors:
plot(regions, do.col = TRUE, main = "")

Related

Set common y axis limits from a list of ggplots

I am running a function that returns a custom ggplot from an input data (it is in fact a plot with several layers on it). I run the function over several different input data and obtain a list of ggplots.
I want to create a grid with these plots to compare them but they all have different y axes.
I guess what I have to do is extract the maximum and minimum y axes limits from the ggplot list and apply those to each plot in the list.
How can I do that? I guess its through the use of ggbuild. Something like this:
test = ggplot_build(plot_list[[1]])
> test$layout$panel_scales_x
[[1]]
<ScaleContinuousPosition>
Range:
Limits: 0 -- 1
I am not familiar with the structure of a ggplot_build and maybe this one in particular is not a standard one as it comes from a "custom" ggplot.
For reference, these plots are created whit the gseaplot2 function from the enrichplot package.
I dont know how to "upload" an R object but if that would help, let me know how to do it.
Thanks!
edit after comments (thanks for your suggestions!)
Here is an example of the a gseaplot2 plot. GSEA stands for Gene Set Enrichment Analysis, it is a technique used in genomic studies. The gseaplot2 function calculates a running average and then plots it and another bar plot on the bottom.
and here is the grid I create to compare the plots generated from different data:
I would like to have a common scale for the "Running Enrichment Score" part.
I guess I could try to recreate the gseaplot2 function and input all of the datasets and then create the grid by facet_wrap, but I was wondering if there was an easy way of extracting parameters from a plot list.
As a reproducible example (from the enrichplot package):
library(clusterProfiler)
data(geneList, package="DOSE")
gene <- names(geneList)[abs(geneList) > 2]
wpgmtfile <- system.file("extdata/wikipathways-20180810-gmt-Homo_sapiens.gmt", package="clusterProfiler")
wp2gene <- read.gmt(wpgmtfile)
wp2gene <- wp2gene %>% tidyr::separate(term, c("name","version","wpid","org"), "%")
wpid2gene <- wp2gene %>% dplyr::select(wpid, gene) #TERM2GENE
wpid2name <- wp2gene %>% dplyr::select(wpid, name) #TERM2NAME
ewp2 <- GSEA(geneList, TERM2GENE = wpid2gene, TERM2NAME = wpid2name, verbose=FALSE)
gseaplot2(ewp2, geneSetID=1, subplots=1:2)
And this is how I generate the plot list (probably there is a much more elegant way):
plot_list = list()
for(i in 1:3) {
fig_i = gseaplot2(ewp2,
geneSetID=i,
subplots=1:2)
plot_list[[i]] = fig_i
}
ggarrange(plotlist=plot_list)

Issue: ggplot2 replicates last plot of a list in grid

I have some 16 plots. I want to plot all of these in grid manner with ggplot2. But, whenever I plot, I get a grid with all the plots same, i.e, last plot saved in a list gets plotted at all the 16 places of grid. To replicate the same issue, here I am providing a simple example with two files. Although data are entirely different, but plots drawn are similar.
library(ggplot2)
library(grid)
library(gridExtra)
library(scales)
set.seed(1006)
date1<- as.POSIXct(seq(from=1443709107,by=3600,to=1446214707),origin="1970-01-01")
power <- rnorm(length(date1),100,5)#with normal distribution
write.csv(data.frame(date1,power),"file1.csv",row.names = FALSE,quote = FALSE)
# Now another dataset with uniform distribution
write.csv(data.frame(date1,power=runif(length(date1))),"file2.csv",row.names = FALSE,quote = FALSE)
path=getwd()
files=list.files(path,pattern="*.csv")
plist<-list()# for saving intermediate ggplots
for(i in 1:length(files))
{
dframe<-read.csv(paste(path,"/",files[i],sep = ""),head=TRUE,sep=",")
dframe$date1= as.POSIXct(dframe$date1)
plist[[i]]<- ggplot(dframe)+aes(dframe$date1,dframe$power)+geom_line()
}
grid.arrange(plist[[1]],plist[[2]],ncol = 1,nrow=2)
You need to remove the dframe from your call to aes. You should do that anyway because you have provided a data-argument. In this case it's even more important because while you save the ggplot-object, things don't get evaluated until the call to plot/grid.arrange. When you do that, it looks at the current value of dframe, which is the last dataset in your iteration.
You need to plot with:
ggplot(dframe)+aes(date1,power)+geom_line()

Using a raster attribute from a multi-attribute raster for colour levels in a plot in R

I have a raster object with a large number of attributes, and I would like to plot the spatial data in R and colour code it by a certain attribute. I have not been able to work out how to use the information of a particular attribute to achieve this. So far I have successfully extracted the attribute of choice using factorValues(), but I cannot determine how to now incorporate this information into the plot() function. I tried using the ratify() and level() functions mentioned in the raster package documentation, but I don’t understand how the simplified online examples can be adapted for a raster with multiple attributes.
Any advice on how to achieve this would be greatly appreciated.
# read in shapefile
shp = readOGR(".", "grid")
#convert to raster
r = raster(extent(shp))
res(r) = c(1,0.5)
ra = rasterize(shp, r)
#crop raster to desired extent
rcrop = crop(ra, extent(-12, 2, 29, 51))
# extract attribute value of interest
f = factorValues(rcrop, 1:420, layer=1, att=17, append.names=FALSE)
# here there are 420 cells in the raster and I am interested in plotting values of attribute 17 of the raster (this is currently a numeric attribute, not a factor)
#extra code to set attribute as the level to use for plotting colours???
rcrop = ratify(rcrop)
rat = levels(rcrop)[[1]] #this just extras row IDs..not what I want
#…
### plot: I want to plot the grid using 7 colours (I would ideally like to specify the breaks myself)
require(RColorBrewer)
cols = brewer.pal(7,"YlGnBu")
#set breaks
brks = seq(min(minValue(rcrop)),max(maxValue(rcrop),7))
#plot
plot(rcrop, breaks=brks, col=cols, axis.arg=arg)
The following is pretty hacky (and may perform poorly for large rasters), but I'm not sure if there's a way to link col.regions to a specified attribute.
rasterVis::levelplot does a nice job of labelling colour ramps corresponding to factor rasters, and while it provides an att argument allowing you to specify which attribute you're interested in, this seems to only modify the labelling of the ramp. Raster cell values control how the colour ramp is mapped to the raster, so it seems to me that we need to modify the cell values themselves. Maybe #OscarPerpiñán will chime in here to prove me wrong :)
We can create a simple function to substitute the original cell values with whichever attribute we want:
switch_att <- function(r, att) {
r[] <- levels(r)[[1]][values(r), att]
r
}
Let's download and import a small example polygon dataset from Natural Earth:
library(rasterVis)
library(rgdal)
require(RColorBrewer)
download.file(file.path('http://www.naturalearthdata.com',
'http//www.naturalearthdata.com/download/110m/cultural',
'ne_110m_admin_0_countries.zip'),
f <- tempfile())
unzip(f, exdir=tempdir())
shp <- readOGR(tempdir(), 'ne_110m_admin_0_countries')
rasterize the vector data:
r <- rasterize(shp, raster(raster(extent(shp), res=c(1, 1))))
And create some plots with levelplot:
levelplot(switch_att(r, 'continent'), col.regions=brewer.pal(8, 'Set2')) +
layer(sp.polygons(shp, lwd=0.5))
levelplot(switch_att(r, 'economy'), par.settings=BuRdTheme) +
layer(sp.polygons(shp, lwd=0.5))
EDIT
With Oscar's update to rasterVis, the switch_att hack above is no longer necessary.
devtools::install_github('oscarperpinan/rastervis')
levelplot(r, att='continent', col.regions=brewer.pal(8, 'Set2')) +
layer(sp.polygons(shp, lwd=0.5))
will produce the same figure as the first one above.

rCharts Polychart: Adding horizontal or vertical lines to a plot

I'm having some trouble understanding how to customize graphs using the rPlot function in the rCharts Package. Say I have the following code
#Install rCharts if you do not already have it
#This will require devtools, which can be downloaded from CRAN
require(devtools)
install_github('rCharts', 'ramnathv')
#simulate some random normal data
x <- rnorm(100, 50, 5)
y <- rnorm(100, 30, 2)
#store in a data frame for easy retrieval
demoData <- data.frame(x,y)
#generate the rPlot Object
demoChart <- rPlot(y~x, data = demoData, type = 'point')
#return the object // view the plot
demoChart
This will generate a plot and that is nice, but how would I go about adding horizontal lines along the y-axis? For example, if I wanted to plot a green line which represented the average y-value, and then red lines which represented +/- 3 standard deviations from the average? If anybody knows of some documentation and could point me to it then that would be great. However, the only documentation I could find was on the polychart.js (https://github.com/Polychart/polychart2) and I'm not quite sure how to apply this to the rCharts rPlot function in R.
I have done some digging and I feel like the answer is going to have something to do with adding/modifying the layers parameter within the rPlot object.
#look at the slots in this object
demoChart$params$layers
#doing this will return the following output (which will be different for
#everybody because I didn't set a seed). Also, I removed rows 6:100 of the data.
demoChart$params$layers
[[1]]
[[1]]$x
[1] "x"
[[1]]$y
[1] "y"
[[1]]$data
x y
1 49.66518 32.75435
2 42.59585 30.54304
3 53.40338 31.71185
4 58.01907 28.98096
5 55.67123 29.15870
[[1]]$facet
NULL
[[1]]$type
[1] "point"
If I figure this out I will post a solution, but I would appreciate any help/advice in the meantime! I don't have much experience playing with objects in R. I feel like this is supposed to have some similarity to ggplot2 which I also don't have much experience with.
Thanks for any advice!
You can overlay additional graphs onto your rCharts plot using layers. Add values for any additional layers as columns on to your original data.frame. copy_layer lets you use the values from the data.frame in the extra layers.
# Regression Plots using rCharts
require(rCharts)
mtcars$avg <- mean(mtcars$mpg)
mtcars$sdplus <- mtcars$avg + sd(mtcars$mpg)
mtcars$sdneg <- mtcars$avg - sd(mtcars$mpg)
p1 <- rPlot(mpg~wt, data=mtcars, type='point')
p1$layer(y='avg', copy_layer=T, type='line', color=list(const='red'))
p1$layer(y='sdplus', copy_layer=T, type='line', color=list(const='green'))
p1$layer(y='sdneg', copy_layer=T, type='line', color=list(const='green'))
p1
Here are a couple of examples: one from the main rCharts website and the other showing how to overlay a regression line.

Clearing plotted points in R

I am trying to use the animation package to generate an "evolving" plot of points on a map. The map is generated from shapefiles (from the readShapeSpatial/readShapeLines functions).
The problem is when it's plotted in a for loop, the result is additive, whereas the ideal result is to have it evolve.
Are there ways of using par() that I am missing?
My question is: is there a way to clear just the points ploted from the points function
and not clearing the entire figure thus not having to regraph the shapefiles?
in case someone wants to see code:
# plotting underlying map
newyork <- readShapeSpatial('nycpolygon.shp')
routes <- readShapeLines('nyc.shp')
par(bg="grey25")
plot(newyork, lwd=2, col ="lightgray")
plot(routes,add=TRUE,lwd=0.1,col="lightslategrey")
# plotting points and save to GIF
ani.options(interval=.05)
saveGIF({
par(bg="grey25")
# Begin loop
for (i in 13:44){
infile <-paste("Week",i,".csv",sep='')
mydata <-read.csv(file = infile, header = TRUE, sep=",")
plotvar <- Var$Para
nclr <- 4
plotclr <-brewer.pal(nclr,"RdPu")
class<- classIntervals(plotvar,nclr,style = "pretty")
colcode <- findColours(class,plotclr)
points(Var$Lon,Var$Lat,col=colcode)
}
})
If you can accept a residual shadow or halo of ink, you can over-plot with color ="white" or == to your background choices. We cannot access your shape file but you can try it out by adding this line:
points(Var$Lon, Var$Lat, col="grey25")
It may leave gaps in other previously plotted figures or boundaries, because it's definitely not object-oriented. The lattice and ggplot2 graphics models are more object oriented, so if you want to post a reproducible example, that might be an alternate path to "moving" forward. I seem to remember that the rgl package has animation options in its repetoire.

Resources