Immediate Mode Plotting
| 文件 | 最后提交记录 | 最后更新时间 |
|---|---|---|
| 4 个月前 | ||
| 4 个月前 | ||
| 7 个月前 | ||
| 6 年前 | ||
| 4 个月前 | ||
| 4 个月前 | ||
| 1 个月前 | ||
| 1 个月前 | ||
| 1 个月前 | ||
| 1 个月前 | ||
| 1 个月前 |
ImPlot
ImPlot 是一款用于 Dear ImGui 的即时模式、GPU 加速绘图库。它旨在提供 ImGui 爱好者会喜爱的一流 API。ImPlot 非常适合实时可视化程序数据或创建交互式图表,并且只需极少代码即可集成。与 ImGui 一样,它不会给最终用户带来 GUI 状态管理的负担,避免使用 STL 容器和 C++ 头文件,除了 ImGui 本身外没有其他外部依赖。




特性
- GPU 加速渲染
- 多种图表类型:
- 折线图
- 填充区域图
- 散点图
- 垂直/水平/堆叠条形图
- 垂直/水平误差线
- 茎状图
- 阶梯图
- 饼图
- 热力图
- 一维/二维直方图
- 图像
- 更多类型即将推出
- 在单个图表上混合/匹配多个图表项
- 可配置的轴范围和缩放(线性/对数)
- 子图
- 时间格式化 X 轴(美国格式或 ISO 8601)
- 可反转和可锁定的轴
- 多个 X 轴和 Y 轴
- 用于缩放、平移、框选和自动拟合数据的控件
- 用于创建持久查询范围的控件(见演示)
- 多种图表样式选项:10 种标记类型,可调整标记大小、线宽、轮廓颜色、填充颜色等
- 16 种内置颜色映射,并支持用户添加颜色映射
- 可选的图表标题、轴标签和网格标签
- 可选且可配置的图例,带有切换按钮以快速显示/隐藏图表项
- 基于当前 ImGui 主题的默认样式,或完全自定义的图表样式
- 可自定义的数据获取器和数据步幅(与 ImGui::PlotLine 类似)
- 接受 float、double 以及 8、16、32 和 64 位有符号/无符号整数类型的数据
- 以及更多!(参见公告 2022/2021/2020)
使用方法
该 API 的使用方式与其他 ImGui 的 BeginX/EndX 函数对类似。首先,使用 ImPlot::BeginPlot() 开始一个新图表。接下来,使用提供的 PlotX 函数(例如 PlotLine()、PlotBars()、PlotScatter() 等)绘制任意数量的项目。最后,调用 ImPlot::EndPlot() 完成绘制。就是这么简单!
int bar_data[11] = ...;
float x_data[1000] = ...;
float y_data[1000] = ...;
ImGui::Begin("My Window");
if (ImPlot::BeginPlot("My Plot")) {
ImPlot::PlotBars("My Bar Plot", bar_data, 11);
ImPlot::PlotLine("My Line Plot", x_data, y_data, 1000);
...
ImPlot::EndPlot();
}
ImGui::End();
当然,使用 ImPlot 还能实现更多功能……
演示程序
implot_demo.cpp 中提供了 ImPlot 功能的综合示例。将此文件添加到您的源代码中,并在更新循环的某处调用 ImPlot::ShowDemoWindow()。建议您在需要实现各种图表类型时,将此文件作为参考。演示程序会随着新图表类型和功能的添加而不断更新,因此请在每个版本发布时查看更新!
在线版演示程序托管于此处。您可以查看图表及其生成源代码。请注意,此在线演示可能并非始终保持最新,且性能不如桌面版实现,但它应该能让您大致了解 ImPlot 的功能。特别感谢 pthom 创建并托管了此在线演示!
需要更长代码和/或第三方库的更复杂演示可在单独的仓库中找到:implot_demos。在这里,您将看到高级信号处理和 ImPlot 的实际应用。如果您有新的演示想法,请阅读该仓库的“贡献”部分!
集成
- 如果尚未设置 ImGui 环境,请先进行设置。
- 将
implot.h、implot_internal.h、implot.cpp、implot_items.cpp以及可选的implot_demo.cpp添加到您的源代码中。或者,您也可以通过 vcpkg 获取 ImPlot。 - 在创建和销毁
ImGuiContext的位置,相应地创建和销毁ImPlotContext:
ImGui::CreateContext();
ImPlot::CreateContext();
...
ImPlot::DestroyContext();
ImGui::DestroyContext();
您应该可以开始使用了!
使用 vcpkg 安装 ImPlot
您可以使用 vcpkg 依赖管理器下载并安装 ImPlot:
git clone https://github.com/Microsoft/vcpkg.git
cd vcpkg
./bootstrap-vcpkg.sh
./vcpkg integrate install
./vcpkg install implot
vcpkg 中的 ImPlot 移植版本由 Microsoft 团队成员和社区贡献者负责更新。如果版本过时,请在 vcpkg 仓库上创建 issue 或 pull request。
极为重要的注意事项
Dear ImGui 默认使用16 位索引,因此像 ImPlot::PlotHeatmap() 这样的高密度 ImPlot 部件可能会在 ImDrawList 中生成过多顶点,这会导致断言失败,并可能造成数据截断和/或视觉故障。因此,强烈建议您执行以下任一操作:
- 选项 1: 在您的 ImGui
imconfig.h文件中取消注释#define ImDrawIdx unsigned int,以启用 32 位索引。 - 选项 2: 如果必须使用 16 位索引,请在渲染器中处理
ImGuiBackendFlags_RendererHasVtxOffset标志。许多默认的 ImGui 渲染后端已支持ImGuiBackendFlags_RendererHasVtxOffset。有关更多信息,请参考此 issue。
常见问题解答
问:为什么需要 ImPlot?
答:ImGui 是一个用于快速原型设计和开发的极其强大的工具,但它提供的数据可视化机制有限。二维图表在几乎所有应用中都非常普遍且有用。能够实时可视化您的数据将使您深入了解并更好地理解您的应用程序。
问:ImPlot 是适合我的绘图库吗?
答:如果您希望生成可用于发表的高质量图表和/或将图表导出到文件,那么 ImPlot 不是您要找的库!ImPlot 旨在以实时速度和高度交互性绘制应用程序数据。ImPlot 尽最大努力创建美观的图表(确实有相当多的样式选项可用),但它始终会优先考虑功能而非形式。
问:文档在哪里?
答:API 在 implot.h 中有详尽的注释,implot_demo.cpp 中的演示应该足以帮助您入门。也可以查看 implot_demos 仓库。
问:ImPlot 适合绘制大型数据集吗?
答:是的,在合理范围内。您可以毫无问题地绘制数万到数十万个点,但不要期望数百万个点能有丝般顺滑的体验。也就是说,如果需要,您总是可以通过告诉 ImPlot 以更大的间隔对数据进行跨步采样来对极大的数据集进行下采样。也可以尝试实验性的 backends 分支,该分支旨在提供 GPU 加速支持。
问:我可以绘制哪些数据类型?
答:ImPlot 绘图函数接受大多数标量类型:float、double、int8、uint8、int16、uint16、int32、uint32、int64、uint64。自定义结构体或类的数组(例如 Vector2f 或类似类型)可以使用内置的跨步功能轻松传递给 ImPlot 函数(有关文档,请参见 implot.h),并且许多绘图器提供了接受数据生成回调的“getter”重载。您可以通过在编译时定义 IMPLOT_CUSTOM_NUMERIC_TYPES 来完全自定义接受的类型列表:请参见 implot_items.cpp 中的文档。
问:可以修改图表样式吗?
答:可以。有三种默认样式可用,还有一种自动样式会尝试匹配您的 ImGui 样式。您也可以定义任何自定义样式。图表项通常会根据当前的颜色图为您设置样式,但也可以逐个进行自定义。
问:ImPlot 是否支持非线性轴缩放?时间格式化?
答:是的。默认提供对数刻度和对称对数刻度,您也可以定义自定义轴刻度。默认还提供具有微秒精度的时间刻度。
问:ImPlot 是否支持多个 y 轴?x 轴呢?
答:是的。最多可以启用三个 x 轴和三个 y 轴。
问:ImPlot 是否支持[插入图表类型]?
答:可能支持。查看演示、图库或公告(2020/2021/2022),看看是否有您需要的图表类型。如果没有,可以考虑提交 issue,更好的是提交 PR!
问:ImPlot 是否支持 3D 图表?
答:ImPlot 的一个实验性扩展 ImPlot3D 提供了类似的 API 用于绘制和交互 3D 数据。
问:ImPlot 是否提供分析工具?
答:不完全提供,但它使您能够查询图表的子范围,您可以用它来以任何您喜欢的方式处理数据。
问:图表可以导出/保存为图像吗?
答:目前不可以。如果需要捕获图表,请使用操作系统的屏幕捕获机制。ImPlot 不适合渲染可用于发表的高质量图表;它仅旨在用作可视化工具。对于这些目的,请使用 MATLAB 或 matplotlib 对数据进行后期处理。
问:为什么我的图表线条显示锯齿?
答:您可能需要启用 ImGuiStyle::AntiAliasedLinesUseTex(或者可能是 ImGuiStyle::AntiAliasedLines)。如果这些设置已启用,那么您必须确保您的后端支持基于纹理的抗锯齿(即使用双线性采样)。大多数默认的 ImGui 后端都开箱即用地支持此功能。此处了解更多信息。或者,如果您的硬件支持,您可以在应用程序级别启用多重采样抗锯齿(4x 应该足够)。
问:我可以将 ImPlot 编译为动态库吗?
答:与 ImGui 一样,建议您将 ImPlot 编译并链接为静态库,或者直接作为源代码的一部分。但是,如果您必须并且要将 ImPlot 和 ImGui 编译为单独的 DLL,请确保使用 ImPlot::SetImGuiContext(ImGuiContext* ctx) 设置当前的 ImGui 上下文。这确保了全局 ImGui 变量在 DLL 边界正确共享。
问:ImPlot 可以与其他语言/绑定一起使用吗?
答:是的,您可以将生成的 C 绑定 cimplot 与大多数高级语言一起使用。DearPyGui 提供了 Python 包装器等功能。DearImGui/DearImPlot 提供了 .NET 的绑定。imgui-java 提供了 Java 的绑定。ImPlot.jl 提供了 Julia 的绑定。Rust 绑定 implot-rs 目前正在开发中。可以在 此处 找到使用 Emscripten 的示例。