linuxBean14.04(86)AnacondaのパッケージをLibreOfficeマクロで使う

前の関連記事:linuxBean14.04(85)Eclipse Mars 4.5.1で横スクロールすると字が滲む


LibreOfficeのマクロからlinuxBean14.04(72)Anacondaで科学技術系Pythonパッケージを一括インストールするのAnacondaのパッケージが使えるようにします。
(2017.3.18追記。 LibreOffice5.2のPython3.5.0で同じことをやってみましたがうまくいきませんでした。soファイルのモジュールのインポートに失敗します。linuxBean14.04(150)AnacondaとJupyter NotebookとLibreOffice5.2(失敗編)参照。 )

LibreOffice5.0.2のバンドルPythonのバージョンを確認する


LibreOfficeのPythonマクロとして動かしたいのでPythonのバージョンを揃えておきます。

まずLibreOffice5.0.2のバンドルPythonのバージョンを確認します。

すでにlinuxBean14.04(83)LibreOfiice5.0.2のインストールでPyCharmのインタプリタに/opt/libreoffice5.0/program/pythonを指定して3.3.5と知っていますが、モジュール検索パスも知りたいのでLibreOffice(29)Pythonインタプリタの置き換えは断念のversion_check.pyを使うことにします。
#!/opt/libreoffice5.0/program/python
# -*- coding: utf-8 -*-
# version_check.py
import sys
def version_check():
    oDoc = XSCRIPTCONTEXT.getDocument()
    oText="Pythonインタプリタのバージョン\n"+sys.version+"\n\n"
    oText=oText+"Pythonインタプリタの絶対パス\n"+sys.executable+"\n\n"
    oText=oText+"Pythonモジュール検索パス\n"+"\n".join(sys.path)
    oDoc.getText().setString(oText)
if __name__ == "__main__":
    import unopy
    XSCRIPTCONTEXT = unopy.connect()
    if not XSCRIPTCONTEXT:
        print("Failed to connect.")
        sys.exit(0)
    version_check()
このversion_check.pyをlinuxBean14.04(6)LibreOffice4.3.7とPyCharmの設定で作ったマイマクロフォルダ(~/.config/libreoffice/4/user/Scripts/python)に置きます。

LibreOffice Writerを起動します。

ツール→マクロ→マクロの管理→Pythonでマイマクロにあるversion_checkを実行します。
Pythonインタプリタのバージョン
3.3.5 (default, Sep 18 2015, 12:43:29) 
[GCC 4.8.2 20140120 (Red Hat 4.8.2-15)]

Pythonインタプリタの絶対パス
/usr/bin/python3

Pythonモジュール検索パス
/opt/libreoffice5.0/program/python-core-3.3.3/lib
/opt/libreoffice5.0/program/python-core-3.3.3/lib/lib-dynload
/opt/libreoffice5.0/program/python-core-3.3.3/lib/lib-tk
/opt/libreoffice5.0/program/python-core-3.3.3/lib/site-packages
/opt/libreoffice5.0/program
/home/pq
/opt/libreoffice5.0/program/python-core-3.3.3/lib/python33.zip
/opt/libreoffice5.0/program/python-core-3.3.3/lib/python3.3
/opt/libreoffice5.0/program/python-core-3.3.3/lib/python3.3/plat-linux
/opt/libreoffice5.0/program/python-core-3.3.3/lib/python3.3/lib-dynload
/home/pq/.local/lib/python3.3/site-packages
/usr/lib/python3.3
/usr/lib/python3.3/plat-i386-linux-gnu
/usr/lib/python3.3/lib-dynload
/usr/local/lib/python3.3/dist-packages
/usr/lib/python3/dist-packages
/opt/libreoffice5.0/share/extensions/dict-en/pythonpath
モジュールの検索パスの20行目から24行目はlinuxBean14.04(38)LibreOfficeバンドルPythonにパッケージを追加で~/.local/lib/python3.3/site-packages/sites.pthで追加したものですので、sites.pthを設定してなければこれらの行はでてきません。

最後の1行は一回目の実行では出てきませんが、二回目以降に出現してきます。

Pythonインタプリタの絶対パスはsys.executableで取得しているのですが、想定に反してシステムPythonのパスが返っています。

