由于 C 语言本身没有内置的图形库,我们需要借助第三方库来完成,下面我将为你详细介绍几种主流的 C 语言绘图库,并给出一个从简单到复杂的示例,让你能直观地感受到它们与 Matplotlib 的异同。

(图片来源网络,侵删)
核心思想
Matplotlib 的强大之处在于它:
- 提供了高级API:用简单的函数调用(如
plt.plot(),plt.scatter())就能完成复杂的绘图。 - 封装了底层细节:你不需要关心像素如何填充、坐标轴如何计算、图像如何保存等。
- 支持多种后端:可以显示在 GUI 窗口,也可以保存为图片文件。
在 C 语言中,我们也要寻找具备类似特性的库。
主流 C 语言绘图库推荐
我将它们分为两类:轻量级、适合快速出图 和 功能强大、可定制性高。
轻量级选择:CImg
- 简介:CImg (C++ Imaging Library) 是一个用 C++ 编写的图像处理库,但它对 C 语言非常友好,尤其适合进行科学计算和可视化,它是一个“头文件”库,无需编译,只需包含其头文件即可使用,非常方便。
- 优点:
- 极其简单:几行代码就能画出图像。
- 单文件:下载一个
CImg.h就能开始。 - 自包含:不依赖任何外部图形库(如 GTK, Qt)。
- 缺点:
- 主要用于生成位图(
.png,.jpg),交互性差。 - 定制化能力相对有限。
- 主要用于生成位图(
- 与 Matplotlib 的类比:更像
matplotlib.pyplot的快速绘图功能,专注于生成静态图片。
功能强大选择:PLPLOT (Plotting Library)
- 简介:这是一个非常成熟和强大的跨平台绘图库,专门为科学和工程绘图设计,它支持多种语言(C, C++, Fortran, Python 等)和多种输出设备(窗口、矢量图、位图)。
- 优点:
- 功能全面:支持几乎所有常见的 2D 图表和部分 3D 图表。
- 高度可定制:可以精细控制坐标轴、标签、图例、颜色等。
- 多种输出:可以输出为 PNG, JPEG, PDF, SVG, PostScript 等格式。
- 缺点:
- 配置和编译较复杂:需要下载源码并编译,或者找到预编译好的库。
- API 相对繁琐:比 CImg 的代码量多一些。
- 与 Matplotlib 的类比:这是最接近 Matplotlib 功能的 C 语言库,提供了丰富的 API 和强大的可定制性。
现代化选择:ImGUI + OpenGL
- 简介:这不是一个专门的绘图库,而是一个即时模式图形用户界面库,它通常与 OpenGL (或 DirectX, Vulkan) 结合使用,用于创建交互式应用程序,你可以用 ImGUI 来创建绘图窗口和控件,用 OpenGL 来绘制实际的图表。
- 优点:
- 交互性极强:可以轻松实现缩放、平移、鼠标悬停显示数据点等动态效果。
- 现代化:非常适合开发桌面应用程序。
- 缺点:
- 学习曲线陡峭:你需要了解 ImGUI 和 OpenGL 的基本概念。
- 需要自己实现绘图逻辑:库本身不提供
plot()函数,你需要用 OpenGL 的基本绘图原语(点、线、三角形)来“画”出坐标轴、曲线和数据点。
- 与 Matplotlib 的类比:可以实现类似 Matplotlib 的交互式后端(如 QtAgg)的功能,但需要做更多底层工作。
示例对比:绘制一个正弦波
下面我们用 CImg 和 PLPLOT 来绘制一个简单的正弦波,让你感受一下代码风格。

(图片来源网络,侵删)
示例 1:使用 CImg (更简单)
步骤 1: 下载 CImg.h
从 CImg 官网 下载最新的 CImg.h 文件,并将其放在你的项目目录下。
步骤 2: 编写代码 cimg_example.c
#include "CImg.h"
// 使用 cimg namespace 方便调用
using namespace cimg;
int main() {
// 1. 定义图像大小
const int width = 800;
const int height = 600;
// 2. 创建一个彩色图像对象 (R,G,B channels, 8 bits per channel)
// 初始化为白色背景
CImg<unsigned char> image(width, height, 1, 3, 255);
// 3. 绘制坐标轴
// 横轴 (y = height/2)
image.draw_line(50, height / 2, width - 50, height / 2, 0); // 黑色
// 纵轴 (x = 50)
image.draw_line(50, 50, 50, height - 50, 0);
// 4. 绘制正弦曲线
const double pi = 3.1415926535;
const int num_points = 500;
double x1, y1, x2, y2;
for (int i = 0; i < num_points; ++i) {
// 计算当前点的坐标 (数据坐标)
double t = (double)i / num_points * 4 * pi; // 从 0 到 4π
x1 = 50 + (t / (4 * pi)) * (width - 100); // 映射到图像坐标 x
y1 = height / 2 - (sin(t)) * (height / 3); // 映射到图像坐标 y (注意Y轴方向)
// 计算下一个点
double t_next = (double)(i + 1) / num_points * 4 * pi;
x2 = 50 + (t_next / (4 * pi)) * (width - 100);
y2 = height / 2 - (sin(t_next)) * (height / 3);
// 绘制线段
image.draw_line(x1, y1, x2, y2, 0, 0, 255); // 蓝色
}
// 5. 添加标签 (CImg的文本绘制功能相对基础)
image.draw_text(60, 20, "Sine Wave using CImg", blue);
// 6. 显示图像
image.display("CImg Sine Wave");
return 0;
}
编译和运行:
# g++ 是推荐的编译器,因为 CImg 使用了 C++ 特性 g++ cimg_example.c -o cimg_example -O2 -lpthread -lX11 ./cimg_example
你会看到一个窗口显示绘制的正弦波。

(图片来源网络,侵删)
示例 2:使用 PLPLOT (更强大,更接近 Matplotlib 风格)
步骤 1: 安装 PLPLOT 在 Linux (Ubuntu/Debian) 上:
sudo apt-get install libplplot-dev
在 macOS (使用 Homebrew) 上:
brew install plplot
在 Windows 上,你需要从官网下载预编译库或自己编译。
步骤 2: 编写代码 plplot_example.c
#include <plplot/plplot.h>
int main() {
// 1. 初始化 PLPLOT 库
plinit();
// 2. 定义数据
const int n = 100;
PLFLT x[n], y[n];
PLFLT xmin = 0, xmax = 2 * M_PI;
PLFLT ymin = -1.1, ymax = 1.1;
for (int i = 0; i < n; i++) {
x[i] = xmin + (xmax - xmin) * i / (n - 1);
y[i] = sin(x[i]);
}
// 3. 开始绘制一页图形
pladv(0);
// 4. 定义一个标准化的窗口
// (0.0, 0.0, 1.0, 1.0) 表示窗口占据整个页面
// (xmin, xmax, ymin, ymax) 是数据坐标的范围
plwind(xmin, xmax, ymin, ymax);
// 5. 绘制坐标轴和网格
// "bcnst" = Bottom, Center, North, South (绘制四个边)
// "bcgln" = Bottom, Center, Grid, Line (在 Bottom 和 Center 边画网格线)
plbox("bcnst", 0.0, 0, "bcgln", 0.0, 0);
// 6. 添加标签 (类似于 plt.xlabel, plt.ylabel)
pllab("x", "sin(x)", "Sine Wave using PLPLOT");
// 7. 绘制数据线
// 1: line style (实线)
// 2: line width
// 1: color number (1=black, 2=red, etc.)
plline(n, x, y);
// 8. 终止 PLPLOT 库,并输出到文件 (默认会生成 plplot.png)
plend();
return 0;
}
编译和运行:
# -lplplotd 链接 PLPLOT 的双精度库 gcc plplot_example.c -o plplot_example -lplplotd -lm ./plplot_example
运行后,你会在当前目录下生成一个名为 plplot.png 的图片文件,内容就是正弦波,如果想在窗口中显示,PLPLOT 也支持,但需要配置不同的驱动。
总结与选择建议
| 特性 | CImg | PLPLOT | ImGUI + OpenGL |
|---|---|---|---|
| 易用性 | ⭐⭐⭐⭐⭐ (非常高) | ⭐⭐⭐ (中等) | ⭐ (非常低) |
| 功能丰富度 | ⭐⭐ (较少) | ⭐⭐⭐⭐⭐ (非常全) | ⭐⭐⭐⭐ (取决于自己实现) |
| 定制性 | ⭐⭐ (低) | ⭐⭐⭐⭐⭐ (非常高) | ⭐⭐⭐⭐⭐ (极高) |
| 交互性 | 无 | 有限 (需额外工作) | ⭐⭐⭐⭐⭐ (原生支持) |
| 依赖 | 无 (单头文件) | 需编译/安装库 | 需要多个库和图形API知识 |
| 适合场景 | 快速生成科学图表、教学示例 | 严肃的科学计算可视化、出版级图表 | 开发交互式数据可视化应用程序 |
如何选择?
- 如果你只是想快速画一张图,不关心交互和复杂样式:选择 CImg,它最简单,几行代码就能搞定。
- 如果你需要一个功能完备、可定制、能生成高质量图表的工具,并且愿意花时间配置环境:选择 PLPLOT,它是 C 语言世界里最接近 Matplotlib 的选择。
- 如果你想开发一个带有交互式图表的桌面软件:选择 ImGUI + OpenGL,这是最灵活的方案,但也是工作量最大的方案。
对于从 Matplotlib 转过来的用户,PLPLOT 是最值得投入时间去学习的库,因为它在理念(高级API、数据驱动绘图)和功能上与 Matplotlib 最为相似。
