R ggnetwork: unable to change graph layout - r

I am trying ggnetwork and ggplot2 to plot some graph visualisation but I am unable to change the graph layout parameter that comes with the ggnetwork function. My reproducible code are as follows, and I am running this on R 4.0.3 on Ubuntu
install.packages("WDI") # this is the data source I need for this example
library(WDI)
new_wdi_cache <- WDIcache()
library(igraph)
library(tidyverse)
library(ggnetwork)
education<-WDI(indicator=c("SE.PRM.ENRR","SE.SEC.ENRR",
"SE.TER.ENRR","SE.SEC.PROG.ZS","SE.PRM.CMPT.ZS"),
start=2014,
end=2014,
extra= TRUE,
cache=new_wdi_cache)
education<-education[education$region!="Aggregates",]
education<-na.omit(education)
education.features <- education[,4:8]
education.features_scaled <-scale(education.features)
education.distance_matrix <- as.matrix(dist(education.features_scaled))
education.adjacency_matrix <- education.distance_matrix < 1.5
g1<-graph_from_adjacency_matrix(education.adjacency_matrix, mode="undirected")
new.g2<-ggnetwork(g1, layout = "kamadakawai") # LINE A
ggplot(new.g2, aes(x=x, y=y, xend=xend, yend=yend))+
geom_edges(colour="grey")+geom_nodes(size=5,aes(colour=species ))+
theme_blank()+labs(caption='WDI School enrollment and progression datasets')
On line A, I get an error that I really cannot understand:
Error: $ operator is invalid for atomic vectors
What does that mean? And if I remove the 'layout=' parameter from ggnetwork, the code runs. However I really need to change the layout.

The layout parameter doesn't take a string, but the output from a igraph::layout_ function.
So you can do:
new_g2 <- ggnetwork(g1, layout = igraph::layout.kamada.kawai(g1))
ggplot(new_g2, aes(x, y, xend = xend, yend = yend)) +
geom_edges(colour = "grey") +
geom_nodes(size = 8, aes(colour = name)) +
theme_blank() +
labs(caption = 'WDI School enrollment and progression datasets') +
theme(plot.caption = element_text(size = 16))

Related

ggplot2 - plotting time is drastically slower on second and following plots in session (RStudio)

