How to use lattice in Rpy2 and save result to pdf? - python

I am following the documentation for rpy2 here (http://rpy.sourceforge.net/rpy2/doc-2.1/html/graphics.html?highlight=lattice). I can successfully plot interactively using lattice from rpy2, e.g.:
iris = r('iris')
p = lattice.xyplot(Formula("Petal.Length ~ Petal.Width"),
data=iris)
rprint = robj.globalenv.get("print")
rprint(p)
rprint displays the graph. However, when I try to save the graph to pdf by first doing:
r.pdf("myfile.pdf")
and then my lattice calls, it does not work and instead results in an empty pdf. If I do the same (call r.pdf, then plot) with ggplot2 or with the R base, then I get a working pdf. Does lattice require anything special from within Rpy2 to save the results to a PDF file? The following does not work either:
iris = r('iris')
r.pdf("myfile.pdf")
grdevices = importr('grDevices')
p = lattice.xyplot(Formula("Petal.Length ~ Petal.Width"),
data=iris)
rprint = robj.globalenv.get("print")
rprint(p)
grdevices.dev_off()
Thank you.

you need some equivalent of dev.off() after the print command.
That is, in order to save your graphs to pdf, the general outline is:
pdf(...)
print(....)
dev.off()
Failing to call dev.off() will result in an empty pdf file.
from this source, it appears that the equivalent in rpy2 might be
grdevices.dev_off()

The solution is to use:
robjects.r["dev.off"]()
For some reason the other variants do not do the trick.

Related

Execute Folium Library code in RMarkdown chunk doesn´t show up map

I`m working with RMarkdown and Python, I just created a chunk where I add code relate to the folium library, but I can create the report or show up the map
Chunk setup in my RMarkdown Report, I`m al so working with matplotlib in the same RMarkdown report a nd it works fine
```{r setup,include=FALSE}
library(reticulate)
library(ggplot2)
library(lattice)
library(vembedr)
use_python("C:/Users/renzocrossi/AppData/Local/Programs/Python/Python310/python.exe")
knitr::opts_chunk$set(echo=TRUE,message = FALSE,warning = FALSE)
This is the code in the RMarkdown chunk about folium
```{python}
import folium
m = folium.Map(location = [46.20, 6.144], zoom_start=6, tiles="OpenStreetMap")
fg = folium.FeatureGroup(name="My Map")
fg.add_child(folium.Marker(location=[40.12, 10.1], popup="Hi I'am a Marker",
icon=folium.Icon(color='green')))
m.add_child(fg)
m
```
<folium.folium.Map object at 0x000001F6A1098B20>
I ran the code in Python and didn't get an output either. The only way that I think this would work as-is is in a Jupyter notebook. (I think!)
However, with just a bit more, you can definitely get the map on the document. I added import webbrowswer so that I could export the map as HTML, then render it in R Markdown.
```{python mapper, include=FALSE}
import folium
import webbrowser
m = folium.Map(location = [46.20, 6.144], zoom_start=6, tiles="OpenStreetMap")
fg = folium.FeatureGroup(name="My Map")
fg.add_child(folium.Marker(location=[40.12, 10.1], popup="Hi I'am a Marker",
icon = folium.Icon(color='green')))
m.add_child(fg)
m.save("map.html")
webbrowser.open("map.html")
```
Then outside of the Python chunk (not in any chunk), I called the map.
![](map.html)
![](map.html){width=100% height=800px}
I don't know if you have any default figure sizes set, I didn't for this example. However, the calls of this map rendered this:
By the way, the maps are still completely interactive, as they would be in Python or if rendered directly through R.
For example, I decreased magnification and rendered the following:

VTK : how to read grid cells' lenth, width and height?

I have a huge grid in *.pvd format. I would like to ensure some cells size specification have been respected when building said grid. To do so, I should get a cell data array with (dx,dy,dz)
I first tried to check this in Paraview with very little success. Then I resolved to export the mesh in various format (vtk, vtu, ex2) and import things into python using the vtk module, as in the code below. Unfortunately, the size of the mesh forbids it and I get various error messages stating "Unable to allocate n cells of size x".
import vtk
reader = vtk.vtkXMLUnstructuredGridReader()
reader.SetFileName("my_mesh.vtu")
reader.Update()
Finally, in Paraview there is a python-shell that allows me to open the grid file in either pvd or vtk format:
>>> from paraview.simple import *
>>> my_vtk = OpenDataFile("my_mesh.vtk")
>>> print dir(my_vtk)
Despite my browsing the methods and attribute of this reader object, I remain clueless about where to fetch any geometry information on the grid. I also browsed through the simple module documentation and I can't really wrap my head around it.
So how can one retrieve information regarding the geometry of cells from a paraview.servermanager.LegacyVTKReader object?
Any clue about how to achieve this with through the paraview GUI, or any kludge to load the vtk object into python vtk despite the memory issue is also very welcome. Sorry for such a hazy question, but I don't really know where to get started...
You can use GetClientSideObject() (see here) to get a VTK object in the Paraview Python shell. After that you can use all the regular VTK Python functions. For example, you can write the following in the Paraview Python shell
>>> from paraview.simple import *
>>> currentSelection = GetActiveSource()
>>> readerObj = currentSelection.GetClientSideObject()
>>> unstructgrid = readerObj.GetOutput()
>>> firstCell = unstructgrid.GetCell(0)
>>> cellPoints = firstCell.GetPoints()
Alternatively, you can use Programmable Filter in ParaView. This allows access to full VTK python module and even NumPy or other modules. You can enter following script in the script window of the programmable filter:
import vtk as v
import numpy as np
inp = self.GetUnstructuredGridInput()
cells = inp.GetCells()
cells.InitTraversal()
cellPtIds = v.vtkIdList()
lenArr = v.vtkDoubleArray()
lenArr.SetNumberOfComponents(3)
lenArr.SetName('CellSize')
while cells.GetNextCell( cellPtIds ):
pts = []
for i in range( cellPtIds.GetNumberOfIds() ):
ptCoords = inp.GetPoint( cellPtIds.GetId(i) )
pts.append( ptCoords )
pts = np.array( pts )
dx = np.max(pts[:,0]) - np.min(pts[:,0])
dy = np.max(pts[:,1]) - np.min(pts[:,1])
dz = np.max(pts[:,2]) - np.min(pts[:,2])
lenArr.InsertNextTuple3(dx, dy, dz)
out = self.GetUnstructuredGridOutput()
out.ShallowCopy( inp )
out.GetCellData().AddArray( lenArr )
In Paraview when you select the 'ProgrammableFilter1' icon in your pipeline, a new cell data array will be available to you from the drop-down as shown in the screenshot below. You can modify the script above to save the data to file to analyze externally.
This information is visible in the Information Tab.

How can I write a velocity field to a VTI image with anaconda Python?

I am trying to write a VTK Image Data file (.vti) with python. For my python coding I am using the Anaconda distribution. I am using the evtk package, which has the ability to write a vtk file.
The data I need to write is a velocity for which I have the 3d X,Y,Z and U,V,W 3d arrays. I have found some sample code which uses the evtk package to write a .vti file.(http://www.vtk.org/Wiki/VTK/Writing_VTK_files_using_python)
The problem is that the sample code and built in functions only take scalar point or cell data. So I am able to write a file with scalars, but I need it to have the data as vectors.
I am digging through the actual package files and trying to find a solution or tools to code one.I would extremely appreciate if somebody had suggestions or solutions to give me a hand.
I enclose the test code I have written from info on the wiki just in case I am missing a way of inputing to the function, but I fear I am going to need to start from scratch.
Thanks in advance
(removed the code since the one bellow is more recent)
Managed to write an unstructured file (.vtu), but I would really like to be a able to write an Image Data file.(Found the following link helpful during the process. http://www.aero.iitb.ac.in/~prabhu/tmp/python_cep07/course_handouts/viz3d_handout.pdf)
Thanks again in advance
I attach the code to see if anybody has any suggestions.
from tvtk.api import tvtk, write_data
import numpy as N
##Generation of data
#array of x,y,z coordinates
[Z,Y,X] = N.mgrid[-2.:2+1, -2.:2+1, -2.:2+1]
#array of zeros to add the u,v,w components
[W,V,U] = N.zeros_like([Z,Y,X],dtype=float)
#loop through data to have correct format
points = N.array([N.zeros(3) for i in range(len(Z)*len(Z[0])*len(Z[0][0]))])
velF = N.zeros_like(points)
c=0
for k in range(len(Z)):
for j in range(len(Z[0])):
for i in range(len(Z[0][0])):
#coordinates of point
x = X[k][j][i]
y = Y[k][j][i]
z = Z[k][j][i]
points[c] = N.array([x,y,z])
#test velocity field
u = k -2.
v = 0.
w = 0.
velF[c] = N.array([u,v,w])
#update counter
c = c+1
##Generate and write the vtk file
Ugrid = tvtk.UnstructuredGrid()
Ugrid.points = points
Ugrid.point_data.vectors = velF
Ugrid.point_data.vectors.name = 'velocity'
write_data(Ugrid, 'vtktest.vtu')
If you want to write the unstructured grids using evtk, here you can find a full demo with point and cell data (both vector and scalar fields): https://gist.github.com/dromanov/0fb8bacff5342a56a690.
Description of the technique and explanations are here: http://spikard.blogspot.ru/2015/07/visualization-of-unstructured-grid-data.html.
Good luck!

R package Bio3D tutorial reproducing

I started working with R package called Bio3D
(http://thegrantlab.org/bio3d/index.php)
and encountered a problem during reproducing examples from "Protein Structure Networks with Bio3D" tutorial
(http://thegrantlab.org/bio3d/tutorials/protein-structure-networks).
Here is the fragment I am trying to do:
"
The code snippet below first sets the file paths for the example HIVpr starting structure (pdbfile) and trajectory data (dcdfile), then reads these files (producing the objects dcd and pdb).
dcdfile <- system.file("examples/hivp.dcd", package = "bio3d")
pdbfile <- system.file("examples/hivp.pdb", package = "bio3d")
# Read MD data
dcd <- read.dcd(dcdfile)
pdb <- read.pdb(pdbfile)
inds <- atom.select(pdb, resno = c(24:27, 85:90), elety = "CA")
trj <- fit.xyz(fixed = pdb$xyz, mobile = dcd,
fixed.inds = inds$xyz, mobile.inds = inds$xyz)
Once we have the superposed trajectory frames we can asses the extent to which the atomic fluctuations of individual residues (in this very short example simulation) are correlated with one another and build a network from this data:
cij <- dccm(trj)
net <- cna(cij)
plot(net, pdb)
"
And till this moment everything works well.
# View the correlations in pymol
view.dccm(cij, pdb, launch = FALSE)
Here I open generated pdb file corr.inpcrd with pymol.
But instead of nice cartoon 3D model I see just aminoacid residues represented by dots.
Tried to solve the problem with pymol using settings for cartoons, ribbons, colors, transparency and command show but it changed nothing.
Would be grateful for your suggestions!
I have not enough reputation to illustrate expected and obtained outcome with images but probably I will be able to send them directly if necessary.
Thank you!
Typically this will work if pymol is in your path for executables (see here: http://tinyurl.com/lzhpz3w for more about where bio3d expects to find pymol and muscle).
view.dccm(cij, pdb, launch = FALSE)
I don't use windows myself but if you post this question on the bio3d bitbucket issues page https://bitbucket.org/Grantlab/bio3d/issues you will get help from experienced windows bio3d users including the author of this function.
Try setting launch=TRUE in your call to the view.dccm() function to have both PDB and pymol script loaded for you.

Can Matplotlib save a plot and re-open it after in its own GUI, without losing information? [duplicate]

Is there a way to save a Matplotlib figure such that it can be re-opened and have typical interaction restored? (Like the .fig format in MATLAB?)
I find myself running the same scripts many times to generate these interactive figures. Or I'm sending my colleagues multiple static PNG files to show different aspects of a plot. I'd rather send the figure object and have them interact with it themselves.
I just found out how to do this. The "experimental pickle support" mentioned by #pelson works quite well.
Try this:
# Plot something
import matplotlib.pyplot as plt
fig,ax = plt.subplots()
ax.plot([1,2,3],[10,-10,30])
After your interactive tweaking, save the figure object as a binary file:
import pickle
pickle.dump(fig, open('FigureObject.fig.pickle', 'wb')) # This is for Python 3 - py2 may need `file` instead of `open`
Later, open the figure and the tweaks should be saved and GUI interactivity should be present:
import pickle
figx = pickle.load(open('FigureObject.fig.pickle', 'rb'))
figx.show() # Show the figure, edit it, etc.!
You can even extract the data from the plots:
data = figx.axes[0].lines[0].get_data()
(It works for lines, pcolor & imshow - pcolormesh works with some tricks to reconstruct the flattened data.)
I got the excellent tip from Saving Matplotlib Figures Using Pickle.
As of Matplotlib 1.2, we now have experimental pickle support. Give that a go and see if it works well for your case. If you have any issues, please let us know on the Matplotlib mailing list or by opening an issue on github.com/matplotlib/matplotlib.
This would be a great feature, but AFAIK it isn't implemented in Matplotlib and likely would be difficult to implement yourself due to the way figures are stored.
I'd suggest either (a) separate processing the data from generating the figure (which saves data with a unique name) and write a figure generating script (loading a specified file of the saved data) and editing as you see fit or (b) save as PDF/SVG/PostScript format and edit in some fancy figure editor like Adobe Illustrator (or Inkscape).
EDIT post Fall 2012: As others pointed out below (though mentioning here as this is the accepted answer), Matplotlib since version 1.2 allowed you to pickle figures. As the release notes state, it is an experimental feature and does not support saving a figure in one matplotlib version and opening in another. It's also generally unsecure to restore a pickle from an untrusted source.
For sharing/later editing plots (that require significant data processing first and may need to be tweaked months later say during peer review for a scientific publication), I still recommend the workflow of (1) have a data processing script that before generating a plot saves the processed data (that goes into your plot) into a file, and (2) have a separate plot generation script (that you adjust as necessary) to recreate the plot. This way for each plot you can quickly run a script and re-generate it (and quickly copy over your plot settings with new data). That said, pickling a figure could be convenient for short term/interactive/exploratory data analysis.
Why not just send the Python script? MATLAB's .fig files require the recipient to have MATLAB to display them, so that's about equivalent to sending a Python script that requires Matplotlib to display.
Alternatively (disclaimer: I haven't tried this yet), you could try pickling the figure:
import pickle
output = open('interactive figure.pickle', 'wb')
pickle.dump(gcf(), output)
output.close()
Good question. Here is the doc text from pylab.save:
pylab no longer provides a save function, though the old pylab
function is still available as matplotlib.mlab.save (you can still
refer to it in pylab as "mlab.save"). However, for plain text
files, we recommend numpy.savetxt. For saving numpy arrays,
we recommend numpy.save, and its analog numpy.load, which are
available in pylab as np.save and np.load.
I figured out a relatively simple way (yet slightly unconventional) to save my matplotlib figures. It works like this:
import libscript
import matplotlib.pyplot as plt
import numpy as np
t = np.arange(0.0, 2.0, 0.01)
s = 1 + np.sin(2*np.pi*t)
#<plot>
plt.plot(t, s)
plt.xlabel('time (s)')
plt.ylabel('voltage (mV)')
plt.title('About as simple as it gets, folks')
plt.grid(True)
plt.show()
#</plot>
save_plot(fileName='plot_01.py',obj=sys.argv[0],sel='plot',ctx=libscript.get_ctx(ctx_global=globals(),ctx_local=locals()))
with function save_plot defined like this (simple version to understand the logic):
def save_plot(fileName='',obj=None,sel='',ctx={}):
"""
Save of matplolib plot to a stand alone python script containing all the data and configuration instructions to regenerate the interactive matplotlib figure.
Parameters
----------
fileName : [string] Path of the python script file to be created.
obj : [object] Function or python object containing the lines of code to create and configure the plot to be saved.
sel : [string] Name of the tag enclosing the lines of code to create and configure the plot to be saved.
ctx : [dict] Dictionary containing the execution context. Values for variables not defined in the lines of code for the plot will be fetched from the context.
Returns
-------
Return ``'done'`` once the plot has been saved to a python script file. This file contains all the input data and configuration to re-create the original interactive matplotlib figure.
"""
import os
import libscript
N_indent=4
src=libscript.get_src(obj=obj,sel=sel)
src=libscript.prepend_ctx(src=src,ctx=ctx,debug=False)
src='\n'.join([' '*N_indent+line for line in src.split('\n')])
if(os.path.isfile(fileName)): os.remove(fileName)
with open(fileName,'w') as f:
f.write('import sys\n')
f.write('sys.dont_write_bytecode=True\n')
f.write('def main():\n')
f.write(src+'\n')
f.write('if(__name__=="__main__"):\n')
f.write(' '*N_indent+'main()\n')
return 'done'
or defining function save_plot like this (better version using zip compression to produce lighter figure files):
def save_plot(fileName='',obj=None,sel='',ctx={}):
import os
import json
import zlib
import base64
import libscript
N_indent=4
level=9#0 to 9, default: 6
src=libscript.get_src(obj=obj,sel=sel)
obj=libscript.load_obj(src=src,ctx=ctx,debug=False)
bin=base64.b64encode(zlib.compress(json.dumps(obj),level))
if(os.path.isfile(fileName)): os.remove(fileName)
with open(fileName,'w') as f:
f.write('import sys\n')
f.write('sys.dont_write_bytecode=True\n')
f.write('def main():\n')
f.write(' '*N_indent+'import base64\n')
f.write(' '*N_indent+'import zlib\n')
f.write(' '*N_indent+'import json\n')
f.write(' '*N_indent+'import libscript\n')
f.write(' '*N_indent+'bin="'+str(bin)+'"\n')
f.write(' '*N_indent+'obj=json.loads(zlib.decompress(base64.b64decode(bin)))\n')
f.write(' '*N_indent+'libscript.exec_obj(obj=obj,tempfile=False)\n')
f.write('if(__name__=="__main__"):\n')
f.write(' '*N_indent+'main()\n')
return 'done'
This makes use a module libscript of my own, which mostly relies on modules inspect and ast. I can try to share it on Github if interest is expressed (it would first require some cleanup and me to get started with Github).
The idea behind this save_plot function and libscript module is to fetch the python instructions that create the figure (using module inspect), analyze them (using module ast) to extract all variables, functions and modules import it relies on, extract these from the execution context and serialize them as python instructions (code for variables will be like t=[0.0,2.0,0.01] ... and code for modules will be like import matplotlib.pyplot as plt ...) prepended to the figure instructions. The resulting python instructions are saved as a python script whose execution will re-build the original matplotlib figure.
As you can imagine, this works well for most (if not all) matplotlib figures.
If you are looking to save python plots as an interactive figure to modify and share with others like MATLAB .fig file then you can try to use the following code. Here z_data.values is just a numpy ndarray and so you can use the same code to plot and save your own data. No need of using pandas then.
The file generated here can be opened and interactively modified by anyone with or without python just by clicking on it and opening in browsers like Chrome/Firefox/Edge etc.
import plotly.graph_objects as go
import pandas as pd
z_data=pd.read_csv('https://raw.githubusercontent.com/plotly/datasets/master/api_docs/mt_bruno_elevation.csv')
fig = go.Figure(data=[go.Surface(z=z_data.values)])
fig.update_layout(title='Mt Bruno Elevation', autosize=False,
width=500, height=500,
margin=dict(l=65, r=50, b=65, t=90))
fig.show()
fig.write_html("testfile.html")

Categories

Resources