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

こちらの続きです

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

若干の説明

無料のMathematicaPlayerでは、基本的に入出力関係の関数が使えなくなっています。
なのですが、ビットマップデータに変換する機能のみは生きてましたので、こちらを使用して画像を出力することに。

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()

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

(前略) 上記の続きで
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")

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型の総和:

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

必要なソフト

必要なモジュール

わかっている不具合

  • 内部的に、Mathematicaの変数をいくつか使用しています
    $ipyimagedata,$ipycolortransなど。
    プログラム中で、変数名がかぶらないように気をつけてください。
    あと、メモリが開放されないかも、なので、適宜 $ipyimagedata=0 などと、してやってください。
  • 画像の横幅指定は、あくまで目安です
    出力画像では、若干変わります
  • 横幅によっては、画像が乱れます
    透明度付きモード "RGBA"を指定してやると、乱れが治る。。。場合もあります。
m.im("Plot[Sin[x],{x,0,2Pi}]",100,"RGBA")

ソースコード

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()
Tags: , , ,

Related posts

Tags: , , ,

Comments are closed.