qgraph legend two rows instead of a long one - r

I am plotting my network graph with over 117 nodes. I have made it to where you can visualize a legend for the nodes, but I have to make the text really small. Is there a way I can adjust the legend to have two columns of my nodes? I have attached my code and a picture of the graph in this question.
Network image I have
Network image I want
Thanks!!
g = LoGo(dataset, normal= FALSE)
qgraph(g, layout = "spring", diag = FALSE, labels = TRUE,
nodeNames = rownames(g),
legend.cex = 0.16,vsize = 2, GLratio = 9, vsize=4, legend=TRUE, legend.cex=.6)

Related

Can the shape of data points be changed according to group when plotting with Sjplot?

I am trying to optimize a sjPlot for black and white printing.
My plot looks at essentially numbers of parasites, depending on the amount of rain and is categorized by breeding status.
My data is broken up into groups of bachelor and breeder/territorial males.
While I can break up the prediction lines (GLMM pred models) into dashed and solid for the two groups when using "bw" for colors in the plot.model function, I cannot change the shape (or even grayscale color) of the raw data points for the two groups.
I can split the colors of the data points by group when using a different color scheme, but this distinction disappears with "bw" (all of the points are the same shade).
Key Takeaway: Is there a way to maintain a dashed and solid line distinction between two prediction lines (achieved using [colors="bw"]) and to either change the shape or color of raw data points by group in sjPlot? Thank you in advance!
I have tried using various additions to change shape; however, nothing has worked. Here are a few of the code additions to the plot that I have tried:
aes(shape=Reproductive_Status)
dot.shape="Reproductive_Status"
group="Reproductive_Status"....shape=group
Code: set up of the GlmmTMB model
strong.2.int.y<-glmmTMB(log.strongyle.
~ Rainfall_2MDelay*Reproductive_Status+age_y+(
1 | Animal_ID),data=parasites,na.action=na.exclude)
Code: plot; "aes(shape=Reproductive_Status)" does nothing to change point shape in this function unfortunately
test2.plot_strong.2.int.y.bw<-plot_model(strong.2.int.y, type ="pred", terms = c("Rainfall_2MDelay","Reproductive_Status"),
sort.est = NULL, rm.terms = NULL, group.terms = NULL, pred.type = "fe",
title = "(a)", axis.title = NULL, axis.labels = NULL, legend.title = NULL,
colors = "bw", show.intercept = FALSE, show.values = TRUE, show.p = F,
show.data = T, show.legend = TRUE, digits = 2, show.scatter=T,
dot.size = 2, dot.alpha=0.3,line.size = 1, vline.color = NULL,
aes(shape=Reproductive_Status))
+ labs(x=expression('Rainfall, R'[t-2]*' (mm)'),
y="Strongyle Count (log[x])")
+ theme(plot.title = element_text(hjust=0.0))
plot(test2.plot_strong.2.int.y.bw,add=TRUE)
For marginal effects plots (i.e. when type = "pred"), sjPlot simply calls functions from ggeffects. So if you're familiar with ggplot2, I suggest you use directly ggpredict(), which returns the underlying data that is needed for plotting.
You can also try ggeffects' plot()-method, and then try to customize it. There are two vignettes describing how to customize the plots:
Plotting Marginal Effects and Customize Plot Appearance.
Hope that helps.

Convert network/igraph object to plotly

