I want to plot the clustering coefficient and the average shortest- path as a function of the parameter p of the Watts-Strogatz model as following:
And this is my code:
library(igraph)
library(ggplot2)
library(reshape2)
library(pracma)
p <- #don't know how to generate this?
trans <- -1
path <- -1
for (i in p) {
ws_graph <- watts.strogatz.game(1, 1000, 4, i)
trans <-c(trans, transitivity(ws_graph, type = "undirected", vids = NULL,
weights = NULL))
path <- c(path,average.path.length(ws_graph))
}
#Remove auxiliar values
trans <- trans[-1]
path <- path[-1]
#Normalize them
trans <- trans/trans[1]
path <- path/path[1]
x = data.frame(v1 = p, v2 = path, v3 = trans)
plot(p,trans, ylim = c(0,1), ylab='coeff')
par(new=T)
plot(p,path, ylim = c(0,1), ylab='coeff',pch=15)
How should I proceed to make this x-axis?
Key ggplot2 R functions R functions to set a logarithmic axis: p + scale_x_log10(), p + scale_y_log10() : Plot x and y in log 10 scale, respectively. p + coord_trans(x = “log2”, y = “log2”): Transformed cartesian coordinate system.
scale_x_log10() and scale_x_log10() are shortcuts for the base-10 logarithmic transformation of an axis. The same could be achieved by using, e.g., scale_x_continuous(trans = "log10") . The latter can take a selection of options, namely "reverse" , "log2" , or "sqrt" .
You can generate the values of p
using code like the following:
p <- 10^(seq(-4,0,0.2))
You want your x values to be evenly spaced on a log10 scale. This means you need to take evenly spaced values as the exponent for the base 10, because the log10 scale takes the log10 of your x values, which is the exact opposite operation.
With this, you are already pretty far. You don't need par(new=TRUE)
, you can simply use the function plot
followed by the function points
. The latter does not redraw the whole plot. Use the argument log = 'x'
to tell R you need a logarithmic x axis. This only needs to be set in the plot
function, the points
function and all other low-level plot functions (those who do not replace but add to the plot) respect this setting:
plot(p,trans, ylim = c(0,1), ylab='coeff', log='x')
points(p,path, ylim = c(0,1), ylab='coeff',pch=15)
EDIT: If you want to replicate the log-axis look of the above plot, you have to calculate them yourselves. Search the internet for 'R log10 minor ticks' or similar. Below is a simple function which can calcluate the appropriate position for log axis major and minor ticks
log10Tck <- function(side, type){
lim <- switch(side,
x = par('usr')[1:2],
y = par('usr')[3:4],
stop("side argument must be 'x' or 'y'"))
at <- floor(lim[1]) : ceil(lim[2])
return(switch(type,
minor = outer(1:9, 10^(min(at):max(at))),
major = 10^at,
stop("type argument must be 'major' or 'minor'")
))
}
After you have defined this function, by using the above code, you can call the function inside the axis(...)
function, which draws axes. As a suggestion: save the function away in its own R script and import that script at the top of your calculation using the function source
. By this means, you can reuse the function in future projects. Prior to drawing the axes, you have to prevent plot
from drawing default axes, so add the parameter axes = FALSE
to your plot
call:
plot(p,trans, ylim = c(0,1), ylab='coeff', log='x', axes=F)
Then you may generate the axes, using the tick positions generated by the new function:
axis(1, at=log10Tck('x','major'), tcl= 0.2) # bottom
axis(3, at=log10Tck('x','major'), tcl= 0.2, labels=NA) # top
axis(1, at=log10Tck('x','minor'), tcl= 0.1, labels=NA) # bottom
axis(3, at=log10Tck('x','minor'), tcl= 0.1, labels=NA) # top
axis(2) # normal y axis
axis(4) # normal y axis on right side of plot
box()
As a third option, as you are importing ggplot2 in your original post: The same, without all of the above, with ggplot:
# Your data needs to be in the so-called 'long format' or 'tidy format'
# that ggplot can make sense of it. Google 'Wickham tidy data' or similar
# You may also use the function 'gather' of the package 'tidyr' for this
# task, which I find more simple to use.
d2 <- reshape2::melt(x, id.vars = c('v1'), measure.vars = c('v2','v3'))
ggplot(d2) +
aes(x = v1, y = value, color = variable) +
geom_point() +
scale_x_log10()
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