Как перенаправить / отобразить вывод Pyodide в браузере? - PullRequest
5 голосов
/ 13 июня 2019

Я недавно натолкнулся на проект Pyodide .

Я создал небольшую демонстрацию с использованием Pyodide, но хотя я потратил много времени на просмотр источника, онДля меня неясно (пока), как перенаправить вывод print из python (кроме изменения исходного кода CPython), а также как перенаправить вывод из matplotlib.pyplot в браузер.

Из исходного кода, FigureCanvasWasm имеет метод show() с соответствующим бэкэндом для отображения на холсте браузера - однако мне не ясно, как создать экземпляр этого класса и вызвать его метод show() или, еслиесть еще один более очевидный способ перенаправления графиков на холст.

Поэтому у меня следующие вопросы:

  1. Как перенаправить print() сообщения
  2. Как заставитьпиодид для построения в браузере фигур matplotlib?

Вот моя тестовая страница:

<!doctype html>
<meta charset="utf-8">
<html lang="en">
<html>
<head>
    <title>Demo</title>
    <script src="../../pyodide/build/pyodide.js"></script>
</head>
<body>
</body>
    <script type="text/javascript">
      languagePluginLoader.then(() => {
      pyodide.loadPackage(['matplotlib']).then(() => {
          pyodide.runPython(`
                  import matplotlib.pyplot as plt
                  plt.plot([1, 2, 3, 4])
                  plt.ylabel('some numbers')
                  #fig = plt.gcf()
                  #fig.savefig(imgdata, format='png')                  
                  print('Done from python!')`
          );
          //var image = pyodide.pyimport('imgdata');
          //console.log(image);
      });});

    </script>
<html>

1 Ответ

4 голосов
/ 19 июня 2019

Прежде всего, давайте посмотрим, сможем ли мы получить что-нибудь в браузере; например нормальная строка. Переменные Python хранятся в атрибуте pyodide.globals. Следовательно, мы можем взять оттуда объект python и поместить его в элемент <div> на странице.

<!doctype html>
<meta charset="utf-8">
<html>
<head>
    <title>Demo</title>
    <script src="../pyodide/pyodide.js"></script>
</head>
<body>
</body>
    <script type="text/javascript">
      languagePluginLoader.then(() => {
          pyodide.runPython(`my_string = "This is a python string." `);

          document.getElementById("textfield").innerText = pyodide.globals.my_string;
      });

    </script>

    <div id="textfield"></div>
<html>

Теперь, я думаю, мы можем сделать то же самое с фигурой Matplotlib. Ниже будет показано сохраненное изображение PNG в документе.

<!doctype html>
<meta charset="utf-8">
<html lang="en">
<html>
<head>
    <title>Demo</title>
    <script src="../pyodide/pyodide.js"></script>
</head>
<body>
</body>
    <script type="text/javascript">
      languagePluginLoader.then(() => {
      pyodide.loadPackage(['matplotlib']).then(() => {
          pyodide.runPython(`
                import matplotlib.pyplot as plt
                import io, base64

                fig, ax = plt.subplots()
                ax.plot([1,3,2])

                buf = io.BytesIO()
                fig.savefig(buf, format='png')
                buf.seek(0)
                img_str = 'data:image/png;base64,' + base64.b64encode(buf.read()).decode('UTF-8')`
          );

          document.getElementById("pyplotfigure").src=pyodide.globals.img_str

      });});

    </script>

    <div id="textfield">A matplotlib figure:</div>
    <div id="pyplotdiv"><img id="pyplotfigure"/></div>
<html>

Я еще не изучил backends.wasm_backend, так что это может позволить более автоматизированный способ вышеперечисленного.

...