在R Markdown文档中使用Python代码绘制matplotlib图表

17

能否使用Python matplotlib代码在RStudio中绘制图形?

例如以下Python matplotlib代码:

import numpy as np
import matplotlib.pyplot as plt

n = 256
X = np.linspace(-np.pi,np.pi,n,endpoint=True)
Y = np.sin(2*X)

plt.plot (X, Y+1, color='blue', alpha=1.00)
plt.plot (X, Y-1, color='blue', alpha=1.00)
plt.show()

输出的图形将是:

enter image description here

然后我需要编写R Markdown,将这些代码包含进去,并在编织Markdown后自动生成图形。


R可以轻松完成这个任务,为什么还需要使用Python呢! - lucky1928
@lucky1928 这只是一个例子,Python可以做很多其他不适合R的事情。 :-) - beetlej
5个回答

18
  1. 首先安装devtools包:install.packages('devtools'),然后获取install_github函数。
  2. 安装reticulate的开发版本:install_github("rstudio/reticulate")。
  3. 在R Markdown文档中使用以下代码启用该功能。
```{r setup, include=FALSE}  
library(knitr)  
library(reticulate)  
knitr::knit_engines$set(python = reticulate::eng_python)  
```

尝试一下,你会得到想要的东西,并且不需要保存任何图片。

Imgur


代码在R Markdown文档中,正如问题所要求的那样。 - jtianling

13

一个可能的解决方案是将绘图保存为图片,然后将文件加载到Markdown中。

### Call python code sample
```{r,engine='python'}
import numpy as np
import matplotlib.pyplot as plt

n = 256
X = np.linspace(-np.pi,np.pi,n,endpoint=True)
Y = np.sin(2*X)

fig, ax = plt.subplots( nrows=1, ncols=1 )
ax.plot (X, Y+1, color='blue', alpha=1.00)
ax.plot (X, Y-1, color='blue', alpha=1.00)
#plt.show()
fig.savefig('foo.png', bbox_inches='tight')
print "finished"
```
Output image:
![output](foo.png)

#### The End

输出:

在这里输入图片描述


今天我尝试使用knitr中的hooks来使这个解决方案更加自动化,但问题在于hooks是用R编写的,因此似乎无法访问Python代码。也许有一种方法可以在最后编写一些Python代码。 - Mark Adamson
1
现在,2018年,您可以在Rmarkdown中插入Python代码。要使用matplotlib绘制图形,您只需要添加plt.show即可。 - user989762

3
你可以使用reticulate来实现这个,但是在尝试教程时,你可能会遇到一些技术问题,而这些问题没有得到充分的解释。
我的回答可能有点晚,但我希望它能彻底地指导你正确地完成操作——不是将其呈现并加载为png文件,而是更加“本地”地执行Python代码。
步骤1:从RStudio配置Python
你需要插入一个R代码块,并运行以下代码来配置你想要使用的Python版本的路径。大多数操作系统默认的python通常是过时的Python 2,也不是你安装包的位置。这就是为什么这很重要的原因,确保Rstudio将使用指定的Python实例,你的matplotlib库(以及你将用于该项目的其他库)可以被找到:
library(reticulate)
# change the following to point to the desired path on your system
use_python('/Users/Samuel/anaconda3/bin/python')
# prints the python configuration
py_config()

您应该期望看到会话已经按照您指定的设置进行了配置:

python:         /Users/Samuel/anaconda3/bin/python
libpython:      /Users/Samuel/anaconda3/lib/libpython3.6m.dylib
pythonhome:     /Users/Samuel/anaconda3:/Users/Samuel/anaconda3
version:        3.6.3 |Anaconda custom (64-bit)| (default, Oct  6 2017, 12:04:38)  [GCC 4.2.1 Compatible Clang 4.0.1 (tags/RELEASE_401/final)]
numpy:          /Users/Samuel/anaconda3/lib/python3.6/site-packages/numpy
numpy_version:  1.15.2