Terminalで実行してみると/usr/bin/python3はPython 3.4.3になっていますのでsys.versionと整合性がありませんがそうなる理由は不明です。

PyCharmから実行したオートメーションではPythonインタプリタの絶対パスは想定通り /opt/libreoffice5.0/program/python.binが返ってきます。

Anaconda3のPython3.3.5をインストールする


linuxBean14.04(72)Anacondaで科学技術系Pythonパッケージを一括インストールするでやった通りです。

conda create -n py335 python=3.3.5 anaconda

conda env listでインストールした環境一覧の取得ができます。
pq@pq-VirtualBox:~$ conda env list
# conda environments:
#
py335                    /home/pq/anaconda3/envs/py335
root                  *  /home/pq/anaconda3
py335が環境名なのでアンインストールするときはconda remove --name py335 --allでできます。

インタプリタへの絶対パスは~/anaconda3/envs/py335/bin/pythonになります。

Anaconda3のパッケージをLibreOfficeのマクロで使えるようにする


linuxBean14.04(38)LibreOfficeバンドルPythonにパッケージを追加と同様にしてこの環境のパッケージにアクセスできるようにsites.pthファイルを作成することにします。
pq@pq-VirtualBox:~$ ~/anaconda3/envs/py335/bin/python
Python 3.3.5 |Anaconda 2.3.0 (32-bit)| (default, Jun  4 2015, 15:23:08) 
[GCC 4.4.7 20120313 (Red Hat 4.4.7-1)] on linux
Type "help", "copyright", "credits" or "license" for more information.
>>> import sys
>>> sys.path
['', '/home/pq/anaconda3/envs/py335/lib/python33.zip', '/home/pq/anaconda3/envs/py335/lib/python3.3', '/home/pq/anaconda3/envs/py335/lib/python3.3/plat-linux', '/home/pq/anaconda3/envs/py335/lib/python3.3/lib-dynload', '/home/pq/.local/lib/python3.3/site-packages', '/home/pq/anaconda3/envs/py335/lib/python3.3/site-packages', '/home/pq/anaconda3/envs/py335/lib/python3.3/site-packages/Sphinx-1.3.1-py3.3.egg', '/home/pq/anaconda3/envs/py335/lib/python3.3/site-packages/cryptography-0.9.1-py3.3-linux-i686.egg', '/home/pq/anaconda3/envs/py335/lib/python3.3/site-packages/setuptools-17.1.1-py3.3.egg']
このsys.pathの結果を順番を変えないようにして1行ずつ書き出します。

/home/pq/anaconda3/envs/py335/lib/python33.zip
/home/pq/anaconda3/envs/py335/lib/python3.3
/home/pq/anaconda3/envs/py335/lib/python3.3/plat-linux
/home/pq/anaconda3/envs/py335/lib/python3.3/lib-dynload
/home/pq/anaconda3/envs/py335/lib/python3.3/site-packages
/home/pq/anaconda3/envs/py335/lib/python3.3/site-packages/Sphinx-1.3.1-py3.3.egg
/home/pq/anaconda3/envs/py335/lib/python3.3/site-packages/cryptography-0.9.1-py3.3-linux-i686.egg
/home/pq/anaconda3/envs/py335/lib/python3.3/site-packages/setuptools-17.1.1-py3.3.egg
/home/pq/.config/libreoffice/4/user/Scripts/python

/home/pq/.local/lib/python3.3/site-packagesはsites.pthのフォルダを指定しているので省略しました。

/home/pqをチルダ~に置換すると認識されませんでしたので「pq」の部分は各々ユーザー名で置換してください。

最後に追加してある/home/pq/.config/libreoffice/4/user/Scripts/pythonはLibreOffice5のマイマクロフォルダのルートパスです。

あとでIPython NotebookからLibreOfficeのオートメーションをするときに便利なので追加しました。

~/.local/lib/python3.3/site-packages/sites.pthをこれらのパスに書き換えます。

これで/opt/libreoffice5.0/program/pythonからanacondaのパッケージが使えるようになったはずです。

まずnumpyが使えるかどうか試してみましょう。