I have build a network and created both igraph and network object. I can plot the object with ggplot and export to plot_ly using ggplotly.
The problem is that i don´t have real control over the graph so i was wondering if there is a better way to import my network (or Ig graph) into plotly to have better control over the layout.
For example when connecting two nodes i have a weight score and would like to add a slider to filter according to the weight score (between 0 and 1).
I guess plotly could be a nice alternative that would allow dynamic filtering over the network graph.
So here is a reproducible exemple.
I create a bipartite network as follows:
library(ggnet)
library(plotly)
library(network)
n <- data.frame(event1 = c(-0.2,0.8,0.4,0),
event2 = c(0.34,-0.17,0.3,0),
event3 = c(0.2,0.1,-0.73,0),
row.names = letters[1:4])
net <- network(n,
matrix.type = "bipartite",
ignore.eval = FALSE,
names.eval = "weights")
col = c("actor" = "grey", "event" = "gold")
set.edge.attribute(net, "color", ifelse(net %e% "weights" > 0, "green", "red"))
g <- ggnet2(net, color = "mode", palette = col, label = TRUE, edge.color = "color",edge.label="weights")
Thanks,
I convert the plot to ggplot format:
gp <- ggplotly(g)
htmlwidgets::saveWidget(as_widget(gp), "ggplot.html")
I get the following graph.
How can i add a slider to the graph so i can filter out (dynamically) the edges above or nelow a certain value ???
For example to see all edges >0 ??? I know how do it from the graph itself but it is not dynamic. I want to use plotly to view and use a slider bar to remove edges.
Thanks,

Likert plot 100 percent scale with Likert Package

I wanted to draw a likert plot with 100% scale (100) with equall plot size. I tried following code and give me following plot:
plot(LIKPR3,centred=TRUE,plot.percents=TRUE, plot.percent.neutral = TRUE, text.size = 6,
text.color = "black", include.center = TRUE,
ordered = TRUE, wrap = 60, wrap.grouping = 50, legend = "Response",
legend.position = "bottom", panel.arrange = "v",
plot.percent.low = FALSE, plot.percent.high = FALSE, central=FALSE)
I would like to make plot similar to following.
I am using "likert" package in R.
Any help is highly appreciated.
Hej,
the difference between the plot that you have created and the plot that you want to have is the "centre". With centered = TRUE you force the plot to be centred around the "neutral" category at 0, in case of a 5-point Likert scale this will be the third category. To obtain a stacked plot you have to use centered = FALSE.

How to reduce the space between the plot and the border for geographic maps?

