よちよちpython

独習 python/Qpython/Pydroid3/termux/Linux

【matplotlib】SVG形式ファイルのグラフを扱ってみる

久しぶりの投稿。あまりプログラミングしないといろいろ忘れる。リハビリがてら…

今回は、matplotlibを使ってSVG形式のファイルでグラフを保存させてみます。
ついでに、JPG形式のグラフでも保存し、2つの形式のファイルサイズを測定します。

matplotlibで描いたグラフは、デフォルトではPNG形式の画像ファイルとして保存されます。拡張子をつければ他の形式でも保存出来ます。今回はJPGとSVGで保存。



実行環境

  • Android
  • Termux
  • Python3.9.6
  • Jupyter Notebook6.4.0
  • 外部ライブラリ
    • numpy、matplotlib



投稿内容

以下の手順を行う。

  1. ファイルサイズを測定する関数をPythonで作成
  2. matplotlibで適当にグラフを作成し、JPGとSVGの2つの形式で保存
  3. 1で作った関数で2つのファイルサイズを取得・表示



ファイルサイズを取得する関数

引数にファイルパスを渡すと、ファイル名とファイルサイズを返します。

import os

def get_filesize(fname):
    return fname, os.path.getsize(fname)



グラフをJPGとSVG形式で保存する

適当なグラフを作成し、2つの形式で保存する。

import numpy as np
import matplotlib.pyplot as plt

# ランダムなデータを生成
x = "a b c d e".split()
y = np.random.randint(1, 101, 5)

# プロット
plt.plot(x, y)

# グラフ画像保存
plt.savefig('fig1.jpg')
plt.savefig('fig1.SVG')

# グラフ表示
plt.show()

カレントディレクトリに2つのファイルが保存されます。

SVG形式のファイルはXML言語をベースにしたマークアップ言語で書かれたファイルで、Scalable Vector Graphics(スケーラブル・ベクター・グラフィックス)の略だそうです。
テキストファイルなのでメモ帳などで開くとコードが表示される。上で出来たSVGファイルは582行でした。

Jupyter Notebookでそのまま開くと次のようなコードが表示される。

<?xml version="1.0" encoding="utf-8" standalone="no"?> <!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" (以下省略



ブログなどに貼るにはコードをそのまま書けば良いらしい。試しに丸ごとコピペしてみる。SVGファイルのXMLコード582行を貼り付け。

↓コピペした。グラフが表示されるかな?

<?xml version="1.0" encoding="utf-8" standalone="no"?> <!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd"> <rdf:RDF xmlns:cc="http://creativecommons.org/ns#" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"> <cc:Work> <dc:type rdf:resource="http://purl.org/dc/dcmitype/StillImage"/> <dc:date>2021-11-21T12:52:59.459157</dc:date> <dc:format>image/svg+xml</dc:format> <dc:creator> <cc:Agent> <dc:title>Matplotlib v3.4.2, https://matplotlib.org/</dc> </cc:Agent> </dc:creator> </cc:Work> </rdf:RDF>



イケますね。ちゃんとグラフが表示されました。不要な部分がコードで表示されてしまっているようです。



グラフ画像ファイルの形式ごとのサイズ測定

最初に作った関数で2つの形式のグラフのサイズを測定、表示させます。

file1 = 'fig1.jpg'
file2 = 'fig1.SVG'

print(get_filesize(file1))
print(get_filesize(file2))
('fig1.jpg', 14594)
('fig1.SVG', 11884)

SVG形式の方がサイズが小さくなっている。

SVGファイルの開き方

ブラウザで開けます。URL窓にSVGファイルパスをコピペするなどして入力すると、file:///ファイルパス.SVGのように自動で変わり、グラフが表示されると思う。というか表現された。ちなみにGoogleChromeです。ブラウザによっては開けない場合もあるみたい。

SVGとは

Scalable Vector Graphics(スケーラブル・ベクター・グラフィックス)の略 。
JPGやPNG形式はいわばドット絵で、拡張して見るとドットがクローズアップされてボヤけたりします。それに対してSVG形式は点や線をコードで表現してあり、表示する際に演算を行っている為に拡張してもボヤけずクリアに見える、という所が利点だとか。ただし複雑な絵は表示が遅くなると。



XML言語で表現されているので、NumpyやOpenCVなどで直接配列をイジルような操作は出来ない。一旦JPGやPNGなどビットマップ形式のファイルに変換する必要がある。変換用のイカしたライブラリもあるのでしょうが、それはまたの機会に。



今回は以上です。