High resolution capture of plot3d.neuron()

162 views
Skip to first unread message

Andrew Walter-McNeill

unread,
Oct 8, 2020, 6:10:34 PM10/8/20
to nat-user
Hi Natverse team,

Thank you so much for all of your hard work on these amazing tools. I have a question related to exporting a high resolution snapshot of the rgl 3d graphics window. I understand the functions rgl.snapshot() and rgl.postscript are typically used for this purpose, but the former does not allow the user to specify resolution, and the latter does not render objects with transparency. We am trying to create images including a semi-transparent hemibrain mesh, so the transparency is crucial.  

I am using the following code to generate the plot (adapted from https://github.com/natverse/neuprintr/issues/129) : 
library(natverse)
library(readobj)

meshpaths=dir(OBJ_path, pattern = "obj$", full.names = T)
names(meshpaths)=tools::file_path_sans_ext(basename(meshpaths))
meshes=nlapply(meshpaths, function(p) readobj::read.obj(p, convert.rgl = T)[[1]])
neurons <- read.neurons(paths = SWC_path)

plot3d(meshes, col = mesh_color, alpha = mesh_opacity, plotengine = 'rgl', add = TRUE)
plot3d(neurons, col = neuron_colors, lwd = neuron_width,
       soma = soma_radius, WithNodes = neuron_nodes, WithText = neuron_text,
       skipRedraw = TRUE, plotengine = engine, add = TRUE)

Where SWC_path is a directory containing 3 SWC neurons and OBJ_path is a directory containing a hemibrain mesh in OBJ format fetched via neuprint.

the rendering looks beautiful in the xquartz window, but we cannot figure out a good way to capture it in high resolution after we have manipulated it to a good viewing angle. Ideally, we would be able to specify the FOV and export the plot to a high resolution bitmap (tiff). Any ideas how to do this?

I am attaching the results of rgl.snapshot (poor resolution) and rgl.postscript (no transparency), to give an idea of what we're looking for.

Thanks so much for your time,
Andrew
snapshot.png
postscript.pdf

romain.fr...@gmail.com

unread,
Oct 8, 2020, 7:08:14 PM10/8/20
to nat-user
Hi Andrew,

One simple way would be to change the size of the graphic window before doing the snapshot (the default is pretty small). For example: 
`
plot3d(niceMeshes...etc)
par3d(windowRect = c(30, 30, 1530, 1530))
rgl.snapshot("higherres.png")
 would yield ~1500x1500 png in a snapshot.

Hope that helps!
Romain

Greg Jefferis

unread,
Oct 8, 2020, 7:58:08 PM10/8/20
to romain.fr...@gmail.com, nat-user
Romain's advice is the simplest way forwards and has been fine for nearly all our figure needs. If doing this, since you cannot make the rgl window bigger than the screen without some gymnastics, choose a high res screen …

Also I have updated the sample code at https://github.com/natverse/neuprintr/issues/129 for plotting meshes since I made some changes to the nat package on GitHub recently that make this quite a bit easier. Incidentally, as far as I can see the surface mesh you are using is from the hemibrainr package but perhaps it came from my recent response on the neuprint user group. If this is the case your code can be simplified:

library(hemibrainr)
nn=neuprint_read_neurons('/V_.*PN')

# omit the 2nd heavily truncated PN 
plot3d(nn[-2])
plot3d(hemibrain.surf, alpha=.2)

Of course, there are other ways to smarten up your plots. The first is probably to use the mesh format for neurons. You can also add normals to the brain surface. See below.

All the best,

Greg.

--
You received this message because you are subscribed to the Google Groups "nat-user" group.
To unsubscribe from this group and stop receiving emails from it, send an email to nat-user+u...@googlegroups.com.
To view this discussion on the web, visit https://groups.google.com/d/msgid/nat-user/69fa99a8-11d4-4cfd-bd64-93a23bb37730n%40googlegroups.com.

Andrew Walter-McNeill

unread,
Oct 9, 2020, 11:24:58 AM10/9/20
to Greg Jefferis, romain.fr...@gmail.com, nat-user
Hi Romain and Greg,

Thanks so much for the replies. I'll play around with snapshot() and manipulate the rgl window -- if its good enough for you folks, I'm sure it will be good enough for us! 

Greg, thanks for the sleeker code and the link to the hemibrain meshes; these look great. You mentioned plotting the mesh normals and plotting neurons in mesh format as two ways to improve our output, and the second image you attached looks considerably better than the first (I assume because of the normals?) Is there a good post or resource I could consult detailing how to achieve these two things? 

I have tried write.neuron(Cell07PNs[[1]], format = 'obj', file='pathname') to get a neuron in mesh format, but this gives an error. Haven't found anything promising re: normals.

Best,
Andrew




Greg Jefferis

unread,
Oct 11, 2020, 7:02:44 PM10/11/20
to Andrew Walter-McNeill, romain.fr...@gmail.com, nat-user
Dear Andrew,

If you run the python code snippet in the issue you mentioned after editing it to specify the segids for the neurons you want.


e.g. 

segids=[ "2064165421", "698508565", "666818300" ]

You can then run

library(hemibrainr)
# 2 is the directory on which neurons with level of detail (lod) =2 are saved
# they are calibrated in nm iirc
nn=read.neurons("2/")
plot3d(nn)
# nb convert from raw voxels to nm
hbm=as.mesh3d(hemibrain.surf*8)
hbmn=rgl::addNormals(hbm)
shade3d(hbmn, alpha=.2)

And that should give you more or less what you see in the second .

You can also edit the lod in the python script to 1 (slightly better effect visually). I don't think 0 is worth it for the size of the mesh files involved.

All the best,

Greg.
Reply all
Reply to author
Forward
0 new messages