在Gox語言中進行基本折線圖的繪製與展現-GX25

Gox語言中內置了著名的gonum/plot包,它的作用與Python中的Matplotlib庫類似,可以輔助進行科學計算中的圖表繪製,非常方便。該包更詳細的文檔可以參考這裡。


基本折線圖繪製

下面是繪製一個最基本的折線圖的例子。


<code>// 導入plot包
plot = import("plot")

// 創建一個繪製上下文環境
p, _ = plot.New()

// 設置圖表的抬頭標題
p.Title.Text = "Gonum Plot Example"

// 設置圖標X、Y座標的文字
p.X.Label.Text = "X"
p.Y.Label.Text = "Y"

// 創建一組準備繪製的座標點
points = make(plot.XYs)

// 創建併為第一個點賦值X、Y座標
points[0] = make(plot.XY)
points[0].X = 0.0
points[0].Y = 0.0

// 採用簡便的方法創建第2、3、4個點
points[1] = plot.NewXY(1.0, 1.0)

points[2] = plot.NewXY(2.0, 4.0)

points[3] = plot.NewXY(3.0, 9.0)

// 在圖表中加入這些點,並給相應的曲線設定圖例的名字

plot.AddLinePoints(p, "y = x * x", points)

// 將折線圖保存為4英寸見方大小的圖片points.png,
// 需要確保c:\\test目錄已經存在
p.Save(4*plot.Inch, 4*plot.Inch, `c:\\test\\points.png`)


/<code>

程序執行後,可以在C盤的test目錄下找到points.png圖像文件,打開後可以看到繪製出來的圖形如下:

在Gox語言中進行基本折線圖的繪製與展現-GX25

可以看到一個簡單的折線圖已經成功繪製出來了。


將繪製好的圖形展示在界面上

下面我們用一個簡單的界面將畫好的圖展示出來:


<code>plot = import("plot")

p, _ = plot.New()

p.Title.Text = "Gonum Plot Example"
p.X.Label.Text = "X"
p.Y.Label.Text = "Y"

points = make(plot.XYs)

points[0] = make(plot.XY)
points[0].X = 0.0
points[0].Y = 0.0

points[1] = plot.NewXY(1.0, 1.0)

points[2] = plot.NewXY(2.0, 4.0)

points[3] = plot.NewXY(3.0, 9.0)

plot.AddLinePoints(p, "y = x * x", points)

p.Save(4*plot.Inch, 4*plot.Inch, `c:\\test\\points.png`)

var gui = import("gui")

func onButtonClick() {
\texit()
}

func loop() {


\tlayoutT = []gui.Widget{
\t\tgui.ImageWithFile(`c:\\test\\points.png`, 300, 300),
\t\tgui.Button("Close", onButtonClick),
\t}

\tgui.SingleWindow("Plot Diagram", layoutT)
}

mainWindow = gui.NewMasterWindow("Plot Diagram", 400, 400, gui.MasterWindowFlagsNotResizable, nil)

gui.LoopWindow(mainWindow, loop)



/<code>

這段代碼很好理解,就是將保存的折線圖載入到界面上的一個ImageWithFile控件上,效果是這樣的:

在Gox語言中進行基本折線圖的繪製與展現-GX25

這樣,我們就完全控制了圖片生成到展示的全過程。


從內存中加載圖片並展示

但上面的例子是以保存的png圖像文件作為中轉載入圖片,如果要直接載入內存中的圖片,可以這樣。


<code>plot = import("plot")

p, _ = plot.New()

p.Title.Text = "Gonum Plot Example"
p.X.Label.Text = "X"
p.Y.Label.Text = "Y"

points = make(plot.XYs)

points[0] = make(plot.XY)
points[0].X = 0.0
points[0].Y = 0.0

points[1] = plot.NewXY(1.0, 1.0)

points[2] = plot.NewXY(2.0, 4.0)

points[3] = plot.NewXY(3.0, 9.0)

plot.AddLinePoints(p, "y = x * x", points)

image = import("image")

rgbaT, errT = image.LoadPlotImage(p, 4*plot.Inch, 4*plot.Inch)

checkError(errT, nil)

p.Save(4*plot.Inch, 4*plot.Inch, `c:\\test\\points.png`)


var gui = import("gui")

func onButtonClick() {
\texit()
}

textureT = nil

flagT = 0

