在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成员函数即可。之前很多的例子为了演示方便,并没有都进行资源释放。


分享到:


相關文章: