無料のMathematica Playerで画像を出力してみた(IronPythonで)

[pukiwiki]
[[こちらの続きです:http://boxheadroom.com/2009/10/23/mathematica_ironpython_webapi]]

IronPythonから無料のMathematica Playerのカーネルを呼び出して、グラフなどの画像を出力してみました。
[[http://boxheadroom.com/wp/wp-content/uploads/2009/10/r-150×150.jpg:http://boxheadroom.com/wp/wp-content/uploads/2009/10/r.jpg]]
[/pukiwiki]

[pukiwiki]
*若干の説明
無料のMathematicaPlayerでは、基本的に入出力関係の関数が使えなくなっています。
なのですが、ビットマップデータに変換する機能のみは生きてましたので、こちらを使用して画像を出力することに。
-[[Rasterize:http://reference.wolfram.com/mathematica/ref/Rasterize.html]]

Plot3Dなども、2次元の静止画としてなら書き出しできます。
*注意書き
netlink.pyをインポート、使用する場合、 最初に画像を書き出すタイミングで、ダイアログが開きます。
MathematicaPlayer.exe の場所を指定してください。

画像データに変換するのに、フロントエンドであるMathematicaPlayerを使用するためです。
(MathKernel.exeではありませんので注意!)

2万5千円ぐらいでフル機能のMathematicaが買えるみたいなので、
*使い方 サンプル
なんか、いろいろまんどくさい時もあるので、学生さんならフル機能版を買っちゃったほうが早そうです
(いきなり記事が台無し)
学生さんは2万5千円で買えるみたいです

ちっちゃいサインカーブ
http://boxheadroom.com/wp/wp-content/uploads/2009/10/sin.png

>>> from netlink import *
>>> m=Mathematica()
>>> m.open()
>>> im=m.im(“Plot[Sin[X],{x,0,2Pi}]”,100,”RGB”)
>>> im.Save(“sin.png”)
>>> im.Dispose()

-[[Mathematica で微分方程式を解く方法を教えてください:http://library.wolfram.com/howtos/diffeq/index.ja.html]]
ローレンツアトラクタ。コードはそのままで、視点の位置だけ変更しました

http://boxheadroom.com/wp/wp-content/uploads/2009/10/r.jpg
ドラム式の洗濯機みたい。

[/pukiwiki]

(前略) 上記の続きで
m.do("""solution=
  NDSolve[
    {Derivative[1][x][t]== -3*(x[t]-y[t]),
     Derivative[1][y][t]==
       26.5*x[t]-y[t]-x[t]*z[t],
     Derivative[1][z][t]==x[t]*y[t]-z[t],
     x[0]==z[0]==0,
     y[0]==2},{x,y,z},{t,0,17}];""")
 
im=m.im("""ParametricPlot3D[
  Evaluate[{x[t],y[t],z[t]}/.solution],
   {t,0,17},PlotPoints ->1000,ViewPoint->{1,0,1}]""",500,"RGBA")
 
im.Save("r.jpg")

[pukiwiki]
http://boxheadroom.com/wp/wp-content/themes/mydefault/images/gamma.jpg

im=m.im(“””ListLinePlot[{Re[#], Im[#]} & /@
Accumulate[Exp[I 10.^4 EulerGamma Sqrt[Range[5000]]]],Axes->False ]”””,500,”RGBA”)

オイラーの定数ガンマ、、、とかよくわかりません(><) 今度勉強します。
[[EulerGammaを含むWeyl型の総和::http://reference.wolfram.com/mathematica/ref/EulerGamma.html#1739425765]]

よくわかりませんが綺麗ですねー

*必要なソフト
-[[MathematicaPlayer:http://wolfram.com/products/player/index.ja.html]]
-[[IronPython:http://www.codeplex.com/IronPython]]
今回は2.6RC2を使用

*必要なモジュール
-[[image.py モジュール:http://boxheadroom.com/2009/10/29/ironpython_smallpil]]
-[[.NetLink:http://www.wolfram.com/solutions/mathlink/netlink/downloading.html]]
アーカイブ中のWolfram.NETLink.dllをスクリプトと同じフォルダに。

**わかっている不具合
-内部的に、Mathematicaの変数をいくつか使用しています
$ipyimagedata,$ipycolortransなど。
プログラム中で、変数名がかぶらないように気をつけてください。
あと、メモリが開放されないかも、なので、適宜 $ipyimagedata=0 などと、してやってください。
-画像の横幅指定は、あくまで目安です
出力画像では、若干変わります
-横幅によっては、画像が乱れます
透明度付きモード “RGBA”を指定してやると、乱れが治る。。。場合もあります。

m.im(“Plot[Sin[x],{x,0,2Pi}]”,100,”RGBA”)

*ソースコード
[/pukiwiki]

netlink.pyとして保存

#-*- coding:utf-8 -*-
"netlink.py"
import clr , System
from System import Array,Byte
clr.AddReferenceToFile("Wolfram.NETLink")
from Wolfram.NETLink import *
import sys
import image

exe1="mathkernel.exe"
exe2="MathematicaPlayer.exe"
mlpath="-linkmode autolaunch -linkname "
#Full Path To MathKernel.exe
mlpath+=" 'C:\\Program Files\\Wolfram Research\\Mathematica Player\\7.0\\%s' "

def fe():
  NL=MathLinkFactory.CreateMathLink(mlpath%exe2)
  return NL

def ev(txt):
  return eval(txt.replace("{","(").replace("}",")"))

class Mathematica(object):
  def open(self):
    "init"
    self.KL=MathLinkFactory.CreateKernelLink(mlpath%exe1)
    self.KL.WaitAndDiscardAnswer()
    
  def do(self,command):
    "evaluate to input form"
    return self.KL.EvaluateToInputForm(command, 0)

  def get(self,name): 
    "get value in symbol"
    #変数の値を、.NETのオブジェクトとして読み出し
    #変数のみ。 式の評価結果などを直接読み出すことは出来ません。
    self.KL.PutFunction("EvaluatePacket",1)
    self.KL.PutSymbol(name)
    self.KL.EndPacket()
    self.KL.WaitForAnswer()
    try:
      ret=self.KL.GetObject()
    except Exception:
      self.KL.ClearError()
      self.do("")
      self.KL.Flush()   
      while not self.KL.Ready:
        pass
      while self.KL.Ready:
        self.KL.WaitAndDiscardAnswer()
      ret=self.do(name)
    return ret

  def imagedata(self,txt,w,mode="RGB"):
    "evaluate to image data array"
    if mode=="RGBA":
      bg=",Background->None"
      self.do("$ipycolortrans={{0,0,1,0},{0,1,0,0},{1,0,0,0},{0,0,0,1}};")
    else :
      bg=""
      self.do("$ipycolortrans={{0,0,1},{0,1,0},{1,0,0}};")
      
    tmpl='$ipyimagedata=Rasterize[%(txt)s,"Image",RasterSize->%(w)s%(bg)s];'
    self.do(tmpl%locals())

    if self.do('ImageQ[$ipyimagedata]')!="True":
      return
    self.do('$ipyimagedata=ImageData[$ipyimagedata,"Byte"];')
    self.do('$ipyimagedata2=$ipycolortrans.#&[#]&/@#&/@$ipyimagedata;')
    return self.get("$ipyimagedata2")    

  def im(self,txt,w,mode="RGB"):
    "evaluate to image"
    dat=self.imagedata(txt,w,mode)
    if dat :
      return image.fromArray(dat)

  def close(self):
    self.KL.EvaluateToInputForm('Quit[]', 0)
    self.KL.Close()

コメントを残す

メールアドレスが公開されることはありません。