python versions found: 
 /Users/Samuel/anaconda3/bin/python
 /usr/bin/python
 /usr/local/bin/python
 /usr/local/bin/python3
 /Users/Samuel/.virtualenvs/r-tensorflow/bin/python

步骤2:熟悉的plt.show

在您的R Markdown文档中添加一个Python代码块(不是R!)(请参见附加的屏幕截图),您现在可以编写原生的Python代码。这意味着熟悉的plt.show()plt.imshow()将无需任何额外的工作即可工作。它将被渲染并可以使用knitr编译为HTML / PDF。

这将有效:

plt.imshow(my_image, cmap='gray') 

或者一个更加详细的例子:

import numpy as np
import matplotlib.pyplot as plt
import os
import cv2

DATADIR = '/Users/Samuel/Datasets/PetImages'
CATEGORIES = ['Dog', 'Cat']

for category in CATEGORIES:
    path = os.path.join(DATADIR, category) # path to cat or dog dir
    for img in os.listdir(path):
        img_array = cv2.imread(os.path.join(path,img), cv2.IMREAD_GRAYSCALE)
        plt.imshow(img_array, cmap='gray')
        plt.show()
        break
    break

输出: enter image description here 步骤3:转化为HTML / PDF / Word等格式
按照惯例进行转换,最终产品是使用R Markdown编写的Python代码美观格式化的文档。RStudio已经发展了很长一段时间,我惊讶于它对Python代码的支持程度不为人知,因此希望任何看到这个答案的人都能从中获得有益信息并学到新内容。 enter image description here

2

我一直在使用reticulate和R Markdown,你需要指定虚拟环境。例如,我的R Markdown如下:

{r setup, include=FALSE}
knitr::opts_chunk$set(echo = TRUE, warning = FALSE, cache.lazy = FALSE)
library(reticulate)

use_condaenv('pytorch') ## yes, you can run pytorch and tensor flow too

那么你可以使用任意一种语言进行工作。所以,对于使用matplotlib绘图,我发现你需要PyQt5模块才能使其运行顺畅。以下代码可以在R Markdown中生成漂亮的图表 - 它是一个独立的代码块。

{python plot}
import PyQt5
import numpy as np
import pandas as pd
import os

import matplotlib.pyplot as plt
from matplotlib.pyplot import figure

data = pd.read_csv('Subscriptions.csv',index_col='Date', parse_dates=True)

# make the nice plot
# set the figure size
fig = plt.figure(figsize = (15,10))

# the series
ax1 = fig.add_subplot(211)
ax1.plot(data.index.values, data.Opens, color = 'green', label = 'Opens')

# plot the legend for the first plot
ax1.legend(loc = 'upper right', fontsize = 14)

plt.ylabel('Opens', fontsize=16)

# Hide the top x axis
ax1.axes.get_xaxis().set_visible(False)

#######  NOW PLOT THE OTHER SERIES ON A SINGLE PLOT

# plot 212 is the MI series

# plot series
ax2 = fig.add_subplot(212)
ax2.plot(data.index.values, data.Joiners, color = 'orange', label = 'Joiners')

# plot the legend for the second plot
ax2.legend(loc = 'upper right', fontsize = 14)

# set the fontsize for the bottom plot
plt.ylabel('Joiners', fontsize=16)

plt.tight_layout()
plt.show()

你可以从中获得以下内容: enter image description here

0

我没有足够的声望点来添加评论,但Bryan上面的答案是唯一对我有用的。添加plt.tight_layout()使得区别。我将该行代码添加到以下简单代码中,然后绘图显示出来了。

{python evaluate}

plt.scatter(X_train, y_train, color = 'gray')
plt.plot(X_train, regresssion_model_sklearn.predict(X_train), color = 'red')
plt.ylabel('Salary')
plt.xlabel('Number of Years of Experience')
plt.title('Salary vs. Years of Experience')

plt.tight_layout()
plt.show()


这并没有回答问题。一旦您拥有足够的声望,您将能够评论任何帖子;相反,提供不需要询问者澄清的答案。- 来自审核 - Mad Physicist

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接