使用Go语言绘制柱状图教程

server/2024/9/23 3:19:20/

使用Go语言绘制柱状图教程

本文将介绍如何使用Go语言及gg包绘制柱状图,并将图表保存为PNG格式的图片。gg包是一个功能强大的2D图形库,适合用于绘制各种图表。

安装gg

首先,确保你已经安装了gg包。如果还没有安装,可以使用以下命令进行安装:

go get -u github.com/fogleman/gg

代码示例

以下是一个完整的Go程序,它会绘制一个柱状图并将其保存为bar_chart.png文件。

package mainimport ("fmt""log""math""github.com/fogleman/gg"
)func main() {// 定义柱状图文件路径barChartFile := "bar_chart.png"// 创建柱状图if err := createBarChart(barChartFile); err != nil {log.Fatalf("创建柱状图时出错: %v", err)}fmt.Println("柱状图生成成功")
}// 创建柱状图并保存为图片
func createBarChart(filename string) error {const (width      = 900  // 画布宽度height     = 700  // 画布高度barWidth   = 60   // 柱子的固定宽度barSpacing = 60.0 // 柱子之间的间隔margin     = 50   // 边距)// 数据data := []struct {label stringvalue float64}{{"身份证", 15},{"电话号码", 2000},{"地址信息", 2500},{"银行卡号", 3000},{"财务数据", 3500},{"基础信息", 4000},{"户籍信息", 4500},}// 计算数据中的最大值var maxValue float64for _, d := range data {if d.value > maxValue {maxValue = d.value}}// 设置纵坐标最大值,稍微高于数据中的最大值,保证柱子不贴顶maxValue *= 1.1// 创建画布dc := gg.NewContext(width, height)dc.SetRGB(1, 1, 1) // 背景色为白色dc.Clear()// 定义颜色colors := []struct{ R, G, B float64 }{{0.8, 0.2, 0.2}, // 红色{0.2, 0.8, 0.2}, // 绿色{0.2, 0.2, 0.8}, // 蓝色{0.8, 0.8, 0.2}, // 黄色{0.8, 0.2, 0.8}, // 紫色{0.2, 0.8, 0.8}, // 青色{0.8, 0.8, 0.8}, // 灰色}// 加载自定义字体if err := dc.LoadFontFace("_examples/word-template/msyh.ttf", 12); err != nil {return fmt.Errorf("无法加载字体: %v", err)}// 绘制柱状图for i, d := range data {x := margin + float64(i)*(barWidth+barSpacing)                    // x轴起始位置y := height - margin - (d.value / maxValue * (height - 2*margin)) // y轴起始位置减去柱子的高度color := colors[i%len(colors)]                                    // 循环使用颜色dc.SetRGB(color.R, color.G, color.B)dc.DrawRectangle(x, y, barWidth, (d.value / maxValue * (height - 2*margin)))dc.Fill()}// 绘制坐标轴dc.SetRGB(0, 0, 0)                                              // 黑色dc.DrawLine(margin, height-margin, width-margin, height-margin) // X轴dc.DrawLine(margin, height-margin, margin, margin)              // Y轴dc.Stroke()// 计算纵坐标标签间隔interval := calculateInterval(maxValue, 10)// 添加横坐标标签for i, d := range data {dc.DrawStringAnchored(d.label, margin+float64(i)*(barWidth+barSpacing)+barWidth/2, height-margin+20, 0.5, 1)}// 添加纵坐标标签for i := 0.0; i <= maxValue; i += interval {y := height - margin - (i / maxValue * (height - 2*margin))dc.DrawStringAnchored(fmt.Sprintf("%.0f", i), margin-10, y, 1, 0.5)}// 保存图像为PNG文件return dc.SavePNG(filename)
}// 计算适当的标签间隔
func calculateInterval(maxValue float64, maxLabels int) float64 {interval := maxValue / float64(maxLabels)// 向上取整到最近的10的倍数magnitude := math.Pow(10, math.Floor(math.Log10(interval)))normalized := interval / magnitudeif normalized > 5 {interval = 10 * magnitude} else if normalized > 2 {interval = 5 * magnitude} else {interval = 2 * magnitude}return interval
}

代码解析

  1. 导入必要的包:代码导入了fmtlogmathgithub.com/fogleman/gg包。

  2. 定义画布大小和柱状图参数:画布的宽度为900像素,高度为700像素,柱子的宽度为60像素,柱子之间的间隔为60像素,边距为50像素。

  3. 数据定义:定义了一组数据,每个数据项包括一个标签和一个值。

  4. 计算最大值:遍历数据以确定最大值,并将最大值稍微增加10%以便在图表中显示完整。

  5. 创建画布:使用gg.NewContext创建一个新的绘图上下文,并设置背景颜色为白色。

  6. 定义颜色:定义了七种颜色用于绘制柱子。

  7. 加载自定义字体:使用dc.LoadFontFace方法加载自定义字体(这里假设字体文件路径为_examples/word-template/msyh.ttf)。

  8. 绘制柱子:遍历数据,计算每个柱子的x轴和y轴位置,并绘制矩形表示柱子。

  9. 绘制坐标轴:使用dc.DrawLine方法绘制X轴和Y轴。

  10. 计算纵坐标标签间隔:调用calculateInterval函数计算适当的纵坐标标签间隔。

  11. 添加横坐标和纵坐标标签:在适当的位置绘制横坐标和纵坐标标签。

  12. 保存图像:使用dc.SavePNG方法将图表保存为PNG文件。

运行代码

将上述代码保存为main.go,然后在命令行运行以下命令:

go run main.go

运行成功后,你将在当前目录下看到生成的bar_chart.png文件。

结论

通过本文的介绍,你已经学会了如何使用Go语言及gg包绘制柱状图。你可以根据需要调整数据和图表样式,生成各种自定义的柱状图。希望本文对你有所帮助,祝你编程愉快!

效果图

在这里插入图片描述


http://www.ppmy.cn/server/96293.html

相关文章

算法通关:014_1:用栈实现队列

文章目录 题目总结代码运行结果 题目 用栈实现队列 leetcode :232 总结 时间复杂度 平均下来每个方式是O(1) 代码 class MyQueue {public Stack<Integer> in;public Stack<Integer> out;//初始化public MyQueue() {in new Stack<>();out new Stack<…

【Linux 从基础到进阶】Linux 内核参数调优

Linux 内核参数调优 引言 内核参数调优是提升 Linux 系统性能和稳定性的重要手段。通过合理配置和优化内核参数,可以显著改善系统资源利用率和响应速度。本文将介绍内核参数的调优方法,并提供适用于 CentOS 和 Ubuntu 系统的具体示例。 1. 内核参数简介 内核参数是控制 L…

Spring为啥用三级缓存而不用两级缓存

1. 背景介绍 Spring框架&#xff1a;一个广泛应用于Java应用开发的轻量级容器框架。三级缓存机制&#xff1a;Spring框架特有的设计&#xff0c;旨在解决单例Bean创建过程中的循环依赖问题。 2. 缓存层级详解 一级缓存&#xff08;Singleton Objects&#xff09; 作用&#x…

通过指令深入了解Linux

文章目录 1.简单介绍XShell1.1下载安装XShell1.2 使用XShell登录主机1.3 XShell下的复制粘贴 2. Linux下的基本指令2.1 ls指令2.1.1 对文件的理解2.1.2 目录下的隐藏文件 2.2 pwd指令2.3 cd指令2.3.1 Linux下目录结构的认识 2.4 touch指令2.5 mkdir指令2.6 clear指令 1.简单介绍…

面试中的算法 [ 持续更新中 ] 基于Python语言 如何判断链表有环

本文主要介绍了如何判断链表有环的问题&#xff0c;并进行了延伸&#xff1a; 如果链表有环如何求出环的长度&#xff0c;入环节点... ...嗯&#xff0c;点个赞总可以不&#xff01;&#xff01;&#xff01; 目录 5.1如何判断链表有环 5.1.1 有一个单向链表&#xff0c;链表…

serial 反序列化靶机

1.安装靶机 2.扫描靶机ip,端口,访问 3.扫描目录,发现有 backup 目录,访问发现是压缩包,下载,解压,查看 通过审计源代码了解到: 首次访问该网站后,会通过 user.class.php 中的创建一个user对象, 内容为wel变量创建welcome对象,同时进行序列化base64编码存入cookie,在此过程中调用…

自学黑客(网络安全)

前言&#xff1a; 想自学网络安全&#xff08;黑客技术&#xff09;首先你得了解什么是网络安全&#xff01;什么是黑客&#xff01; 网络安全可以基于攻击和防御视角来分类&#xff0c;我们经常听到的 “红队”、“渗透测试” 等就是研究攻击技术&#xff0c;而“蓝队”、“…

Visual Studio创建 OpenCV项目

1、cmake 编译 opencv 参考链接&#xff1a;CMake编译OpenCV3.4.1心得_cmake 3.4.1-CSDN博客 1&#xff09;opencv文件名最好不要有空格 2&#xff09;没有下载opencv_contrib&#xff0c;不用配置OPENCV_EXTRA_MODULES_PATH 1、Visual Studio创建 OpenCV项目 参考链接&am…