alishinski / lavaanPlot

R package for plotting lavaan path models with DiagrammeR
http://alexlishinski.com/lavaanPlot/
38 stars 4 forks source link

Allow specifying size/resolution of image exports #38

Closed rempsyc closed 2 years ago

rempsyc commented 2 years ago

The save_png and embed_plot_pdf functions allow exporting the sem plot to png and pdf files, respectively. However, I see no arguments for specifying width and height, or resolution. I have a rather large model so when using save_png the words are blurry when zooming. It would be nice to be able to specify a high resolution for a publication-ready figure.

The resolution is not a problem for embed_plot_pdf as it's a scalable vector graphic, and that is great. However, with my large model when saving as pdf, it appears quite cluttered, with so many paths and coefficients. In contrast, opening the plot in the RStudio viewer in full screen gives appreciated breathing space and better visibility for the paths. Right now my workaround is to take a screenshot of the viewer, but again the result is not a scalable vector graphic. Adding an argument for specifying width and height would give the best of both worlds. Thanks for considering my suggestion!

I've tried using the ggplot2::ggsave and dev.off() methods but I couldn't get them to work with the lavaanPlot object.

alishinski commented 2 years ago

Thanks for bringing this to my attention! I will check and see if there's a straightforward way to let you control the png resolution. Saving plots has been a tricky thing to do with diagrammeR, which is why these functions even need to exist. Thanks for letting me know what you tried as well.

alishinski commented 2 years ago

Could you also explain a bit more what you mean about why it doesn't look as good when you save as a pdf versus looking at it in the viewer? The embed_plot_pdf version doesn't look the same as what you see in the viewer?

alishinski commented 2 years ago

So, I still want to know the answer to my last question, but I made the change so that you can specify height and width in pixels when you use save_png. I also added that option to the embed_plot_pdf. I would recommend you only do one or the other but I'm not your mom. Hopefully you find that change helpful.

rempsyc commented 2 years ago

Thanks for providing me with the opportunity to show what I mean. I will try to make a minimally reproducible example and post the results here as soon as I am done.

rempsyc commented 2 years ago

It seems that I cannot reproduce the difference between the viewer and the PDF output. They are, in fact, exactly the same, so I must have been mistaken about this point. Perhaps I was led astray by the lack of margins in the PDF creating an illusion that it was more cluttered than in the viewer which had larger white margins. I think I was also under the impression that widening the viewer was widening the plot, but after more careful observation, it seems the plot is static, not dynamic (unlike regular plots). Indeed, it uses the Viewer tab, not the Plot tab, so it makes sense.

I just downloaded lavaanPlot version 0.6.3 to test it. Specifying e.g. 2000 pixels width (or height) makes a much prettier png, thank you!

png before (blurry):

png after (clean):

However, I was under the impression that specifying both the width and height, in unmatching proportions, would actually resize the plot shape to the desired proportions. But putting dimensions e.g. to width = 3000 and height = 1000, provided the unexpected outcome below:

a - semplot_github6

The image is squeezed rather than the elements resized and rearranged. Now that I understand that it is a static and not dynamic image, I suspect that it might not actually be possible to change the actual width of the image (regardless of the resolution) since it depends on diagrammeR? The hope was that it would have been possible to declutter some lines and coefficients by making the whole thing larger so there would be more space between the lines, affording better visibility.

EXAMPLE CODE

library(lavaan)
library(lavaanPlot)
model <- "
################################################
# IV on mediating variable
cyl ~ disp + hp + drat + wt + qsec
vs ~ disp + hp + drat + wt + qsec
am ~ disp + hp + drat + wt + qsec
#gear ~ disp + hp + drat + wt + qsec
#carb ~ disp + hp + drat + wt + qsec
################################################
# Direct links IV and DV
mpg ~ disp + hp + drat + wt + qsec
################################################
# Mediating variable on DV
mpg ~ cyl + vs + am #+ gear + carb
################################################
"
fitmodel <- sem(model, mtcars, missing="fiml")

lavaanPlot(model = fitmodel, 
           node_options = list(shape = "box", fontname = "Helvetica"),
           edge_options = list(color = "grey"), 
           coefs = TRUE, 
           stand = TRUE, 
           stars = "regress",
           sig = .05,
           graph_options=list(rankdir="LR")) -> my.plot
my.plot

save_png(my.plot, "semplot_github.png", width = 3000, height = 1000)

embed_plot_pdf(my.plot, "semplot_github.pdf", width = 3000, height = 1000)
alishinski commented 2 years ago

So I don't have a full grasp of what's going on under the hood with DiagrammeR, with the moving pieces of graphviz, htmlwidgets, and viz.js, but I think that it is not possible to do what you are suggesting with diagrammeR, where you can increase the dimensions of the whole plot to have more buffer in the layout. But I'm digging a bit more into some of the more recent changes that have been made to DiagrammeR, to see if there is a way to overhaul the way I'm setting up graphs, because the current way has kinda gotten unwieldy, and I will keep this in mind as I do so.