CPUとメモリ消費量の3次元グラフをぐりぐり動かす
matplotlibの3次元グラフ描いてみたい!そしてグラフをアニメする機能があるらしいのでぐりぐり動かしたい!
1. WindowsでCPUとメモリの消費量を取得する。
ぐりぐりリアルタイムで動かすデータと言えばCPUとメモリ消費量が気軽でいいかな。Windowsではちょうどいいコマンドが用意されていないので探したらPythonのモジュールでちょうどいいのがあった。
psutil -
A cross-platform process and system utilities module for Python - Google Project Hosting
プロセスとシステムの使用量(CPU, disk, memory, network)を取得できる。
しかもLinux, Windows, OSX,FreeBSDに対応!32bitでも64bitでも!頼もしい!
(1) システムのCPU使用量(%)
import psutil
psutil.cpu_percent(interval=0.1, percpu=False)
- intervalはCPU割り当て時間の計測期間
- CPU割り当て時間 / 経過時間 * 100
- interval=0.0 の場合は前回にこのメソッドが呼び出され時から計測
- percpuは複数CPUある場合の挙動
- Falseの場合は結果は1個にまとめられる。(上限は100%)
- Trueの場合は結果はCPUの個数分、リストで出力される。
(2) システムの物理メモリ使用量(%)
import psutil
psutil.used_phymem()
(3) プロセスのCPU使用量・メモリ使用量
import psutil # プロセスIDからProcessオブジェクトを生成 p = psutil.Process(pid) # CPU使用量(%) # interval引数の使い方は(1)と同様 # CPUが複数個の場合はCPU個数*100が上限となる p.get_cpu_percent(interval=0.0) # メモリ使用量(%) p.get_memory_percent()
2.3次元グラフを動かす
(1) 3次元のグラフ描画
from mpl_toolkits.mplot3d import Axes3D import numpy as np import matplotlib.pyplot as plt # Axes3DSubplotを取得 fig = plt.figure() ax = fig.gca(projection='3d') # 直線をプロット x = [i for i in range(10)] y = [i for i in range(10)] z = [i for i in range(10)] line, = ax.plot(x, y, zs=np.array(z), zdir='z') plt.show()
(2) グラフを動かす
matplotlib.animationのFuncAnimation関数を使用する。
import matplotlib.animation as animation line_ani = animation.FuncAnimation(fig, update_line, frames=360, fargs=(line, ax), interval=100, blit=False) plt.show()
引数
fig | Figureオブジェクト |
func | グラフを更新する関数。この関数の1個目の引数は現在のフレーム数が渡される。 |
frames | 描画するフレーム数 |
fargs | funcに渡す引数 |
interval | グラフを更新する間隔 |
blit | 描画するグラフを最適化するかどうか(?) |
グラフを更新する関数の例
def update_line(num, line, ax): # ラインの更新 # x軸、y軸、z軸それぞれに値リストをセットする。(伸びてく直線) line.set_xdata([i for i in range(num)]) line.set_ydata([i for i in range(num)]) line.set_3d_properties([i for i in range(num)]) # グラフ全体を回転 ax.view_init(30, 1 * num)
3.作ったスクリプト
psutil と matplotlib を使用してシステム・プロセスの3次元グラフ(x軸:メモリ使用量、y軸:時間、z軸:CPU使用量)をリアルタイムで描画するスクリプト。
This is a script which draws the amount of CPU used and memory usage of a process to a 3D graph. — Gist
(GitHubのGistを使ってみた。初回保存時、ログオンし忘れててAnonymousになってしまった……。)
全「???48」を生成してみる
課題1
- 大文字のアルファベット3文字 + '48' の全パターンのリストを作る
解答 その1
単純にループの入れ子で
# まず大文字のアルファベットのリストを作る al = [chr(a) for a in range(65, 91)] # 全パターンのジェネレータ def akb(): for a1 in al: for a2 in al: for a3 in al: yield a1 + a2 + a3 + '48' # リストで取得 allptns = [p for p in akb()] allptns.index('AKB48') #=> 本家は261番目に出てきた
解答 その2
リスト内包表記の入れ子
# al は大文字アルファベットのリスト # 全パターンのリスト allPtns = [a1 + a2 + a3 + '48' for a1 in al for a2 in al for a3 in al]
解答その3
アルファベットの桁数を指定できるようにしてみる
# al は大文字アルファベットのリスト # 2個のリストを組み合わせる関数 getprd = lambda list1, list2 : [a1 + a2 for a1 in list1 for a2 in list2] # 全パターンのリストを生成する関数 def akb(num): temp = [''] def _akb(tl, n): if n == 0: return getprd(tl, ['48']) else: return _akb(getprd(tl, al), n - 1) return _akb(temp, num) allPtns = akb(3)
なんかいまいちだなー。もっとかっこよい解答求む。
課題2
課題1に制限を加える
アルファベット3文字は別々のアルファベットを使う(AAAとかAABはダメ)
解答
課題1の解答3のリストを組み合わせる関数(getprd)を以下に修正すれば対応できる。
# 2個のリストを組み合わせる関数(重複省く) getprd = lambda list1, list2 : [a1 + a2 for a1 in list1for a2 in list2 if a2 not in a1]
課題2の場合は本家は216番目に出てきた。
やってみた感想
ループとか関数とか考えながら書けるので、初めてのプログラミング言語に取り組むときはHello Worldよりこの課題やると楽しそう。
別解
ちなみに標準モジュールのitertoolsを使えば以下のように書ける。
至れり尽くせり!
import itertools # al は大文字アルファベットのリスト # 課題1 allptns1 = [''.join(a) + '48' for a in itertools.product(al, al, al)] # 課題2 allptns2 = [''.join(a) + '48' for a in itertools.permutations(al, 3)]
EXIFタグで写真の情報を見てみる
自分がデジカメで撮った写真のEXIFタグ情報を見てみようかと思い立った。大量に集めれば何か撮影の傾向が見えるかも?
とりあえずPythonでEXIF情報を取得してみよう。
1.EXIF情報を取得するモジュール
EXIF.py プロジェクト日本語トップページ - SourceForge.JP
2008年8月のリリース以後、更新されていないので2010年に策定されたExif2.3に対応したデジカメだとうまく情報がとれないかもしれない。
Exif規格に7年ぶりの新バージョンExif 2.3 - PhotoXP
自分のデジカメは2011年1月発売のOLYMPUS PEN Lite E-PL2。まあ試してみてダメだったら考えよう。
2.EXIFを読み込み!
EXIFモジュールのprocess_file関数使用する。
> from EXIF import process_file > fp = r'd:\sample.jpg' # EXIFタグを読みたい画像ファイルパス > f = open(fp, 'rb') > exifDic = process_file(f)
process_fileは以下の名前付き引数が指定できる。
名前 | 既定値 | 説明 |
stop_tag | 'UNDEF' | 出現した場合に読み込みを切り上げるタグ名を指定する |
details | True | メーカーが独自に使っているMakerNoteタグを読み込むかどうか。 |
strict | False | タグ読み込み時にエラーが発生した場合に実行を停止するかどうか。 |
debug | False | タグ読み込み時にデバッグレベルの情報を出力するかどうか |
戻り値はタグ名がkeyでEXIF.IFD_Tagのインスタンスをvalueとする辞書型となる。
> ifdTag = exifDic['Image Model'] #IFD_Tagのインスタンス > dir(ifdTag) ['__doc__', '__init__', '__module__', '__repr__', '__str__', 'field_length', 'field_offset', 'field_type', 'printable', 'tag', 'values']
E-PL2のタグはdetailsにFalseを指定すると読み込むことができた。
3.サンプル画像を読み込む!
以下の関数で、フォルダ内のjpgファイルのEXIFタグ情報を一度に読めるようにする。
ExifReader.py #cording:utf-8 import EXIF import os import glob # 読み込みたくないタグは以下に指定する excludetags = ['JPEGThumbnail','TIFFThumbnail'] def getTagValueDict(filePath): f = open(filePath, 'rb') exifTags = EXIF.process_file(f, details=False, strict=False) f.close() exifKeys = [key for key in exifTags.keys() if key not in excludetags] exifDict = {} for exifKey in exifKeys: exifDict[exifKey] = exifTags[exifKey].printable return exifDict def getTagValueDicts(root, pattern='*.jpg'): files = glob.glob(os.path.join(root, pattern)) exifDicts = {} for file in files: tags = getTagValueDict(file) exifDicts[os.path.basename(file)] = tags return exifDicts
EXIF.py プロジェクト日本語トップページ - SourceForge.JPではサンプル画像もダウンロードできるので読み込ませてみる。
デジカメで撮った画像である以下を対象とする。
Canon_40D.jpg Canon_DIGITAL_IXUS_400.jpg Fujifilm_FinePix6900ZOOM.jpg Fujifilm_FinePix_E500.jpg Kodak_CX7530.jpg Konica_Minolta_DiMAGE_Z3.jpg Nikon_COOLPIX_P1.jpg Nikon_D70.jpg Olympus_C8080WZ.jpg Panasonic_DMC-FZ30.jpg PC040163.JPG Pentax_K10D.jpg Ricoh_Caplio_RR330.jpg Samsung_Digimax_i50_MP3.jpg Sony_HDR-HC3.jpg WWL_(Polaroid)_ION230.jpg
さらにE-PL2で撮った画像を一枚対象に含める。
全機種で使われているタグを調べてみる
> from ExifReader import getTagValueDicts,getTagValueDict > rootPath = r'D:\Exif_test_images' # サンプル画像のフォルダ > exifTagsDict = getTagValueDicts(rootPath) > tagSets = [tagnames for dic in exifTagsDict.values() for tagnames in dic.keys()] > distinctTags = reduce(lambda x,y: x.intersection(y) ,tagSets) > distinctTags set(['EXIF Flash', 'Image ExifOffset', 'Image Model', 'EXIF ColorSpace', 'EXIF DateTimeOriginal', 'Image XResolution', 'Image Make', 'Image DateTime', 'Image YResolution', 'EXIF FNumber', 'EXIF ExifImageLength', 'Image ResolutionUnit', 'EXIF ExifImageWidth'])
サンプル画像のExifバージョンを調べる
> versions = [str(v) for tags in exifTagsDict.values() for t,v in tags.iteritems() if t=="EXIF ExifVersion"] > set(['0220', '0221', '0210'])
ちなみにE-PL2で撮った画像の結果は以下
> d = getTagValueDict(epl2FilePath) > tagNames = sorted(d.keys()) > for t in tagNames: v = d[t] print t,':'v EXIF ColorSpace : sRGB EXIF ComponentsConfiguration : YCbCr EXIF Contrast : Normal EXIF CustomRendered : Normal EXIF DateTimeDigitized : 2011:12:04 12:18:44 EXIF DateTimeOriginal : 2011:12:04 12:18:44 EXIF DigitalZoomRatio : 1 EXIF ExifImageLength : 4032 EXIF ExifImageWidth : 3024 EXIF ExifVersion : 0221 EXIF ExposureBiasValue : 0 EXIF ExposureMode : Auto Exposure EXIF ExposureProgram : Program Normal EXIF ExposureTime : 1/500 EXIF FNumber : 71/10 EXIF FileSource : Digital Camera EXIF Flash : Auto Off EXIF FlashPixVersion : 0100 EXIF FocalLength : 17 EXIF GainControl : None EXIF ISOSpeedRatings : 200 EXIF InteroperabilityOffset : 17202 EXIF LightSource : Unknown EXIF MaxApertureValue : 761/256 EXIF MeteringMode : Pattern EXIF Padding : [] EXIF Saturation : Normal EXIF SceneCaptureType : Standard EXIF Sharpness : Normal EXIF Tag 0xEA1D : 1872 EXIF WhiteBalance : Auto Image Artist : Image Copyright : Image DateTime : 2011:12:31 21:47:17 Image ExifOffset : 2538 Image ImageDescription : OLYMPUS DIGITAL CAMERA Image Make : OLYMPUS IMAGING CORP. Image Model : E-PL2 Image Orientation : Horizontal (normal) Image Padding : [] Image PrintIM : [80, 114, 105, 110, 116, 73, 77, 0, 48, 51, 48, 48, 0, 0, 37, 0, 1, 0, 20, 0, ... ] Image ResolutionUnit : Pixels/Inch Image Software : Microsoft Windows Photo Viewer 6.1.7600.16385 Image XResolution : 314 Image YCbCrPositioning : Co-sited Image YResolution : 314 Thumbnail Compression : JPEG (old-style) Thumbnail JPEGInterchangeFormat : 17864 Thumbnail JPEGInterchangeFormatLength : 5873 Thumbnail ResolutionUnit : Pixels/Inch Thumbnail XResolution : 72 Thumbnail YResolution : 72