rstudio / reticulate

R Interface to Python
https://rstudio.github.io/reticulate
Apache License 2.0
1.68k stars 327 forks source link

"SyntaxError: invalid or missing encoding declaration" when using matplotlib #398

Open koverholt opened 5 years ago

koverholt commented 5 years ago

I'm getting a "SyntaxError: invalid or missing encoding declaration" when attempting to render an Rmarkdown document that uses matplotlib and the Agg backend (since I'm using a remote Linux machine).

The document renders fine on my local machine on macOS.

The error appears in RStudio on Linux whether I try to render with knit or execute the cell in an Rmarkdown notebook. And it works if I run it with the Python environment I am pointing to that contains numpy and matplotlib. If I remove the matplotlib code, then reticulate works with Python as expected.

OS: Ubuntu 14.04 R version: 3.4.4

Input Rmarkdown file:

---
title: "Python Error"
output: html_document
---

```{r setup, include=FALSE}
library(reticulate)
use_python("/opt/python/bin/python3", required = TRUE)
import matplotlib
matplotlib.use('Agg')
import matplotlib.pyplot as plt
import numpy as np

x = np.linspace(0, 1, 500)
y = np.sin(4 * np.pi * x) * np.exp(-5 * x)
fig, ax = plt.subplots()
ax.fill(x, y, zorder=10)
ax.grid(True, zorder=5)
plt.show()

Output when rendering with knit:

processing file: python-error.Rmd |................ | 25% ordinary text without R code

|................................ | 50% label: setup (with options) List of 1 $ include: logi FALSE

|................................................. | 75% ordinary text without R code

|.................................................................| 100% label: unnamed-chunk-1 (with options) List of 2 $ include: logi TRUE $ engine : chr "python"

Quitting from lines 12-24 (python-error.Rmd) Error in py_run_string_impl(code, local, convert) : SyntaxError: invalid or missing encoding declaration for '/opt/python/bin/python3'

Detailed traceback: File "", line 1, in File "/opt/python/lib/python3.4/site-packages/matplotlib/init.py", line 1407, in use stacklevel=2) File "/usr/lib/python3.4/warnings.py", line 18, in showwarning file.write(formatwarning(message, category, filename, lineno, line)) File "/usr/lib/python3.4/warnings.py", line 26, in formatwarning line = linecache.getline(filename, lineno) if line is None else line File "/usr/lib/python3.4/linecache.py", line 15, in getline lines = getlines(filename, module_globals) File "/usr/lib/python3.4/linecache.py", line 41, in getlines return updatecache(filename, module_globals) File "/usr/lib/python3.4/linecache.py", line 126, in updatecache with tokenize.open(fullname) as fp: File "/usr/lib/python3.4/tokenize.py", line 439, in open encoding, lines = detect_encoding(buffer.readline) File "/usr/lib/ Calls: ... force -> py_run_string -> py_run_string_impl -> .Call Execution halted



If I remove the `Agg` backend lines, then it complains about the display with `  TclError: couldn't connect to display ":0"` as expected since this is running remotely on a Linux machine.
kevinushey commented 5 years ago

Can you reproduce this error without reticulate? IIUC the error is occurring while attempting to initialize matplotlib.

koverholt commented 5 years ago

I cannot reproduce the error without reticulate.

If I run the Python script on the same Linux machine with the same Python version I point to above, it runs without any errors, and I can even add plt.savefig("python-error.png") and successfully get a rendered plot.

kevinushey commented 5 years ago

This error seems similar:

https://gist.github.com/grzegorz-siekaniec/238b32bebd42d16eb676#file-scikit-learn_issue_4664

I wonder if there are other errors in the stack trace that are being lost? (it looks like the output was truncated; not sure if that was done by reticulate or not)

koverholt commented 5 years ago

Agreed, it looks similar, and I saw some other issues about the stack trace being lost.

The puzzling part for me is that it runs fine in Python but fails in reticulate when trying to change to any matplotlib backend.