I'm trying to produce voronoi diagrams with R. The plotting of the diagrams itself is working fine, but I have a problem with labelling the different tiles of my plots.
The code I'm using is as follows:
data <- read.csv("data.csv", sep=",")
x <- data$column1
y <- data$column2
voro <- deldir(x,y,rw=c(0,1,0,1))
list <- tile.list(voro)
color <- heat.colors(6)
plot(list,polycol=color,close=TRUE)
plot(voro,number=TRUE,add=TRUE,wlines=c('tess'))
Is it possible to swap the numbers for custom labels before plotting the diagram?
You can use text to add the labels (you already know the coordinates, x and y).
library(deldir)
# Sample data
x <- c(2.3,3.0,7.0,1.0,3.0,8.0)
y <- c(2.3,3.0,2.0,5.0,8.0,9.0)
voro <- deldir(x,y,list(ndx=2,ndy=2),c(0,10,0,10))
# Plot
plot( tile.list(voro), polycol = heat.colors(6), close=TRUE )
plot( voro, add = TRUE, wlines = 'tess' )
text( x, y, labels = LETTERS[1:length(x)], adj = c(0,0) )
Related
I have run a factor analysis on a spatial dataset, and I would like to plot the results on a map so that the color of each individual point (location) is a combination in a RGB/HSV space of the scores at that location of the three factors extracted.
I am using base R to plot the locations, which are in a SpatialPointsDataFrame created with the spdep package:
Libraries
library(sp)
library(classInt)
Sample Dataset
fas <- structure(list(MR1 = c(-0.604222013102789, -0.589631093835467,
-0.612647301042234, 2.23360319770647, -0.866779007222414), MR2 = c(-0.492209397489792,
-0.216810726717787, -0.294487678489753, -0.60466348557844, 0.34752411748663
), MR3 = c(-0.510065798219453, -0.61303212834454, 0.194263734935779,
0.347461766159926, -0.756375966467285), x = c(1457543.717, 1491550.224,
1423185.998, 1508232.145, 1521316.942), y = c(4947666.766, 5001394.895,
4948766.5, 4950547.862, 5003955.997)), row.names = c("Acqui Terme",
"Alagna", "Alba", "Albera Ligure", "Albuzzano"), class = "data.frame")
Create spatial object
fas <- SpatialPointsDataFrame(fas[,4:5], fas,
proj4string = CRS("+init=EPSG:3003"))
Plotting function
map <- function(f) {
pal <- colorRampPalette(c("steelblue","white","tomato2"), bias = 1)
collist <- pal(10)
class <- classIntervals(f, 8, style = "jenks")
color <- findColours(class, collist)
plot(fas, pch=21,cex=.8, col="black",bg=color)
}
#example usage
#map(fas$MR1)
The above code works well for producing a separate plot for each factor. What I would like is a way to produce a composite map of the three factors together.
Many thanks in advance for any suggestion.
I found a solution through this post! With the data shown above, it goes like this:
#choose columns to map to color
colors <-fas#data[,c(1:3)]
#set range from 0 to 1
range_col <- function(x){(x-min(x))/(max(x)-min(x))}
colors_norm <- range_col(colors)
print(colors_norm)
#convert to RGB
colors_rgb <- rgb(colors_norm)
print(colors_rgb)
#plot
plot(fas, main="Color Scatterplot", bg=colors_hex,
col="black",pch=21)
I'm trying to produce a dotchart with a secondary axis on top. However once I plot the second dotchart (with a par(new=T)), I can't figure out how not to display the axis ticks over the previous ones in axis side=1. Here's my code with mock data:
y1_i <- c(2,8,2,14,2)
y2_i <- c(15,17,28,22,30)
y1_f <- c(4,9,11,16,7)
y2_f <- c(13,11,16,11,21)
y=c(y1_i,y2_i,y1_f,y2_f)
x <- c("AAEG","AALO","AGAM","ACHR","AALB")
y1=c(y1_i,y1_f)
y2=c(y2_i,y2_f)
dotchart(y1_i,labels=x,xlab="N50 length",xlim = c(0,max(y1)))
par(new=T)
dotchart(y2_i,labels=x,xlim = c(0,max(y2)))
axis(side=3)
Also, if possible, I would like to add a second data set which would be slightly pushed vertically above the first dataset (to not overlap it), but still corresponding to the same y-axis categories.
Thank you for any suggestion :)
Found it, by using dotchart2 from the Hmisc package
library(Hmisc)
y1_i <- c(2,8,2,14,2)
y2_i <- c(15,17,28,22,30)
y1_f <- c(4,9,11,16,7)
y2_f <- c(13,11,16,11,21)
y=c(y1_i,y2_i,y1_f,y2_f)
x <- c("AAEG","AALO","AGAM","ACHR","AALB")
y1=c(y1_i,y1_f)
y2=c(y2_i,y2_f)
y1_i <- c(2,8,2,14,2)
y2_i <- c(15,17,28,22,30)
y1_f <- c(4,9,11,16,7)
y2_f <- c(13,11,16,11,21)
y=c(y1_i,y2_i,y1_f,y2_f)
x <- c("AAEG","AALO","AGAM","ACHR","AALB")
y1=c(y1_i,y1_f)
y2=c(y2_i,y2_f)
dotchart2(y1_i,labels=x,xlab="N50 length",xlim = c(0,max(y1)))
par(new=T)
dotchart2(y2_i,labels=x,xlim = c(0,max(y2)),xlab="Scaffold number",lines=F,xaxis=F)
axis(side=3,xlab="Scaffold number")
I am trying to create hexbins where the x-axis is a date using the hexbin function in the hexbin package in R. When I feed in my data, it seems to convert the dates into a numeric, which gets displayed on the x-axis. I want it force the x-axis to be a date.
#Create Hex Bins
hbin <- hexbin(xData$Date, xData$YAxis, xbins = 80)
#Plot using rBokeh
figure() %>%
ly_hexbin(hbin)
This gives me:
Here's a brute force approach using the underlying grid plotting package. The axes are ugly; maybe someone with better grid skills than I could pretty them up.
# make some data
x = seq.Date(as.Date("2015-01-01"),as.Date("2015-12-31"),by='days')
y = sample(x)
# make the plot and capture the plot
p <- plot(hexbin(x,y),yaxt='n',xaxt='n')
# calculate the ticks
x_ticks_date <-
x_ticks <- axTicks(1, log = FALSE, usr = as.numeric(range(x)),
axp=c(as.numeric(range(x)) ,5))
class(x_ticks_date) <- 'Date'
y_ticks_date <-
y_ticks <- axTicks(1, log = FALSE, usr = as.numeric(range(y)),
axp=c(as.numeric(range(y)) ,5))
class(y_ticks_date) <- 'Date'
# push the ticks to the view port.
pushViewport(p$plot.vp#hexVp.off)
grid.xaxis(at=x_ticks, label = format(y_ticks_date))
grid.yaxis(at=y_ticks, label = format(y_ticks_date))
Lets consider that I have five 2D-Matrices which describe the magnetic field at different z-Layers. A nice, smoothed version of a 2D-Surface plot can be obtained as follows:
data2_I<-matrix(c(1.0,1.0,0.6,0.6,0.7,0.9,0.9,0.5,0.5,0.5,0.7,0.9,0.9,0.6,0.3,0.4,0.7,0.9,0.9,0.7,0.5,0.5,0.6,0.9,0.9,0.7,0.6,0.6,1.0,1.0), nrow=5)
Z = as.vector(data2_I)
length(Z)
XY=data.frame(x=as.numeric(gl(5,1,30)),y=as.numeric(gl(5,6,30)))
t=Tps(XY,Z)
surface(t)
Now it would be great if I could get a 3D-plot where at different z-Positions these surfaces are plotted. Is there a possibility to do that?
I found an alternative approach: With the package rgl I and the function surface 3D I can stack several 3D-Surface plots within one open3d-window. Lets look at a small example:
library("rgl")
data2_I<-matrix(c(1.0,1.0,0.6,0.6,0.7,0.9,0.9,0.5,0.5,0.5,0.7,0.9,0.9,0.6,0.3,0.4,0.7,0.9,0.9,0.7,0.5,0.5,0.6,0.9,0.9,0.7,0.6,0.6,1.0,1.0), nrow=5)
data0_I<-matrix(c(1.0,1.0,0.6,0.6,0.7,0.9,0.9,0.5,0.5,0.5,0.7,0.9,0.9,0.6,0.3,0.4,0.7,0.9,0.9,0.7,0.5,0.5,0.6,0.9,0.9,0.7,0.6,0.6,1.0,1.0), nrow=5)
data1_I<-2*data0_I
data2_I<-1/data1_I
elv=0
offs=5*elv+1
z0 <- scale*data0_I
z1 <- scale*data1_I
z2 <- scale*data2_I
x <- 1:nrow(z0)
y <- 1:ncol(z0)
palette <- colorRampPalette(c("blue","green","yellow", "red"))
col.table <- palette(256)
open3d(windowRect=c(50,50,800,800))
surface3d(x, y, elv*z0, color = col.table[cut(z0, 256)], back = "lines")
surface3d(x, y, elv*z1+1*offs, color = col.table[cut(z1, 256)], back = "lines")
surface3d(x, y, elv*z2+2*offs, color = col.table[cut(z2, 256)], back = "lines")
axes3d()
aspect3d(1,1,2)
The variables offsand elv are included for cosmetic purposes: offs controls the space between two surface plots and elevation how the z-axes of the surface3d-plots should scale. As I wanted to have a 2D surface plot without any elevation I set it to zero.
Refer to the above plot. I have drawn the equations in excel and then shaded by hand. You can see it is not very neat. You can see there are six zones, each bounded by two or more equations. What is the easiest way to draw inequalities and shade the regions using hatched patterns ?
To build up on #agstudy's answer, here's a quick-and-dirty way to represent inequalities in R:
plot(NA,xlim=c(0,1),ylim=c(0,1), xaxs="i",yaxs="i") # Empty plot
a <- curve(x^2, add = TRUE) # First curve
b <- curve(2*x^2-0.2, add = TRUE) # Second curve
names(a) <- c('xA','yA')
names(b) <- c('xB','yB')
with(as.list(c(b,a)),{
id <- yB<=yA
# b<a area
polygon(x = c(xB[id], rev(xA[id])),
y = c(yB[id], rev(yA[id])),
density=10, angle=0, border=NULL)
# a>b area
polygon(x = c(xB[!id], rev(xA[!id])),
y = c(yB[!id], rev(yA[!id])),
density=10, angle=90, border=NULL)
})
If the area in question is surrounded by more than 2 equations, just add more conditions:
plot(NA,xlim=c(0,1),ylim=c(0,1), xaxs="i",yaxs="i") # Empty plot
a <- curve(x^2, add = TRUE) # First curve
b <- curve(2*x^2-0.2, add = TRUE) # Second curve
d <- curve(0.5*x^2+0.2, add = TRUE) # Third curve
names(a) <- c('xA','yA')
names(b) <- c('xB','yB')
names(d) <- c('xD','yD')
with(as.list(c(a,b,d)),{
# Basically you have three conditions:
# curve a is below curve b, curve b is below curve d and curve d is above curve a
# assign to each curve coordinates the two conditions that concerns it.
idA <- yA<=yD & yA<=yB
idB <- yB>=yA & yB<=yD
idD <- yD<=yB & yD>=yA
polygon(x = c(xB[idB], xD[idD], rev(xA[idA])),
y = c(yB[idB], yD[idD], rev(yA[idA])),
density=10, angle=0, border=NULL)
})
In R, there is only limited support for fill patterns and they can only be
applied to rectangles and polygons.This is and only within the traditional graphics, no ggplot2 or lattice.
It is possible to fill a rectangle or polygon with a set of lines drawn
at a certain angle, with a specific separation between the lines. A density
argument controls the separation between the lines (in terms of lines per inch)
and an angle argument controls the angle of the lines.
here an example from the help:
plot(c(1, 9), 1:2, type = "n")
polygon(1:9, c(2,1,2,1,NA,2,1,2,1),
density = c(10, 20), angle = c(-45, 45))
EDIT
Another option is to use alpha blending to differentiate between regions. Here using #plannapus example and gridBase package to superpose polygons, you can do something like this :
library(gridBase)
vps <- baseViewports()
pushViewport(vps$figure,vps$plot)
with(as.list(c(a,b,d)),{
grid.polygon(x = xA, y = yA,gp =gpar(fill='red',lty=1,alpha=0.2))
grid.polygon(x = xB, y = yB,gp =gpar(fill='green',lty=2,alpha=0.2))
grid.polygon(x = xD, y = yD,gp =gpar(fill='blue',lty=3,alpha=0.2))
}
)
upViewport(2)
There are several submissions on the MATLAB Central File Exchange that will produce hatched plots in various ways for you.
I think a tool that will come handy for you here is gnuplot.
Take a look at the following demos:
feelbetween
statistics
some tricks