I am busy creating a set of components to integrate the bupaR package (from R) into knime for business process analysis. Some the bupaR commands generate ggplot objects that need to be plotted and shown.
Currently, I am using R View (Workspace) to run the bupaR command (e.g. trace_explorer(), which then passes the ‘image’ to the Image View node. This works, but the output is PNG and the quality is subpar.
I wanted to see if we can export a SVG image from “R View (Workspace)” to the Image View or Javascript View (the latter would allow me to add html buttons to zoom in and out).
However, it’s not clear how to do this. I have tried ggsave(), but this gives me a lot of errors. Anybody an idea in which direction I can look to get this to work (some existing workflows that do something similar). I couldn’t find anything useful online after some hours of searching.
Thanks
PS: Is there a way to see how other community components are created (the internals?). It might help me get some ideas.
Thanks for the input. It really helped and I got it working.
I copied your workflow, and although it gave a few errors on my MacBook, it was sufficient to figure out how to get it working. Not sure if something changed in KNime which made your workflow not work, or if it has to do with me being on Mac, or whether I simply did something wrong.
For those reading this in the future, here are some observations I experienced that might be useful:
The ggsave() function, which you often find online being suggested to turn ggplot into svg, doesn’t seem to work. It kept throwing errors which I simply could not decipher. Maybe you get it to work, maybe it doesn’t play nicely with kNime and the R extension. Instead I used CairoSVG() function of the Cairo package.
Initially I tried to create an RScript which directly saved the SVG XML into a variable in my R workspace. I never got this to work. My workaround is to save the SVG to a temporary file (using the tempfile(fileext = ".svg") function) and then to read it again into a variable using the readlines() function.
Another observation which took me quite some time to realize is that the Eval Selection button in R Snippet Tab of e.g. the R View (Workspace) node doesn’t work well with CairoSVG. It will throw errors, which don’t appear if you click the Eval Script button or simply execute the node. I assume it has something to do with CairoSVG creating a different output device, but the R Snippet somehow resetting to the default output devices during separate executions of Eval Selection (To be honest, this is a wild guess).
My final solution uses a R to Table node with the following code in the R Snippet dialog
library(Cairo)
# Create temporary file to store svg
tmp1 <- tempfile(fileext=".svg")
# Create new SVG device and print the ggplot object. Then close the device
CairoSVG(width=width, height=height, file = tmp1)
print(ggplot_object)
dev.off()
# Read the temporary SVG file and store the SVG XML code into a dataframe (into a single cell of the data frame)
knime.out <- data.frame(paste(readLines(tmp1), collapse=" "))
This generates a Knime table with the SVG XML in the first column of the first row. Next I send this output to a Generic Javascript View (Javascript) node which allows me to use Javascript to visualize the SVG again (I also added some additional HTML buttons that allow me to zoom in and out and export the SVG as SVG, JPEG and PNG.
PS: It’s my aim to create a shared component to turn ggplot into SVG, but this isn’t ready yet.
I am not entirely sure if I understood your questions correctly, @benoitdepaire, but you can drop any component from Community Hub into a workflow and open it up. To inspect it properly, I suggest to disconnect the component immediately so that you can edit the component.
This would be a pretty cool component by itself, to be honest. Given a table with an XML (or String?) column that contains an SVG, plot it with the buttons on top of it. This would be very useful for various use cases and you should be able to just embed it in your bupaR components easily…
Ignore this. I am learning more and more about Knime and in hindsight this question makes no sense. I was looking at a node within an extension to see if I could open it (as you can with components). Now I realize components and nodes (from extensions) are different beasts.
I guess I could idd turn this into a separate component. Right now, it’s part of a bigger component (ggplot to svg) which I reuse throughout my bupar integration. But, I might just turn it into its own component.
This makes it even more suitable for a dedicated, shared component: You can use it in multiple places and only need to update it once to propagate changes downstream! Let me know if there’s anything that I/we can help with – even if it’s just testing and providing feedback!