アプリ版:「スタンプのみでお礼する」機能のリリースについて

python matplotlibで作ったグラフを.emfにする方法を教えてください.

python 3.8.3 windows10です.
以下のサイトを参考に.svg→.emfとしたいのですが,できません.どうすればいいでしょうか.
https://teratail.com/questions/236513

import subprocess
from matplotlib import pyplot as plt

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

plt.savefig("A.svg")

subprocess.call('"C:\Program Files\Inkscape\bin\inkscape.exe" A.svg -M A.emf',shell=True)
plt.show()

これは,A.emfというファイルが生成される認識でいいのでしょうか.
間違っているとすれば,inkscapeのパスです.ネットで調べていると,c:/program files/inkscape/inkscape.exeにexeファイルがありますが,私の場合,C:\Program Files\Inkscape\bin\inkscape.exeにあります.
これがおかしい原因でしょうか

ご回答よろしくお願いいたします.

質問者からの補足コメント

  • jupyter lab 上でエラーをはいてなかったので,回っているのかと思いましたが,anaconda prompt上で以下のようなエラーをはいていました.

    [I 19:29:50.434 LabApp] Saving file at /デスクトップ/concat/Untitled.ipynb
    ファイル名、ディレクトリ名、またはボリューム ラベルの構文が間違っています。

    おそらくパスがまちがっているのでしょうが,確かにここにあるんですけどね...
    なんででしょう.
    inkscape.comもC:\Program Files\Inkscape\binの中にあります.

    文字数の関係で続きを次の補足で投稿します

    No.1の回答に寄せられた補足コメントです。 補足日時:2020/11/15 21:51
  • subprocess.run("C:\Program Files\Inkscape\bin\inkscape.exe A.svg -M A.emf", shell=True, check=True)
    だと以下jupyter lab上で以下のエラーをはきました.

    ---------------------------------------------------------------------------
    CalledProcessError Traceback (most recent call last)
    <ipython-input-2-128abc5071a7> in <module>
    7 plt.savefig("A.svg")
    8
    ----> 9 subpr(省略)

    続く

      補足日時:2020/11/15 21:52
  • ~\anaconda3\lib\subprocess.py in run(input, capture_output, timeout, check, *popenargs, **kwargs)
    510 retcode = process.poll()
    511 if check and retcode:
    --> 512 raise CalledProcessError(retcode, process.args,
    513 output=stdout, stderr=stderr)
    514 return CompletedProcess(process.args, retcode, stdout, std..(省略)
    続く

      補足日時:2020/11/15 21:53
  • CalledProcessError: Command 'C:\Program Files\Inkscapein\inkscape.exe A.svg -M A.emf' returned non-zero exit status 1.

    です.

    結局,svg作ってinkscapeで手動で変換できたので,いいのですが,もやもやします...

    長くなり申し訳ありません.

      補足日時:2020/11/15 21:54
  • inkscapeのパスを通した状態でコマンドプロンプト上で,以下のコードを実行しましたがいずれもエラーがでました.

    inkscape A.svg -M A.emf
    Unknown option -M

    inkscape A.svg M A.emf
    ** (org.inkscape.Inkscape:3208): WARNING **: 00:42:30.905: Can't open file: C:\Users\kaito\M (doesn't exist)

    ** (org.inkscape.Inkscape:3208): WARNING **: 00:42:30.913: Can't open file: C:\Users\kaito\M (doesn't exist)

    続く

    No.2の回答に寄せられた補足コメントです。 補足日時:2020/11/16 00:44
  • へこむわー

    ink_file_open: 'C:\Users\kaito\M' cannot be opened!
    InkscapeApplication::document_open: Failed to open: C:\Users\kaito\M
    ConcreteInkscapeApplication::on_open: failed to create document!

    省略
    (org.inkscape.Inkscape:3208): Gtk-CRITICAL **: 00:42:34.104: gtk_distribute_natural_allocation: assertion 'extra_space >= 0' failed

    でした.
    -Mはなくて,Mも無理でって感じですね

    すみません,よろしくお願いいたします.

      補足日時:2020/11/16 00:46
  • へこむわー

    あ,/Mですね
    inkscape A.svg /M A.emf
    としましたが,やはり,
    ** (org.inkscape.Inkscape:17916): WARNING **: 00:48:35.000: Can't open file: \M (doesn't exist)
    ink_file_open: '\M' cannot be opened!
    InkscapeApplication::document_open: Failed to open: \M
    ConcreteInkscapeApplication::on_open: failed to create document!

    と似たようなエラーはきました.

    勝手にpath通して実行してみましたが,これが原因でしょうか

    続きます

      補足日時:2020/11/16 00:53
  • へこむわー

    コマンドプロンプト上で
    C:\Program Files\Inkscape\bin\inkscape.com A.svg -M A.emf
    と打ってみましたが,
    'C:\Program' は、内部コマンドまたは外部コマンド、
    操作可能なプログラムまたはバッチ ファイルとして認識されていません。のエラーがでたので,path通したのですが..

    どうすればいいでしょうか..

      補足日時:2020/11/16 00:54

A 回答 (4件)

1.0.1 があったのでインストールしてみたけど, 今のバージョンの inkscape で svg から emf にするならたぶん