f = func() {
\tif flagT != 0 {
\t\treturn
\t}

\tflagT = 1

\ttextureT, errT = gui.NewTextureFromRgba(rgbaT)

\tif errT != nil {
\t\tplerr(errT)
\t\treturn
\t}
}

func loop() {
\tgo f()

\tlayoutT = []gui.Widget{
\t\tgui.ImageWithFile(`c:\\test\\points.png`, 300, 300),
\t\tgui.Custom(func() {
\t\t\tif textureT != nil {
\t\t\t\tgui.Image(textureT, 348, 348).Build()
\t\t\t}
\t\t}),
\t\tgui.Button("Close", onButtonClick),
\t}

\tgui.SingleWindow("Plot Diagram", layoutT)
}

mainWindow = gui.NewMasterWindow("Plot Diagram", 400, 750, gui.MasterWindowFlagsNotResizable, nil)

gui.LoopWindow(mainWindow, loop)




/<code>

運行的結果如下:

在Gox語言中進行基本折線圖的繪製與展現-GX25

第二張圖片即是直接從內存中加載的圖片,注意其尺寸設置與gui.ImageWithFile的有所不同,另外,加載圖片所需的NewTextureFromRGBA必須要在線程中啟動,這是受imgui所限制的。


用LCL庫展示圖片

上面同樣的功能用LCL庫實現圖形界面的代碼如下,更適合傳統的編程思維一些。


<code>plot = import("plot")

p, _ = plot.New()

p.Title.Text = "Gonum Plot Example"
p.X.Label.Text = "X"
p.Y.Label.Text = "Y"

points = make(plot.XYs)

points[0] = make(plot.XY)
points[0].X = 0.0
points[0].Y = 0.0

points[1] = plot.NewXY(1.0, 1.0)

points[2] = plot.NewXY(2.0, 4.0)

points[3] = plot.NewXY(3.0, 9.0)

plot.AddLinePoints(p, "y = x * x", points)

p.Save(4*plot.Inch, 4*plot.Inch, `c:\\test\\points.png`)

lcl = import("lcl")
os = import("os")

errT = lcl.InitLCL()

if errT != nil {
\tplerr(errT)
\texit()
}

application = lcl.GetApplication()

application.Initialize()

application.SetTitle("Calculator with LCL")
application.SetMainFormOnTaskBar(true)

mainForm = application.CreateForm()

mainForm.SetWidth(880)
mainForm.SetHeight(480)
mainForm.SetCaption("Calculator with LCL")

mainForm.SetPosition(lcl.PoScreenCenter)

mainForm.Font().SetSize(11)

img1 = lcl.NewImage(mainForm)
img1.SetBounds(10, 10, 400, 400)
img1.SetParent(mainForm)
img1.Picture().LoadFromFile(`c:\\test\\points.png`)
img1.SetStretch(true)
img1.SetProportional(true)

imagetk = import("imagetk")

itk = imagetk.NewImageTK()

bufT, errT = itk.LoadPlotImageInMemory(p, 4*plot.Inch, 4*plot.Inch, "png")

checkError(errT, nil)

mem = lcl.NewMemoryStream()
mem.Write(bufT.Bytes())
mem.SetPosition(0)


img2 = lcl.NewImage(mainForm)
img2.SetBounds(420, 10, 400, 400)
img2.SetParent(mainForm)
img2.Picture().LoadFromStream(mem)
img2.SetStretch(true)
img2.SetProportional(true)

mem.Free()

onButtonCloseClick = func(sender) {
\tapplication.Terminate()
}

buttonClose = lcl.NewButton(mainForm)
buttonClose.SetParent(mainForm)
buttonClose.SetLeft(10)
buttonClose.SetTop(420)
buttonClose.SetCaption("Close")
buttonClose.SetOnClick(&onButtonCloseClick)

application.Run()


/<code>

執行後的結果界面如下:

在Gox語言中進行基本折線圖的繪製與展現-GX25

效果還是不錯的,其中,左側的圖是通過圖像文件進行中轉顯示的,右側的圖是直接通過內存中緩衝區中轉顯示的。

代碼中用到了imagetk庫,這是封裝了一些便捷的圖形處理相關的函數。

需要特別注意的是,由於LCL受VCL的影響發展而來,所以所有的對象理論上都應該釋放,調用該對象的Free成員函數即可。之前很多的例子為了演示方便,並沒有都進行資源釋放。


分享到:


相關文章: