I'm trying to save the output of a ggplot2
R object created using rpy2
into a buffer controlled by Python.
I'm able to do this using matplotlib
but I cannot seems to do it with ggplot2 via rpy2
.
In matplotlib.pyplot
, this can be accomplished with:
import matplotlib.pyplot as plt
import io
import numpy
def test_save():
x = numpy.linspace(-5, 5)
y = 3*x + 2
fig = plt.figure()
plt.plot(x, f)
buf = io.BytesIO()
plt.savefig(buf, format = 'png')
return buf
ggplot2
attempt:
import io
import numpy
import rpy2.robjects as robjects
from pandas import DataFrame
import rpy2.robjects.lib.ggplot2 as ggplot2
def test_ggplot2_save():
x = numpy.linspace(-5, 5)
y = 3*x + 2
df = DataFrame({'x': x, 'y': y})
gp = ggplot2.ggplot(df)
pp = (gp
+ ggplot2.aes_string(x='x', y='y')
+ ggplot2.geom_point()
+ ggplot2.labs(title="MY DATA", x='x', y='y'))
# pp.plot()
buf = io.BytesIO()
robjects.r.ggsave(filename=buf, plot=pp, width=200, height=120, unit='mm')
Error:
NotImplementedError: Conversion 'py2ri' not defined for objects of type ''
I was trying to use the rpy2.robjects.lib.ggplot2.GGPlot.save
feature.
R's ggplot2::ggsave
is expecting a string specifying a path (relative or absolute) as an argument for the parameter filename
. For example "/this/is/my/figure.png"
.
A Python BytesIO
object is quite different. It is an in-memory binary stream (roughly Python object that behaves like a (binary) file).
If using ggsave
is not an absolute requirement, consider using
rpy2.robjects.lib.grdevices.render_to_bytesio()
. This is the function that makes the following display inline figures in the Jupyter notebook:
from rpy2.ipython.ggplot import image_png
# pp is your ggplot2 figure
display(image_png(pp))