inkscape --export-type=emf A.svg
ってしないといけないんだと思う. -M で指定するのはちょっと前の (0.92 とかの) バージョンっぽい. ベースネームまで変えたかったら
inkscape A.svg --output-filename=hoge.emf
のような感じ (この場合出力が emf なのはファイル名でわかるので --export-type=emf は付けなくてもいい).

ちなみにパスが通ってないときにはフルパスで書かないといけないんだけど, 今の場合はフルパスが空白を含むのでコマンドプロンプトで実行するときにも
"C:Program Files\Inkscape\bin\inkscape.com"
のようにダブルクォートを付けないといけないし, これにあわせるなら subprocess.run の引数も適切に (ダブルクォートを付けるように) 変えなきゃならない.

あと外部コマンドについてはオプションの解釈も含めて外部コマンドが処理する (cmd.exe は空白で切り分けるだけ) ので, 「-M」なのか「/M」なのかは使うコマンドに依存する>#2.
    • good
    • 1

> 勝手にpath通して実行してみましたが,これが原因でしょうか



いや、Path通したらそれで良いです。ただ、その場合、

C:\Program Files\Inkscape\bin\inkscape.com A.svg -M A.emf

じゃなくって、

inkscape.com A.svg /M A.emf

になるのかな。

'C:\Program' は、内部コマンドまたは外部コマンド、
操作可能なプログラムまたはバッチ ファイルとして認識されていません。'

と言うエラーは、ProgramとFilesの間にスペースがあるんで、「Program Files」ってひと続きの名前だ、って認識されてないんですよ。だから文字列として、

"C:\Program Files\Inkscape\bin\inkscape.com" A.svg -M A.emf

とかやったりしなきゃいけないのが、DOS窓のメンド臭いトコです。

ただし、パスを通してるのなら「完全パス」じゃなくって、inkscape.comだけでプログラム名として認識してくれる筈です。

となると、やっぱ問題はオプショナル引数の-Mがどうなってんのか、って事ですねぇ。

inkscape A.svg -M A.emf
Unknown option -M

でオプションだ、って認識されてるトコ見ると、一応ハイフン(-)使ってもいいのかな。
一回、

inkscape.com A.svg --export-emf=A.emf

でどうなるか、見てみてください。
    • good
    • 0

subprocess.run("C:\Program Files\Inkscape\bin\inkscape.com A.svg -M A.emf", shell=True, check=True)



だとどうなりますかね?

エラーメッセージは読んだけど、イマイチハッキリせんメッセージですねぇ(笑)。もちろん貴方のせいじゃないですけど。

ちょっともう一回確認しておきますが。

subprocessってのは、Python内部で端末(DOS窓)呼び出して実行するだけ、なんですよ。
極端に言うと、例えばPythonでWindows Media Playerを呼び出してお気に入りのアダルト動画を再生するような事も出来ます(笑)。これは端末が「ソフトウェアを呼び出して実行する」媒体だからだ、って事ですね。PythonはDOS窓とか端末呼び出してコマンドラインを文字列として送っているだけで、Python自体が何かしてるわけじゃあないんです。
つまり、例えば、Python全然関係なく、DOS窓起動して、

C:\Program Files\Inkscape\bin\inkscape.com A.svg -M A.emf

って打った時、特定のsvgがemfに変換されるかどうか、って事ですね。
こういう場合、端末で一回実験してみて、成功したらそのコマンドラインを「コピペして」Pythonのソースに貼っ付けます。DOS窓で実行されればPythonからsubprocess呼び出してやらせても成功する、って事がある意味保証されるんでね。
んで、実は気になってるのが・・・-Mってのがコマンドラインオプション、って言われるモノなんですが、形式がUNIXスタイルなんですよね〜。元ページにもそう書いてますが。
でもDOS窓だとオプションって/Mって書かなアカンかったんじゃないか・・・。そこで引っかかってるなら分かるんですが。
どーだったかなぁ。普段Linux使ってるんでWindows良く知らなくなってるんですが、ひょっとしたら-Mを/Mに直せば上手く動くかも・・・試してみてください。
この回答への補足あり
    • good
    • 0

> これは,A.emfというファイルが生成される認識でいいのでしょうか.



はい、いいです。

> これがおかしい原因でしょうか

いや、貴方の環境でそこに置いてあって、パスが正しいのなら問題は無い筈です。
ぶっちゃけ、書かれたコードには何も問題ないですけどね。
解決策の候補は次の2つ。

1. subprocess.callじゃなくってsubprocess.runを使ってみる。

subprocess.run("C:\Program Files\Inkscape\bin\inkscape.exe A.svg -M A.emf", shell=True, check=True)

に変えて試してみる。
ただし、WindowsでのInkscapeのコマンドラインの場合、inkscape.exeではなく、inkscape.comを使用しろ、と言う話があるので、

https://inkscape.paix.jp/manual/overview/cmdline/

inkscape.comの場所も一応確認してみること。

2. 実用的には別にPython上でのsvg->emf変換にこだわる必要はない。
InkscapeはキチンとGUIを備えたスタンドアロンプログラムなのだから。
結局、PythonからDOS窓等を経由して(これがprocessライブラリが行おうとしている事)、コマンドラインでInkscapeを起動し、変換を試みる、と言うのが

https://teratail.com/questions/236513

での目的なんだけど、svg作ってinkscapeで手動で変換しても結果は同じである。
この回答への補足あり
    • good
    • 0

お探しのQ&Aが見つからない時は、教えて!gooで質問しましょう!