I have an issue, where the first plot of a ggplot script in a RStudio session is really quick (~ 2-3 seconds) and all following plots in the same session, using exactly the same script, take significantly longer (~ 10-20 seconds). I also often need to reload the plot to get it correctly plotted.
Sometimes I also get the warning message:
In grid.Call.graphics(C_setviewport, vp, TRUE) : reached elapsed time limit or In Summary.unit(list(list(2.2, NULL, 8L), list(1, list(list(1, list( : reached elapsed time limit, although the plot still renders after pressing the "refresh current plot" button.
I guess there is an issue with calling some function repeatedly, but I can't figure out which one it would be.
Here is the script I use:
library(ggplot2)
library(tidyverse)
library(showtext)
library(jpeg)
library(patchwork)
#font
font_add("frutiger", regular = "Schrift/frutigerltcom-light.ttf", italic = "Schrift/frutigerltcom-lightitalic.ttf")
showtext_auto()
#colors
i_palette <- c('#ab9c7d', '#235b7f', '#a6aa18', '#338598', '#12c1cd', '#b3d222')
#read data
data <- read.csv(file = "Input_CSV/cond.csv", sep = ";")
#GEOMETRY
g <- ggplot(data,
aes(fill = structure,y=Mittelwert, x=fct_inorder(paste))
) +
geom_hline(yintercept = 3, linetype = 2) +
geom_bar(position = "dodge", stat = "identity") +
geom_errorbar(aes(ymin=Mittelwert-Stdabw, ymax=Mittelwert+Stdabw), width=.2, position=position_dodge(.9))
#LABEL
l <- g +
labs(x = "paste",
y = expression(paste("conductance in ",10^{6}," S/m")),
)
#SCALE
s <- l +
scale_y_continuous(breaks = c(0,3,5,10,15,20)) +
scale_x_discrete(labels = c("1","2","3","4")) +
scale_fill_manual(values = i_palette) +
scale_colour_manual(values = i_palette)
#COORDINATES
c <- s +
coord_cartesian (xlim = c(1, 4), clip="off")
#ANNOTATE
a <- c +
annotate("text", x = 5, y = 3, label = "spec", size = 3)
#THEME
graph1 <- a +
theme_bw() +
theme(text = element_text('frutiger', size=14),
panel.grid.minor = element_blank()
)
#ADD LOGO:
path1 <- "./logo_300px.jpg"
img <- readJPEG(path1, native = TRUE)
img_graph <- graph1 + inset_element(p=img,left = 0.83,bottom = 0,right = 0.97,top = .1, align_to = 'full')
img_graph
showtext_auto(FALSE)
Adding showtext_auto(FALSE) already cut one or two seconds of the time and I suspected the delay is coming from the showtext package, but removing the font_add() and showtext_auto() command for the second run doesn't help.
I also tried:
Clearing the workspace
removing the library() calls after the first run
using print(img_graph) or plot(img_graph) instead of just calling img_graph
Does anyone have an idea to solve this? I already tried to google some ggplot2 script best practices and other things, but I couldn't find any helpful source.
Thanks alot for your help!

Encounter a ggplot2's problem. pic1 is good, then pic2 is good,but when review pic1,it gets bad

Recently, I encountered a question in ggplot2 field. It's confused for me that everytime I plot first plot with ggplot names "pic1"(the result of running is okay), and then I plotted second one with ggplot2 called "pic2". Of course, the "pic2" is good. But at this moment, I check "pic1", I found the regression line became a vertical line.For example:
"pic1"
p <- ggplot()
p <- p + geom_line(data = MyData, aes(x = otherCrop, y = eta ))
p <- p+ geom_point(data = dat,aes(x =otherCrop,
y = dat$sumEnemies, colour = YEAR ),position = position_jitter(width = .01),size = 1)
p <- p+labs(colour = "年份\nYear") + theme_classic(base_size=18) +
theme(axis.title.x=element_text( vjust=0))
p=p + theme(text=element_text(family="Times", size=18))
pic1=p
"pic2"
p <- ggplot()
p <- p + geom_line(data = MyData, aes(x = SHDI, y = eta ))
p <- p+ geom_point(data = dat,aes(x = dat$SHDI,
y = eta,colour = YEAR ),position = position_jitter(width = .01),size = 1)
p <- p+labs(colour = "年份\nYear") + theme_classic(base_size=18) +
theme(axis.title.x=element_text( vjust=0))
p=p + theme(text=element_text(family="Times", size=18))
pic2=p
But at this moment, I started to review "pic1", I found it as below:
It became a strange short vertical line. This would be difficult because I cannot plot them in a same paper. Does anybody know what's the problem?
I think this is a great example of why using the dataframe$column syntax inside an aes call is discouraged: it makes your plot vulnerable to subsequent changes in your data. Here's a simple example. Start with a data frame with columns x and y:
library(ggplot2)
df <- data.frame(x = 1:10, y = 1:10)
Now make a ggplot, but instead of using aes(x = x, y = y), we make the mistake of doing aes(x = df$x, y = df$y):
vulnerable_plot <- ggplot()
vulnerable_plot <- vulnerable_plot + geom_line(data = df, aes(x = df$x, y = df$y))
pic1 <- vulnerable_plot
Now we review our plot. Sure, ggplot nags us to say we shouldn't use this syntax, but the plot looks fine, so who cares, right?
pic1
#> Warning: Use of `df$x` is discouraged. Use `x` instead.
#> Warning: Use of `df$y` is discouraged. Use `y` instead.
Now, let's make pic2 identical to pic1 except we use the correct syntax:
invulnerable_plot <- ggplot()
invulnerable_plot <- invulnerable_plot + geom_line(data = df, aes(x = x, y = y))
pic2 <- invulnerable_plot
Now we don't get any warning, but the plot looks the same.
pic2
So there's no difference between pic1 and pic2. Or is there? What happens when we change our data frame?
df$y <- 10:1
vulnerable_plot
Oh dear. Our first plot has changed because the plot object has a reference to an external variable that it relies on to build the plot. That's not what we wanted.
However, with the version where we used the correct syntax, a copy of the data was taken and is kept with the plot data, so it remains unaffected by subsequent changes to df:
invulnerable_plot
Created on 2020-08-23 by the reprex package (v0.3.0)

Rsample - nested_cv (ggplot2 - geom_tile) -> graphical visualization of nested CV

I am working on a paper where I am using nested-cross-validation. I am keen to present a graphical representation of such.
For the data partition, I am using the package rsplit. #Topepo presents a great vignette here: https://tidymodels.github.io/rsample/reference/tidy.rsplit.html
#Nested Group
library(rsample)
theme_set(theme_bw())
library(rsample)
library(patchwork)
cv <- nested_cv(iris, outside = group_vfold_cv(data = iris, group = "Species", v = 3), inside = rsample::bootstraps(times = 5, apparent = F))
tidy_cv<-tidy(cv)
innerplot<- ggplot(tidy_cv, aes(x = inner_Resample, y = inner_Row, fill = inner_Data)) +
geom_tile() + facet_wrap(~Resample) + scale_fill_brewer()
validation<- ggplot(tidy_cv, aes(x = Resample, y = Row, fill = Data)) +
geom_tile() + facet_wrap(~Resample) + scale_fill_brewer()
validation + innerplot
However, what I am actually trying to achieve is a stack of geom_tiles. Basically, something like this: https://i.stack.imgur.com/vTSPw.png
However, it would be facet_wrap ~Resample.
Is it clear what I am trying to do?
Visual Representaiton
Cheers

Using frame parameter to making a plot from ggplot to plotly

Here is my data:
data <- data.table(year = rep(1980:1985,each = 5),
Relationship = rep(c(" Acquaintance","Unknown","Wife","Stranger","Girlfriend","Friend"), 5),
N = sample(1:100, 30)
)
I can use plotly::plot_ly function to plot a Dynamic map of the years like this:
plot_ly(data
,x=~Relationship
,y=~N
,frame=~year
,type = 'bar'
)
but when I using ggplot with parameter frame ,I get a error
Error in -data$group : invalid argument to unary operator
here is my ggplot code :
p <- ggplot(data = data,aes(x =Relationship,y = N ))+
geom_bar(stat = "identity",aes(frame = year))
ggplotly(p)
Can you modify my ggplot code to produce the same graph ?
This example runs successfully using frame parameter:
data(gapminder, package = "gapminder")
gg <- ggplot(gapminder, aes(gdpPercap, lifeExp, color = continent)) +
geom_point(aes(size = pop, frame = year)) +
scale_x_log10()
ggplotly(gg)
In case others are still looking, this does appear to be a bug related to geom_bar. Per Stéphane Laurent's GitHub report (https://github.com/ropensci/plotly/issues/1544) a workaround is to use geom_col(position = "dodge2") or geom_col(position = "identity") instead of geom_bar(stat='identity')

How to get a really periodic polar surface plot with ggplot

Sample data:
mydata="theta,rho,value
0,0.8400000,0.0000000
40,0.8400000,0.4938922
80,0.8400000,0.7581434
120,0.8400000,0.6675656
160,0.8400000,0.2616592
200,0.8400000,-0.2616592
240,0.8400000,-0.6675656
280,0.8400000,-0.7581434
320,0.8400000,-0.4938922
360,0.8400000,0.0000000
0,0.8577778,0.0000000
40,0.8577778,0.5152213
80,0.8577778,0.7908852
120,0.8577778,0.6963957
160,0.8577778,0.2729566
200,0.8577778,-0.2729566
240,0.8577778,-0.6963957
280,0.8577778,-0.7908852
320,0.8577778,-0.5152213
360,0.8577778,0.0000000
0,0.8755556,0.0000000
40,0.8755556,0.5367990
80,0.8755556,0.8240077
120,0.8755556,0.7255612
160,0.8755556,0.2843886
200,0.8755556,-0.2843886
240,0.8755556,-0.7255612
280,0.8755556,-0.8240077
320,0.8755556,-0.5367990
360,0.8755556,0.0000000
0,0.8933333,0.0000000
40,0.8933333,0.5588192
80,0.8933333,0.8578097
120,0.8933333,0.7553246
160,0.8933333,0.2960542
200,0.8933333,-0.2960542
240,0.8933333,-0.7553246
280,0.8933333,-0.8578097
320,0.8933333,-0.5588192
360,0.8933333,0.0000000
0,0.9111111,0.0000000
40,0.9111111,0.5812822
80,0.9111111,0.8922910
120,0.9111111,0.7856862
160,0.9111111,0.3079544
200,0.9111111,-0.3079544
240,0.9111111,-0.7856862
280,0.9111111,-0.8922910
320,0.9111111,-0.5812822
360,0.9111111,0.0000000
0,0.9288889,0.0000000
40,0.9288889,0.6041876
80,0.9288889,0.9274519
120,0.9288889,0.8166465
160,0.9288889,0.3200901
200,0.9288889,-0.3200901
240,0.9288889,-0.8166465
280,0.9288889,-0.9274519
320,0.9288889,-0.6041876
360,0.9288889,0.0000000
0,0.9466667,0.0000000
40,0.9466667,0.6275358
80,0.9466667,0.9632921
120,0.9466667,0.8482046
160,0.9466667,0.3324593
200,0.9466667,-0.3324593
240,0.9466667,-0.8482046
280,0.9466667,-0.9632921
320,0.9466667,-0.6275358
360,0.9466667,0.0000000
0,0.9644444,0.0000000
40,0.9644444,0.6512897
80,0.9644444,0.9997554
120,0.9644444,0.8803115
160,0.9644444,0.3450427
200,0.9644444,-0.3450427
240,0.9644444,-0.8803115
280,0.9644444,-0.9997554
320,0.9644444,-0.6512897
360,0.9644444,0.0000000
0,0.9822222,0.0000000
40,0.9822222,0.6751215
80,0.9822222,1.0363380
120,0.9822222,0.9125230
160,0.9822222,0.3576658
200,0.9822222,-0.3576658
240,0.9822222,-0.9125230
280,0.9822222,-1.0363380
320,0.9822222,-0.6751215
360,0.9822222,0.0000000
0,1.0000000,0.0000000
40,1.0000000,0.6989533
80,1.0000000,1.0729200
120,1.0000000,0.9447346
160,1.0000000,0.3702890
200,1.0000000,-0.3702890
240,1.0000000,-0.9447346
280,1.0000000,-1.0729200
320,1.0000000,-0.6989533
360,1.0000000,0.0000000"
read in a data frame:
foobar <- read.csv(text = mydata)
You can check (if you really want to!) that the data are periodic in the theta direction, i.e., for each given rho, the point at theta=0 and theta=360 are precisely the same. I would like to plot a nice polar surface plot, in other words an annulus colored according to value. I tried the following:
library(viridis) # just because I very much like viridis: if you don't want to install it, just comment this line and uncomment the scale_fill_distiller line
library(ggplot2)
p <- ggplot(data = foobar, aes(x = theta, y = rho, fill = value)) +
geom_tile() +
coord_polar(theta = "x") +
scale_x_continuous(breaks = seq(0, 360, by = 45), limits=c(0,360)) +
scale_y_continuous(limits = c(0, 1)) +
# scale_fill_distiller(palette = "Oranges")
scale_fill_viridis(option = "plasma")
I'm getting:
Yuck! Why the nasty hole in the annulus? If I generate a foobar data frame with more rows (more theta and rho values) the hole gets smaller. This isn't a viable solutione, both because computing data at more rho/theta values is costly and time-consuming, and both because even with 100x100=10^4 rows I still get a hole. Also, with a bigger dataframe, ggplot takes forever to render the plot: the combination of geom_tile and coord_polar is incredibly inefficient. Isn't there a way to get a nice-looking polar plot without unnecessarily wasting memory & CPU time?
Edit: all value of data for theta=360 were removed (repeat from the values of theta=0)
ggplot(data = foobar, aes(x = theta, y = rho, fill = value)) +
geom_tile() +
coord_polar(theta = "x",start=-pi/9) +
scale_y_continuous(limits = c(0, 1))+
scale_x_continuous(breaks = seq(0, 360, by = 45))
I just removed limits from scale_x_continuous
That gives me:

Resources