#python #r #imagemagick #rpy2
#python #r #imagemagick #rpy2
Вопрос:
Я создаю график в R, но затем пытаюсь вернуть результирующие данные изображения в Python, чтобы Python мог отобразить изображение.
В R я использовал magick
библиотеку для хранения изображения в памяти (вместо вывода на экран).
«Мы используем
image_write
для экспорта изображения в любом формате в файл на диске или в памяти, еслиpath = NULL
«
Я не уверен, как обрабатывать SexpExtPtr
ByteVector
типы or, которые возвращаются rpy2
в Python.
import rpy2.robjects as ro
r = ro.r
r('''
library("magick")
figure <- image_graph(width = 400, height = 400, res = 96)
plot(c(1,2,3))
image <- image_write(figure, path = NULL, format = "png")
# image_write(figure, path = 'example.png', format = 'png')
''')
figure = ro.globalenv['figure']
image = ro.globalenv['image']
im = Image.open(BytesIO(image))
Приведенный выше код выдает ошибку:
Traceback (most recent call last):
File "stackoverflow.py", line 23, in <module>
im = Image.open(BytesIO(image))
TypeError: a bytes-like object is required, not 'ByteVector'
В Python:
figure
имеет тип<class 'rpy2.rinterface.SexpExtPtr'>
image
имеет тип<class 'rpy2.robjects.vectors.ByteVector'>
Ответ №1:
Итак … оказывается, что <class 'rpy2.robjects.vectors.ByteVector'>
это итеративно, и я могу использовать bytes()
для построения массива байтов.
Кроме того, поместив код в функцию, которая использует return
для возврата изображения PIL, я могу получить изображение для отображения в записной книжке Jupyter (в качестве альтернативы мы могли бы просто сделать image.show()
)
from io import BytesIO
import PIL.Image as Image
import rpy2.robjects as ro
def main():
r = ro.r
r('''
library("magick")
figure <- image_graph(width = 400, height = 400, res = 96)
plot(c(1,2,3))
image <- image_write(figure, path = NULL, format = "png")
image_write(figure, path = 'example.png', format = 'png')
''')
image_data = ro.globalenv['image']
image = Image.open(BytesIO(bytes(image_data)))
return image
if __name__ == '__main__':
image = main()
image.show()
Комментарии:
1. rpy2 делает все списки R, векторы, массивы итеративными из Python. В дополнение к этому несколько типов массивов совместимы между R и Python, и для них существуют более эффективные решения. Например, ваш объект
image
будет реализовывать интерфейс массива numpy ( numpy.org/doc/stable/reference/arrays.interface.html ). Это позволит вам использовать ускорение C с совместимым пакетом (например,numpy.array
, илиnumpy.asarray
).