I have following type of data (although number of data points is very large)
# property data
name <- c("A", "B", "C", "D")
diameter <- c(4.3, 8.3,1.2, 3.3)
X <- c( 1, 2, 3, 4)
Y <- c(1, 3, 3, 4)
colr <- c(10, 20, 34, 12)
propdata <- data.frame (name, diameter, X, Y, colr)
# interaction data
name1 <- c("A", "A", "A", "B", "B")
name2 <- c("B", "C", "D", "C", "D")
score <- c(1.1, 2.2, 5.4, 3.1, 2.0)
relation <- data.frame (name1, name2, score)
I want to create a graph similar to following, such that it has following property.
(
1) diameter of circles is governed by propdata$diameter
(2) Position in xy field is governed by cordinates of propdata$X and propdata$y
(3) Fill color of the circle is controlled by propdata$colr
(4) Interaction is governed by relation data.frame, name1
and name2 elements will be connected and weight of the line is govenmened
by relation$score.
Is it possible to make such graph with existing R base or any popular graphics software or need a more specialized software.
EDITS:
This is as far as I go using bubble plot:
p <- ggplot(propdata, aes(X,Y,size = diameter, label=name))
p <- p + geom_point(colour= "red")+geom_text(size=3) # colour = colr does not work
p
Here is something I cooked up quickly with qgraph
:
library("qgraph")
plot(1,type='n',xlim=c(min(propdata$X)-0.5,
max(propdata$Y)+0.5),ylim=c(min(propdata$Y)-0.5,max(propdata$Y)+0.5),
xlab="",ylab="")
col <- rgb(0,1-propdata$colr/max(propdata$colr),0)
qgraph(relation,plot=FALSE,rescale=FALSE,layout=as.matrix(propdata[c("X","Y")]),
edge.color="darkred",color=col,propdata$colr,directed=FALSE,esize=10,
vsize=propdata$diameter+2,lcolor="white",curve=c(0,0,-0.2,0,0))
So, the problem is creating a line plot that represents the interaction.
To do this, you need to format your data in the appropriate form. You want to plot segments, and for this you need the co-ordinates of each segment in a single row in your data frame:
interaction <- merge(propdata, relation, by.x="name", by.y="name1")
interaction <- cbind(interaction,
merge(propdata, relation, by.x="name", by.y="name2")[, c("X", "Y")])
names(interaction)[8:9] <- c("Xend", "Yend")
interaction
name diameter X Y colr name2 score Xend Yend
1 A 4.3 1 1 10 B 1.1 2 3
2 A 4.3 1 1 10 C 2.2 3 3
3 A 4.3 1 1 10 D 5.4 3 3
4 B 8.3 2 3 20 C 3.1 4 4
5 B 8.3 2 3 20 D 2.0 4 4
Now we run into another problem. In ggplot2
, you can only have a single size scale. Since you have a size argument for both the point and line, that really represents two things, this can't be done without a workaround.
Thus the workaround is to manually draw the circles using geom_polygon
.
Construct the data frame with circles:
circle <- function(x, y, d, color, scale=1){
d <- d * scale
angle <- seq(-pi, pi, length = 50)
data.frame(
x = x + d/2*sin(angle),
y = y + d/2*cos(angle),
color=color)
}
circles <- ddply(propdata, .(name),
function(x)with(x, circle(X, Y, diameter, colr, scale=0.2)))
Finally, create the plot:
ggplot() +
geom_polygon(data=circles, aes(group=name, x=x, y=y, fill=color)) +
geom_text(data=propdata, aes(x=X, y=Y, label=name), hjust=0, vjust=0) +
geom_segment(data=interaction, aes(x=X, y=Y, xend=Xend, yend=Yend, size=score)) +
scale_size("Inter", to=c(0, 5)) +
coord_equal()
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With