Writerからマクロを呼び出します。
#!/opt/libreoffice5.0/program/python
# -*- coding: utf-8 -*-
import numpy as np
def Test_Writer():
    data = np.outer(range(10), range(1, 5))
    doc = XSCRIPTCONTEXT.getDocument()
    doc.getText().setString(str(data))
if __name__ == "__main__":
    import unopy
    XSCRIPTCONTEXT = unopy.connect()
    if not XSCRIPTCONTEXT:
        print("Failed to connect.")
        import sys
        sys.exit(0)
    Test_Writer()

マクロでもオートメーションでも動きました。(マクロとオートメーションについてはLibreOffice(5)PythonでLibreOfficeが動く仕組み:UNOへ。)

pandasも使えました。
#!/opt/libreoffice5.0/program/python
# -*- coding: utf-8 -*-
import matplotlib.pyplot as plt
import numpy as np
def Test_Writer():
    data = np.outer(range(10), range(1, 5))
    fig, ax = plt.subplots()
    ax.plot(data)
    plt.show()
    doc = XSCRIPTCONTEXT.getDocument()
    doc.getText().setString(str(data))
if __name__ == "__main__":
    import unopy
    XSCRIPTCONTEXT = unopy.connect()
    if not XSCRIPTCONTEXT:
        print("Failed to connect.")
        import sys
        sys.exit(0)
    Test_Writer()
これでmatplotlibのプロットのウィンドウもでてきました。

オートメーションよりもマクロの方が圧倒的にプロットが速いです。

余談ですが、以前からJupyter Notebookでプロットするときに比べてシステムPythonでのプロットの描画が遅いのが不思議で、Jupyter Notebookではウィンドウを描く必要がないからだ、と考えていましたがオートメーションでも速くプロットが出せるのでそういう理由ではないようですね。

PyCharmから起動しているせい?

次の関連記事:linuxBean14.04(87)ipynbファイルをnbconvertするシェルスクリプト

PR

3 件のコメント:

  1. 関連の質問を、teratail でしました。
    https://teratail.com/questions/20184

    返信削除
    返信
    1. この記事でやっていることはその質問先で回答されているように単にパスを追加しているだけなのですが、、、

      いちいち手動で追加するのは面倒なのでsites.pthに追加するパスを書いて自動で読み込ませています。

      システムPythonのpipでモジュール管理したい場合はlinuxBeanやUbuntuであればlinuxBean14.04(3)LibreOfficeをPPAからインストールでやったようにPPAもしくはlinuxBean設定ウィザードからLibreOfficeをインストールすればシステムPythonでマクロが動くようにビルドされたLibreOfficeがインストールされます。

      ただその場合であってもAnacondaのモジュールを使いたいときはこの記事と同様にsites.pthの設定が必要です。

      AnacondaのPythonインタープリタでマクロを動かしたい場合は、そうなるようにLibreOfficeをビルドし直せばよいようですが、私はC++の経験乏しく挑戦していません。

      Replacing the python runtime with your system's python installationに解説があります。

      Windowsの場合はそもそもシステムPythonがないので、バンドルPython以外のインタープリタを使おうという場合はすべて自分で使いたいPythonでマクロが動くようにLibreOfficeをビルドし直さないといけません。

      マクロではなくオートメーションでLibreOfficeを操作するだけならバンドルPythonにこだわる必要はないと思います。

      ただその場合はLibreOffice(5)PythonでLibreOfficeが動く仕組み:UNOで書いているように相当実行速度が遅くなります。

      私の場合は最終的にWindowsで動くマクロを作らないといけないのでバンドルPythonとわざわざバージョンを一致させているだけです

      Windowsでの開発はLibreOffice(18)setsdkenv_windows.batを修正するでやったようにデフォルトパスに空白や括弧が含まれていることへの対策を逐一しないといけないのでかなり面倒どころかやる気が失せてやめてしまいました。

      削除
    2. 丁寧な返信ありがとうございました。私も、最終的には、windows で使うので、これからもよろしくおねがいします。しばらくは、教えてもらう一方ですが、よろしくおねがいします。関連情報は、qiita にためていきます。http://qiita.com/zanjibar/items/fa4d4c690cd07828d4f9

      削除