I am trying to plot a bathymetry map of the the northeast US using the marmap library. The following code loads the correct extent but when I plot the map I have blank space between the border and the map either at the top/bottom or left/right of the map. This also occurs when exporting the plots. If I drag the plot viewer screen size the plot adjusts and I can remove almost all of the empty space but I will be running this script in a loop so its not practical to solve this problem this way. Because of the loop I also can't hard code any dimensions into the plot because it will change for each new extent. How can I set the border of the plot to match the extent of the bathymetry?
library(marmap)
library(maps)
atl<- getNOAA.bathy(-80.93645,-41.61417,30.2 ,60.905 ,resolution=4)
blues <- colorRampPalette(c("darkblue", "cyan"))
greys <- colorRampPalette(c(grey(0.4),grey(0.99)))
plot(atl, image = TRUE, land = TRUE, n=0,
bpal = list(c(0, max(atl), greys(100)),
c(min(atl), 0, blues(100))))
map(database= "state", col="black", fill=FALSE, add=TRUE)
text(x=state.center$x, y=state.center$y, state.abb, cex=0.5)
This behavior is caused by the asp argument of plot.bathy(). By default, it is fixed as asp = 1 to ensure that the scales on both axes are the same (one degree of longitude equals one degree of latitude). An unwelcome consequence of this default, is the white bands appearing either on the left/right sides of the graph, or on the top/bottom sides depending on the dimensions of your bathymetric map and the plotting device.
So I suppose you have 2 options:
If you don't mind having a slightly distorted perspective, you can set asp = NA in your call to plot.bathy()
If you want to have the correct aspect ratio but need to use the default size for your plotting region, then you have to download a bathymetric region that covers the whole plotting region of your active device. For instance, you could call plot.bathy() once to create a "default" plot, then, use par("usr") to determine the limits of the bathymetry needed to fill the entire plotting area. You would then download a second bathymetry with the appropriate ranges in longitude and latitude. Which is maybe not desirable.
Here is what the code would look like for the second option:
atl <- getNOAA.bathy(-80.93645, -41.61417, 30.2, 60.905, resolution = 4)
blues <- colorRampPalette(c("darkblue", "cyan"))
greys <- colorRampPalette(c(grey(0.4), grey(0.99)))
plot(atl, image = TRUE, land = TRUE, n = 0,
bpal = list(c(0, max(atl), greys(100)),
c(min(atl), 0, blues(100))))
coord <- par("usr")
atl2 <- getNOAA.bathy(coord[1], coord[2], coord[3], coord[4], res = 4)
plot(atl2, image = TRUE, land = TRUE, lwd = 0.2,
bpal = list(c(0, max(atl2), greys(100)),
c(min(atl2), 0, blues(100))))
map(database = "state", col = "black", fill = FALSE, add = TRUE)
text(x = state.center$x, y = state.center$y, state.abb, cex = 0.5)
I suppose the solution proposed by Roman Luštrik works too, but it has the inconvenience of leaving the white bands visible on both sides of the plot.
As an aside, if you have a lot of bathymetric regions to plot, you should maybe consider using the keep = TRUE argument of getNOAA.bathy() to avoid querying the NOAA servers each time you need to re-execute your code (and it is much faster to load local data than remote ones). And you could also download once and for all the global 4Go ETOPO1 and use subset.bathy() to, well, subset the bathymetry you need for each plot.
Here is a proposal using a workaround. The idea is to convert the bathy object into raster object and then make the plot using levelplot from rasterVisthat correctly fits the plotting area to the raster extent. Note that using raster allows having a defined pixel size and, therefore, a correct width/height ratio that you don't seem to have with marmap::plot method.
library(raster)
library(rasterVis)
r <- marmap::as.raster(atl)
state <- map('state', plot = FALSE)
state <- data.frame(lon = state$x, lat = state$y)
state.lab <- data.frame(lon = state.center$x, lat = state.center$y,
label = state.abb)
# you can remove the color legend by adding colorkey = FALSE in levelplot()
levelplot(r,
at = c(seq(min(atl), 0, length.out = 100),
seq(0, max(atl), length.out = 100)[-1]),
col.regions = c(blues(100), greys(100)),
margin = FALSE) +
xyplot(lat ~ lon, state, type = 'l',
col = 'black') +
xyplot(lat ~ lon, data = state.lab,
panel = function(y, x, ...) {
ltext(x = x, y = y, labels = state.lab$label, cex = 0.75)
})

Plotting titles and legends on interactive igraph plot? (R)

I'm having trouble adding a title and legend to the inside of my graph. Is it not possible with tkplot OR plot?
dff <- data.frame(a = c(0,1,2,3,4),b = c(3,4,5,6,7))
nod <- data.frame(node = c(0:7),wt = c(1:8))
pg <- graph_from_data_frame(d = dff, vertices = nod,directed = F)
# plot function with edge.label added
tkplot(pg, edge.label = nod$wt, main = "this is my graph")
legend('topleft',legend= degree(pg)*5,pt.cex=20,col='white',
pch=21, pt.bg='white')
It doesn't seem to want to work the way I want it to. I just want the legend to show the vertices adjusted to be bigger for a higher degree.
I was also wondering if there is a way to plot only certain vertices from the graph? For example, you choose one vertex and plot only the vertices that form a path back to it?
Based on the help for tkplot, here's an example of how to add a title to an interactive plot:
library(tcltk)
id = tkplot(pg, edge.label = nod$wt, main = "this is my graph")
canvas = tk_canvas(id)
width = as.numeric(tkcget(canvas, "-width"))
height = as.numeric(tkcget(canvas, "-height"))
tkcreate(canvas, "text", width/2, 25, text="My title",
justify="center",
font=tkfont.create(family="helvetica", size=20, weight="bold"))
For the standard base R plot, your code works as is:
plot(pg, edge.label = nod$wt, main = "this is my graph")
legend('topleft',legend= degree(pg)*5,pt.cex=20,col='white',
pch=21, pt.bg='white')

Resources