1. ホーム
  2. python

[解決済み] matplotlib のプロットの出力を SVG として取得するにはどうしたらいいですか?

2023-01-12 14:18:22

質問

matplotlibのプロットの出力を、レーザーカッターで使用できるSVGパスに変換する必要があります。

import matplotlib.pyplot as plt
import numpy as np
x = np.arange(0,100,0.00001)
y = x*np.sin(2*pi*x)
plt.plot(y)
plt.show()

例えば、下に波形があります。 この波形をSVGパスとして出力または保存して、後でAdobe Illustratorなどのプログラムで作業できるようにしたいと思います。

私は、matplotlib が使用できる "Cairo" と呼ばれる SVG ライブラリを知っています ( matplotlib.use('Cairo') という SVG ライブラリを知っていますが、matplotlib がプロットを生成するために Cairo を使用しているにもかかわらず、このライブラリによって私が必要とする SVG パスにアクセスできるかどうかは、私には明らかではありません。

私のシステムでは cairo が動作しており、Illustrator で編集できる SVG パスで構成された例をうまく描くことができますが、上の式を SVG パスに取り込む方法がありません。

import cairo
from cairo import SVGSurface, Context, Matrix    
s = SVGSurface('example1.svg', WIDTH, HEIGHT)
c = Context(s)

# Transform to normal cartesian coordinate system
m = Matrix(yy=-1, y0=HEIGHT)
c.transform(m)

# Set a background color
c.save()
c.set_source_rgb(0.3, 0.3, 1.0)
c.paint()
c.restore()

# Draw some lines
c.move_to(0, 0)
c.line_to(2 * 72, 2* 72)
c.line_to(3 * 72, 1 * 72)
c.line_to(4 * 72, 2 * 72)
c.line_to(6 * 72, 0)
c.close_path()
c.save()
c.set_line_width(6.0)
c.stroke_preserve()
c.set_source_rgb(0.3, 0.3, 0.3)
c.fill()
c.restore()

# Draw a circle
c.save()
c.set_line_width(6.0)
c.arc(1 * 72, 3 * 72, 0.5 * 72, 0, 2 * pi)
c.stroke_preserve()
c.set_source_rgb(1.0, 1.0, 0)
c.fill()
c.restore()

# Save as a SVG and PNG
s.write_to_png('example1.png')
s.finish()

<イグ

(ここで表示される画像はpngであることに注意してください。stackoverflowは表示用のsvgグラフィックを受け付けないからです)

どのように解決するのですか?

画像サイズを固定し、あらゆる種類の背景や軸マーカーを取り除くことが最も重要でしょう。

import matplotlib.pyplot as plt
import numpy as np

plt.figure(figsize=[6, 6])
x = np.arange(0, 100, 0.00001)
y = x*np.sin(2* np.pi * x)
plt.plot(y)
plt.axis('off')
plt.gca().set_position([0, 0, 1, 1])
plt.savefig("test.svg")

出来上がったSVGファイルには、余分な要素が1つだけ含まれています。 savefig は本当に図の背景を保存したいのです。この背景の色は 'none' に変更するのは簡単ですが、取り除くことはできないようです。とにかく、SVG はそれ以外は非常にきれいで、正しいスケール (単位は 1/72") になっています。