0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 1 year has passed since last update.

Nimでmatplotlibが使いたい(matplotnim, nimpy)

Last updated at Posted at 2022-12-31

はじめに

ggplotnim, nim-plotly, graph, gnuplot.nim等々、Nimにもグラフ描画ライブラリは複数あります。今回は私が使い慣れているPythonのmatplotlibをNimで使う方法をまとめます。

matplotnim, nimpyとは

matplotnimはmatplotlibのNim版ラッパーライブラリです。
nimpyは、PythonからNim、並びにNimからPythonを呼ぶことを容易にするライブラリです。使用方法はNim初心者が始めるNimとnimpyなどを参考にしてください。

実行環境

Windows11 22H2
nim 1.6.10

matplotnim使用方法(エラー解消方法)

matplotnim自体がnimpyを用いているため、結局Pythonのインストールが必要となります。また、matplotnim公式もnimpyがあるので、自身が冗長であると言っています。 matplotnimを使用するメリットは、import文を使うことでよりPythonしてる感が出る程度です。 nimpyだけを用いる方法も後述します。

まず、nimbleからmatplotnimをダウンロードしましょう。

nimble install matplotnim

なおプログラム例は以下のようになります。

import matplotnim, nimpy # pltからの.呼出でnimpyが要る

let x = @[1, 2, 3, 4]
let y = @[5.5, 7.6, 11.1, 6.5]

discard plt.figure()
discard plt.plot(x, y)
discard plt.show()

さっそく実行すると、以下のエラーが出ました。

Python path configuration:
  PYTHONHOME = (not set)
  PYTHONPATH = (not set)
  program name = 'python'
  isolated = 0
  environment = 1
  user site = 1
  import site = 1
  sys._base_executable = 'c:\\code\\Nim\\matplotnim_test.exe'
  sys.base_prefix = 'C:\\anaconda3'
  sys.base_exec_prefix = 'C:\\anaconda3'
  sys.platlibdir = 'lib'
  sys.executable = 'c:\\code\\Nim\\matplotnim_test.exe'
  sys.prefix = 'C:\\anaconda3'
  sys.exec_prefix = 'C:\\anaconda3'
  sys.path = [
    'C:\\anaconda3\\python39.zip',
    '.\\DLLs',
    '.\\lib',
    'c:\\code\\Nim',
  ]
Fatal Python error: init_fs_encoding: failed to get the Python codec of the filesystem encoding
Python runtime state: core initialized
ModuleNotFoundError: No module named 'encodings'

Current thread 0x00006220 (most recent call first):
<no Python frame>
Error: execution of an external program failed: 'c:\code\Nim\matplotnim_test.exe '

同様のエラーから、PYTHONHOMEPYTHONPATHの環境変数を設定していないことが原因と知りました。Windows10のAnacondaで仮想環境にインストールしたパッケージがimportできない等を参考にして、PYTHONPATHには自作のライブラリを格納したパス、PYTHONHOMEには標準の Python libraries のパスを指定します。

PYTHONHOME=C:\anaconda3
PYTHONPATH=C:\anaconda3\Library\bin

私は上記のように設定しましが、Pythonのインストール状況によってまちまちだと思います。また、今回はmatplotlibを呼び出したいだけなのでPYTHONPATHの設定だけで動作すると思われます。

再起動して実行すると今度はこんなエラーが...

This application failed to start because it could not find or load the Qt platform plugin "windows"
in "".

Reinstalling the application may fix this problem.
Error: execution of an external program failed: 'c:\code\Nim\matplotnim_test.exe '

そもそもPython側で実行すると普通に動きます。

import matplotlib.pyplot as plt
print(plt.__file__) # C:\anaconda3\lib\site-packages\matplotlib\pyplot.py

x = [1, 2, 3, 4]
y = [5.5, 7.6, 11.1, 6.5]

plt.figure()
plt.plot(x, y)
plt.show()

Nim側とPython側では違うmatplotlibを呼び出しているかとも思いましたが、同じでした。

searchPlace.py
def searchPlace(lib):
  return lib.__file__ # アンダーライン始まり・2連続はNimだと多分無理
import matplotnim, nimpy

let place = pyImport("searchPlace").callMethod("searchPlace", plt).to(string)
echo place # C:\anaconda3\lib\site-packages\matplotlib\pyplot.py

調べたところ、同様のエラーを発見したので同じようにQT_PLUGIN_PATHを設定して再起動。

QT_PLUGIN_PATH=C:\anaconda3\Library\plugins

するとやっと表示することができました!
figure1.png

nimpyで同等の処理をする

ところで、matplotnimの実装は

matplotnim.nim
import nimpy

let plt* = pyImport("matplotlib.pyplot")

以上です。実際matplotnimをインストールする必要はあまり感じません。
先の章でmatplotlibをインストールしていなければ、nimpyをインストールしましょう。

nimble install nimpy

先ほどのプログラムを少し変更して実行します。エラー対応は先の章の通りにしましょう。

import nimpy
let plt = pyImport("matplotlib.pyplot")

let x = @[1, 2, 3, 4]
let y = @[5.5, 7.6, 11.1, 6.5]

discard plt.figure()
discard plt.plot(x, y)
discard plt.show()

こちらでも実行できました!
figure1.png

seq型が通るのであれば、ArraymancerのTensor型は通るのかと試しましたが、一度seq型にしないとダメなようです。

import nimpy, arraymancer
let plt = pyImport("matplotlib.pyplot")

let x = [1, 2, 3, 4].toTensor
let y = [5.5, 7.6, 11.1, 6.5].toTensor

discard plt.figure()
discard plt.plot(x.toSeq1D(), y.toSeq1D())
discard plt.show()

(更新) Windows起動時に表示されるメッセージへの対処法

QT_PLUGIN_PATHを設定すると、Windows起動時に以下のエラーメッセージが表示されてしまいます。
Ot_error.jpg

そのため、以下のようにプログラム上で環境変数を設定して、プログラム動作時だけ機能するようにしましょう。

import nimpy, arraymancer
let plt = pyImport("matplotlib.pyplot")

let x = [1, 2, 3, 4].toTensor
let y = [5.5, 7.6, 11.1, 6.5].toTensor

# import os # Nim上での設定は反映されないらしい
# putEnv("QT_PLUGIN_PATH", r"C:\anaconda3\Library\plugins")

let os = pyImport("os")
os.environ["QT_PLUGIN_PATH"] = r"C:\anaconda3\Library\plugins"
# discard os.putenv("QT_PLUGIN_PATH", r"C:\anaconda3\Library\plugins") # 若しくは

discard plt.figure()
discard plt.plot(x.toSeq1D(), y.toSeq1D())
discard plt.show()

まとめ

nimpyを使えばPythonのライブラリを簡単に使えることがわかりました。
描画系ライブラリは他にもあるので、自分に合うものを試していきたいです。

0
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?