『プログラミング言語 Julia でグラフを描画する』 でとりあえずサンプルを動かすことに成功したが、自分の(Julia言語の)プログラムで作ったデータを使ってグラフを描画するにはどうしたら良いかを調べることにした。
う~ん、3Dグラフ(OpenGL)とかも使ってみたいし、PyQtGraph のサンプルコードを全部 Julia に移植するのも大変そうだな~て思ったりした。
よっし、方針転換…グラフは全部 Python に任せよう!
てことで、文末ののソースコードとなった。
- Plotting.jl (Julia のソースコード)は、Plotting.my_graph_set() という関数に配列を渡すだけ(実際には予め配列を計算結果として求めるのだが)。渡したら、Plotting.my_graph_run() を呼んでグラフが描画される。グラフの描画は Python にお任せ。
- Plotting.py (Python のソースコード)では、plot_data_1 というグローバル変数に、Julia から渡される配列を格納する。my_graph_set() が呼ばれた時に plot_data_1 というグローバル変数に Julia から渡された配列を格納しておく。my_graph_run() が呼ばれたら 左上のグラフだけ を Julia から渡された配列データを使って描画する。
- PyCall を用いて Python のコードを呼び出す際には、C:\julia-0.2.1-win32\bin がロードパスに含まれるので、Plotting.jl および Plotting.py の両方共を C:\julia-0.2.1-win32\bin 配下に(とりあえず)保存しておくことにした。
グラフの処理は、 Python のコードに任せっきり にすることで、開発が超楽になったわ~!
後は、Julia 側でそれらしい計算処理をするサンプルができれば… その次は、OpenGL を使った 3D グラフをやってみよう!
注記:環境構築については、『プログラミング言語 Julia でグラフを描画する』 を参照してくださいませ。
Plotting.jl(C:\julia-0.2.1-win32\binに保存すること)
using PyCall
@pyimport Plotting
Plotting.my_graph_set([1, 2, 3, 4, 5, 10, 20, 5])
Plotting.my_graph_run()
Plotting.py(C:\julia-0.2.1-win32\binに保存すること)
# -*- coding: utf-8 -*-
"""
This example demonstrates many of the 2D plotting capabilities
in pyqtgraph. All of the plots may be panned/scaled by dragging with
the left/right mouse buttons. Right click on any plot to show a context menu.
"""
from pyqtgraph.Qt import QtGui, QtCore
import numpy as np
import pyqtgraph as pg
plot_data_1 = []
def my_graph_set(plot_data):
global plot_data_1
plot_data_1 = plot_data
def my_graph_run():
global plot_data_1
app = QtGui.QApplication([])
win = pg.GraphicsWindow(title="Basic plotting examples")
win.resize(800,600)
win.setWindowTitle('pyqtgraph example: Plotting')
# Enable antialiasing for prettier plots
pg.setConfigOptions(antialias=True)
p1 = win.addPlot(title="Basic array plotting", y=plot_data_1)
p2 = win.addPlot(title="Multiple curves")
p2.plot(np.random.normal(size=100), pen=(255,0,0))
p2.plot(np.random.normal(size=100)+5, pen=(0,255,0))
p2.plot(np.random.normal(size=100)+10, pen=(0,0,255))
p3 = win.addPlot(title="Drawing with points")
p3.plot(np.random.normal(size=100), pen=(200,200,200), symbolBrush=(255,0,0), symbolPen='w')
win.nextRow()
p4 = win.addPlot(title="Parametric, grid enabled")
x = np.cos(np.linspace(0, 2*np.pi, 1000))
y = np.sin(np.linspace(0, 4*np.pi, 1000))
p4.plot(x, y)
p4.showGrid(x=True, y=True)
p5 = win.addPlot(title="Scatter plot, axis labels, log scale")
x = np.random.normal(size=1000) * 1e-5
y = x*1000 + 0.005 * np.random.normal(size=1000)
y -= y.min()-1.0
mask = x > 1e-15
x = x[mask]
y = y[mask]
p5.plot(x, y, pen=None, symbol='t', symbolPen=None, symbolSize=10, symbolBrush=(100, 100, 255, 50))
p5.setLabel('left', "Y Axis", units='A')
p5.setLabel('bottom', "Y Axis", units='s')
p5.setLogMode(x=True, y=False)
global curve, data, ptr, p6
p6 = win.addPlot(title="Updating plot")
curve = p6.plot(pen='y')
data = np.random.normal(size=(10,1000))
ptr = 0
def update():
global curve, data, ptr, p6
curve.setData(data[ptr%10])
if ptr == 0:
p6.enableAutoRange('xy', False) ## stop auto-scaling after the first data set is plotted
ptr += 1
timer = QtCore.QTimer()
timer.timeout.connect(update)
timer.start(50)
win.nextRow()
p7 = win.addPlot(title="Filled plot, axis disabled")
y = np.sin(np.linspace(0, 10, 1000)) + np.random.normal(size=1000, scale=0.1)
p7.plot(y, fillLevel=-0.3, brush=(50,50,200,100))
p7.showAxis('bottom', False)
x2 = np.linspace(-100, 100, 1000)
data2 = np.sin(x2) / x2
p8 = win.addPlot(title="Region Selection")
p8.plot(data2, pen=(255,255,255,200))
lr = pg.LinearRegionItem([400,700])
lr.setZValue(-10)
p8.addItem(lr)
p9 = win.addPlot(title="Zoom on selected region")
p9.plot(data2)
def updatePlot():
p9.setXRange(*lr.getRegion(), padding=0)
def updateRegion():
lr.setRegion(p9.getViewBox().viewRange()[0])
lr.sigRegionChanged.connect(updatePlot)
p9.sigXRangeChanged.connect(updateRegion)
updatePlot()
QtGui.QApplication.instance().exec_()