glplot 0.1.6__tar.gz → 0.1.8__tar.gz

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (427) hide show
  1. {glplot-0.1.6 → glplot-0.1.8}/.gitignore +4 -0
  2. {glplot-0.1.6 → glplot-0.1.8}/CITATION.cff +12 -7
  3. glplot-0.1.8/PKG-INFO +594 -0
  4. glplot-0.1.8/README.md +552 -0
  5. {glplot-0.1.6 → glplot-0.1.8}/glplot/__init__.py +13 -1
  6. {glplot-0.1.6 → glplot-0.1.8}/glplot/anim/processes.py +5 -0
  7. {glplot-0.1.6 → glplot-0.1.8}/glplot/animation.py +7 -2
  8. {glplot-0.1.6 → glplot-0.1.8}/glplot/controllers.py +2 -3
  9. {glplot-0.1.6 → glplot-0.1.8}/glplot/core/camera3d.py +4 -2
  10. {glplot-0.1.6 → glplot-0.1.8}/glplot/core/context.py +2 -2
  11. {glplot-0.1.6 → glplot-0.1.8}/glplot/core/layers.py +2 -3
  12. {glplot-0.1.6 → glplot-0.1.8}/glplot/core/timeline.py +1 -1
  13. {glplot-0.1.6 → glplot-0.1.8}/glplot/engine.py +58 -46
  14. {glplot-0.1.6 → glplot-0.1.8}/glplot/gui/actions.py +1 -1
  15. {glplot-0.1.6 → glplot-0.1.8}/glplot/gui/dynamics.py +1 -1
  16. {glplot-0.1.6 → glplot-0.1.8}/glplot/gui/generators3d.py +2 -2
  17. {glplot-0.1.6 → glplot-0.1.8}/glplot/gui/icons.py +28 -29
  18. {glplot-0.1.6 → glplot-0.1.8}/glplot/gui/keys.py +84 -17
  19. {glplot-0.1.6 → glplot-0.1.8}/glplot/gui/mathops.py +6 -1
  20. {glplot-0.1.6 → glplot-0.1.8}/glplot/gui/panels/annotate.py +55 -58
  21. {glplot-0.1.6 → glplot-0.1.8}/glplot/gui/panels/data_editor.py +81 -86
  22. {glplot-0.1.6 → glplot-0.1.8}/glplot/gui/panels/dynamics.py +9 -7
  23. {glplot-0.1.6 → glplot-0.1.8}/glplot/gui/panels/functions.py +16 -15
  24. {glplot-0.1.6 → glplot-0.1.8}/glplot/gui/panels/help.py +21 -23
  25. {glplot-0.1.6 → glplot-0.1.8}/glplot/gui/panels/mathlab.py +19 -19
  26. {glplot-0.1.6 → glplot-0.1.8}/glplot/gui/panels/objects3d.py +5 -6
  27. {glplot-0.1.6 → glplot-0.1.8}/glplot/gui/panels/palette.py +37 -42
  28. {glplot-0.1.6 → glplot-0.1.8}/glplot/gui/panels/pipeline.py +17 -17
  29. {glplot-0.1.6 → glplot-0.1.8}/glplot/gui/panels/presentation.py +7 -7
  30. {glplot-0.1.6 → glplot-0.1.8}/glplot/gui/panels/scene.py +26 -37
  31. {glplot-0.1.6 → glplot-0.1.8}/glplot/gui/panels/selection.py +10 -13
  32. {glplot-0.1.6 → glplot-0.1.8}/glplot/gui/panels/style.py +70 -56
  33. {glplot-0.1.6 → glplot-0.1.8}/glplot/gui/panels/timeline.py +28 -23
  34. {glplot-0.1.6 → glplot-0.1.8}/glplot/gui/panels/view3d.py +1 -1
  35. {glplot-0.1.6 → glplot-0.1.8}/glplot/gui/styles.py +140 -0
  36. {glplot-0.1.6 → glplot-0.1.8}/glplot/gui/theme.py +60 -61
  37. {glplot-0.1.6 → glplot-0.1.8}/glplot/gui/widgets.py +64 -60
  38. {glplot-0.1.6 → glplot-0.1.8}/glplot/gui/workspace.py +41 -31
  39. {glplot-0.1.6 → glplot-0.1.8}/glplot/managers/axis.py +3 -1
  40. {glplot-0.1.6 → glplot-0.1.8}/glplot/managers/effects.py +0 -1
  41. {glplot-0.1.6 → glplot-0.1.8}/glplot/managers/hud.py +74 -63
  42. {glplot-0.1.6 → glplot-0.1.8}/glplot/managers/hud_state.py +1 -3
  43. {glplot-0.1.6 → glplot-0.1.8}/glplot/managers/picking.py +0 -4
  44. {glplot-0.1.6 → glplot-0.1.8}/glplot/managers/renderer_manager.py +25 -16
  45. {glplot-0.1.6 → glplot-0.1.8}/glplot/policy.py +4 -6
  46. {glplot-0.1.6 → glplot-0.1.8}/glplot/pyplot.py +330 -44
  47. {glplot-0.1.6 → glplot-0.1.8}/glplot/renderers/axes3d.py +8 -7
  48. {glplot-0.1.6 → glplot-0.1.8}/glplot/renderers/axis.py +37 -58
  49. {glplot-0.1.6 → glplot-0.1.8}/glplot/renderers/density.py +1 -5
  50. {glplot-0.1.6 → glplot-0.1.8}/glplot/renderers/legend.py +35 -38
  51. {glplot-0.1.6 → glplot-0.1.8}/glplot/renderers/line_family.py +1 -1
  52. {glplot-0.1.6 → glplot-0.1.8}/glplot/renderers/patch.py +1 -1
  53. {glplot-0.1.6 → glplot-0.1.8}/glplot/renderers/scatter.py +1 -1
  54. {glplot-0.1.6 → glplot-0.1.8}/glplot/renderers/text.py +8 -8
  55. {glplot-0.1.6 → glplot-0.1.8}/glplot/utils/anim_export.py +6 -2
  56. {glplot-0.1.6 → glplot-0.1.8}/glplot/utils/gl_utils.py +3 -3
  57. {glplot-0.1.6 → glplot-0.1.8}/glplot/utils/preview.py +264 -24
  58. {glplot-0.1.6 → glplot-0.1.8}/glplot/utils/shaders.py +6 -5
  59. {glplot-0.1.6 → glplot-0.1.8}/pyproject.toml +21 -8
  60. {glplot-0.1.6 → glplot-0.1.8}/tests/conftest.py +1 -1
  61. {glplot-0.1.6 → glplot-0.1.8}/tests/test_anim_processes.py +9 -2
  62. {glplot-0.1.6 → glplot-0.1.8}/tests/test_animation_api.py +1 -1
  63. {glplot-0.1.6 → glplot-0.1.8}/tests/test_api_consistency.py +2 -2
  64. {glplot-0.1.6 → glplot-0.1.8}/tests/test_axes.py +12 -13
  65. {glplot-0.1.6 → glplot-0.1.8}/tests/test_axes3d.py +7 -8
  66. {glplot-0.1.6 → glplot-0.1.8}/tests/test_axis_margins.py +0 -3
  67. {glplot-0.1.6 → glplot-0.1.8}/tests/test_camera_anisotropy.py +1 -1
  68. {glplot-0.1.6 → glplot-0.1.8}/tests/test_camera_projections.py +0 -5
  69. {glplot-0.1.6 → glplot-0.1.8}/tests/test_export.py +76 -0
  70. {glplot-0.1.6 → glplot-0.1.8}/tests/test_function_layer.py +4 -1
  71. {glplot-0.1.6 → glplot-0.1.8}/tests/test_gallery_integration.py +0 -1
  72. {glplot-0.1.6 → glplot-0.1.8}/tests/test_geometry3d.py +2 -2
  73. {glplot-0.1.6 → glplot-0.1.8}/tests/test_gui_3d_panels.py +4 -5
  74. {glplot-0.1.6 → glplot-0.1.8}/tests/test_gui_actions.py +63 -5
  75. {glplot-0.1.6 → glplot-0.1.8}/tests/test_gui_annotate.py +6 -4
  76. {glplot-0.1.6 → glplot-0.1.8}/tests/test_gui_import_safety.py +31 -13
  77. glplot-0.1.8/tests/test_gui_input_regressions.py +183 -0
  78. {glplot-0.1.6 → glplot-0.1.8}/tests/test_gui_keys.py +71 -14
  79. {glplot-0.1.6 → glplot-0.1.8}/tests/test_gui_layer_kinds.py +5 -2
  80. {glplot-0.1.6 → glplot-0.1.8}/tests/test_gui_layer_params.py +1 -1
  81. {glplot-0.1.6 → glplot-0.1.8}/tests/test_gui_legend.py +11 -15
  82. {glplot-0.1.6 → glplot-0.1.8}/tests/test_gui_mathlab.py +13 -12
  83. {glplot-0.1.6 → glplot-0.1.8}/tests/test_gui_pipeline.py +4 -6
  84. {glplot-0.1.6 → glplot-0.1.8}/tests/test_gui_scene_delete.py +2 -3
  85. {glplot-0.1.6 → glplot-0.1.8}/tests/test_gui_style_layer_editor.py +9 -8
  86. {glplot-0.1.6 → glplot-0.1.8}/tests/test_gui_styles_extra.py +2 -2
  87. {glplot-0.1.6 → glplot-0.1.8}/tests/test_gui_timeline_panel.py +7 -5
  88. {glplot-0.1.6 → glplot-0.1.8}/tests/test_layers.py +0 -1
  89. {glplot-0.1.6 → glplot-0.1.8}/tests/test_mpl_bridge.py +3 -3
  90. {glplot-0.1.6 → glplot-0.1.8}/tests/test_mpl_compat.py +1 -1
  91. {glplot-0.1.6 → glplot-0.1.8}/tests/test_mpl_parity_surface.py +7 -0
  92. {glplot-0.1.6 → glplot-0.1.8}/tests/test_objects3d_preview.py +9 -7
  93. {glplot-0.1.6 → glplot-0.1.8}/tests/test_options.py +0 -2
  94. {glplot-0.1.6 → glplot-0.1.8}/tests/test_outline_2d.py +2 -2
  95. {glplot-0.1.6 → glplot-0.1.8}/tests/test_panels.py +43 -1
  96. {glplot-0.1.6 → glplot-0.1.8}/tests/test_polyline_lod.py +2 -7
  97. {glplot-0.1.6 → glplot-0.1.8}/tests/test_pyplot.py +23 -0
  98. {glplot-0.1.6 → glplot-0.1.8}/tests/test_pyplot_integration.py +2 -2
  99. {glplot-0.1.6 → glplot-0.1.8}/tests/test_regression.py +1 -1
  100. {glplot-0.1.6 → glplot-0.1.8}/tests/test_robustness.py +3 -3
  101. {glplot-0.1.6 → glplot-0.1.8}/tests/test_scatter_renderer.py +2 -2
  102. glplot-0.1.6/.claude/agents/glplot-api-analyzer.md +0 -67
  103. glplot-0.1.6/.claude/agents/glplot-bug-reporter.md +0 -83
  104. glplot-0.1.6/.claude/agents/glplot-documentation-auditor.md +0 -80
  105. glplot-0.1.6/.claude/agents/glplot-performance-profiler.md +0 -76
  106. glplot-0.1.6/.claude/agents/glplot-release-manager.md +0 -80
  107. glplot-0.1.6/.claude/agents/glplot-test-runner.md +0 -57
  108. glplot-0.1.6/.github/workflows/build.yml +0 -37
  109. glplot-0.1.6/.github/workflows/lint.yml +0 -33
  110. glplot-0.1.6/.github/workflows/tests.yml +0 -42
  111. glplot-0.1.6/.gitlab-ci.yml +0 -107
  112. glplot-0.1.6/.readthedocs.yml +0 -43
  113. glplot-0.1.6/CODE_OF_CONDUCT.md +0 -47
  114. glplot-0.1.6/CONTRIBUTING.md +0 -98
  115. glplot-0.1.6/DOCUMENTATION_SETUP.md +0 -210
  116. glplot-0.1.6/GLPlot_Architecture_and_Mathematical_Formulation.md +0 -260
  117. glplot-0.1.6/JOSS_READINESS.md +0 -158
  118. glplot-0.1.6/PKG-INFO +0 -433
  119. glplot-0.1.6/PUBLICATION_CHECKLIST.md +0 -104
  120. glplot-0.1.6/PUBLICATION_WORKFLOW.md +0 -384
  121. glplot-0.1.6/README.md +0 -391
  122. glplot-0.1.6/READY_FOR_PUBLICATION.md +0 -253
  123. glplot-0.1.6/build_and_upload.sh +0 -77
  124. glplot-0.1.6/docs/Makefile +0 -148
  125. glplot-0.1.6/docs/README.md +0 -244
  126. glplot-0.1.6/docs/requirements.txt +0 -7
  127. glplot-0.1.6/docs/source/_static/custom.css +0 -119
  128. glplot-0.1.6/docs/source/api/core.rst +0 -26
  129. glplot-0.1.6/docs/source/api/layers.rst +0 -77
  130. glplot-0.1.6/docs/source/api/managers.rst +0 -66
  131. glplot-0.1.6/docs/source/api/plotting.rst +0 -63
  132. glplot-0.1.6/docs/source/api/utilities.rst +0 -65
  133. glplot-0.1.6/docs/source/conf.py +0 -88
  134. glplot-0.1.6/docs/source/dev/architecture.rst +0 -639
  135. glplot-0.1.6/docs/source/dev/contributing.rst +0 -636
  136. glplot-0.1.6/docs/source/dev/index.rst +0 -236
  137. glplot-0.1.6/docs/source/dev/testing.rst +0 -811
  138. glplot-0.1.6/docs/source/gallery/gallery.rst +0 -102
  139. glplot-0.1.6/docs/source/guide/2d-plotting.rst +0 -832
  140. glplot-0.1.6/docs/source/guide/3d-visualization.rst +0 -925
  141. glplot-0.1.6/docs/source/guide/advanced-features.rst +0 -1028
  142. glplot-0.1.6/docs/source/guide/basic-plotting.rst +0 -258
  143. glplot-0.1.6/docs/source/guide/installation.rst +0 -115
  144. glplot-0.1.6/docs/source/guide/performance-tips.rst +0 -184
  145. glplot-0.1.6/docs/source/guide/quickstart.rst +0 -200
  146. glplot-0.1.6/docs/source/index.rst +0 -52
  147. glplot-0.1.6/examples/benchmark/01_line_density.py +0 -263
  148. glplot-0.1.6/examples/benchmark/02_gpu_comparison.py +0 -635
  149. glplot-0.1.6/examples/benchmark/03_density_quality_comparison.py +0 -221
  150. glplot-0.1.6/examples/benchmark/04_hvplot_datashader_interactive.py +0 -83
  151. glplot-0.1.6/examples/benchmark/05_pipeline_diagram.py +0 -503
  152. glplot-0.1.6/examples/benchmark/results/datashader_density_1000.png +0 -0
  153. glplot-0.1.6/examples/benchmark/results/datashader_density_10000.png +0 -0
  154. glplot-0.1.6/examples/benchmark/results/datashader_density_100000.png +0 -0
  155. glplot-0.1.6/examples/benchmark/results/datashader_density_1000000.png +0 -0
  156. glplot-0.1.6/examples/benchmark/results/datashader_density_10000000.png +0 -0
  157. glplot-0.1.6/examples/benchmark/results/density_quality_comparison.png +0 -0
  158. glplot-0.1.6/examples/benchmark/results/density_quality_fastplotlib.png +0 -0
  159. glplot-0.1.6/examples/benchmark/results/density_quality_glplot.png +0 -0
  160. glplot-0.1.6/examples/benchmark/results/density_quality_vispy.png +0 -0
  161. glplot-0.1.6/examples/benchmark/results/fastplotlib_gpu_lines_10.png +0 -0
  162. glplot-0.1.6/examples/benchmark/results/fastplotlib_gpu_lines_100.png +0 -0
  163. glplot-0.1.6/examples/benchmark/results/fastplotlib_gpu_lines_1000.png +0 -0
  164. glplot-0.1.6/examples/benchmark/results/fastplotlib_gpu_lines_10000.png +0 -0
  165. glplot-0.1.6/examples/benchmark/results/fastplotlib_gpu_lines_100000.png +0 -0
  166. glplot-0.1.6/examples/benchmark/results/fastplotlib_gpu_lines_1000000.png +0 -0
  167. glplot-0.1.6/examples/benchmark/results/fastplotlib_gpu_lines_10000000.png +0 -0
  168. glplot-0.1.6/examples/benchmark/results/glplot_density_10.png +0 -0
  169. glplot-0.1.6/examples/benchmark/results/glplot_density_100.png +0 -0
  170. glplot-0.1.6/examples/benchmark/results/glplot_density_1000.png +0 -0
  171. glplot-0.1.6/examples/benchmark/results/glplot_density_10000.png +0 -0
  172. glplot-0.1.6/examples/benchmark/results/glplot_density_100000.png +0 -0
  173. glplot-0.1.6/examples/benchmark/results/glplot_density_1000000.png +0 -0
  174. glplot-0.1.6/examples/benchmark/results/glplot_gpu_density_10.png +0 -0
  175. glplot-0.1.6/examples/benchmark/results/glplot_gpu_density_100.png +0 -0
  176. glplot-0.1.6/examples/benchmark/results/glplot_gpu_density_1000.png +0 -0
  177. glplot-0.1.6/examples/benchmark/results/glplot_gpu_density_10000.png +0 -0
  178. glplot-0.1.6/examples/benchmark/results/glplot_gpu_density_100000.png +0 -0
  179. glplot-0.1.6/examples/benchmark/results/glplot_gpu_density_1000000.png +0 -0
  180. glplot-0.1.6/examples/benchmark/results/glplot_gpu_density_10000000.png +0 -0
  181. glplot-0.1.6/examples/benchmark/results/glplot_gpu_density_100000000.png +0 -0
  182. glplot-0.1.6/examples/benchmark/results/glplot_gpu_exact_10.png +0 -0
  183. glplot-0.1.6/examples/benchmark/results/glplot_gpu_exact_100.png +0 -0
  184. glplot-0.1.6/examples/benchmark/results/glplot_gpu_exact_1000.png +0 -0
  185. glplot-0.1.6/examples/benchmark/results/glplot_gpu_exact_10000.png +0 -0
  186. glplot-0.1.6/examples/benchmark/results/glplot_gpu_exact_100000.png +0 -0
  187. glplot-0.1.6/examples/benchmark/results/glplot_gpu_exact_1000000.png +0 -0
  188. glplot-0.1.6/examples/benchmark/results/glplot_gpu_exact_10000000.png +0 -0
  189. glplot-0.1.6/examples/benchmark/results/glplot_gpu_exact_100000000.png +0 -0
  190. glplot-0.1.6/examples/benchmark/results/glplot_pipeline_diagram.png +0 -0
  191. glplot-0.1.6/examples/benchmark/results/gpu_comparison_benchmark_results.png +0 -0
  192. glplot-0.1.6/examples/benchmark/results/hvplot_density_1000.png +0 -0
  193. glplot-0.1.6/examples/benchmark/results/hvplot_density_10000.png +0 -0
  194. glplot-0.1.6/examples/benchmark/results/hvplot_density_100000.png +0 -0
  195. glplot-0.1.6/examples/benchmark/results/hvplot_density_1000000.png +0 -0
  196. glplot-0.1.6/examples/benchmark/results/hvplot_density_10000000.png +0 -0
  197. glplot-0.1.6/examples/benchmark/results/hvplot_lines_1000.png +0 -0
  198. glplot-0.1.6/examples/benchmark/results/hvplot_lines_10000.png +0 -0
  199. glplot-0.1.6/examples/benchmark/results/hvplot_lines_100000.png +0 -0
  200. glplot-0.1.6/examples/benchmark/results/line_density_benchmark_results.png +0 -0
  201. glplot-0.1.6/examples/benchmark/results/matplotlib_density_10.png +0 -0
  202. glplot-0.1.6/examples/benchmark/results/matplotlib_density_100.png +0 -0
  203. glplot-0.1.6/examples/benchmark/results/matplotlib_density_1000.png +0 -0
  204. glplot-0.1.6/examples/benchmark/results/matplotlib_density_10000.png +0 -0
  205. glplot-0.1.6/examples/benchmark/results/matplotlib_density_100000.png +0 -0
  206. glplot-0.1.6/examples/benchmark/results/matplotlib_density_1000000.png +0 -0
  207. glplot-0.1.6/examples/benchmark/results/matplotlib_lines_10.png +0 -0
  208. glplot-0.1.6/examples/benchmark/results/matplotlib_lines_100.png +0 -0
  209. glplot-0.1.6/examples/benchmark/results/matplotlib_lines_1000.png +0 -0
  210. glplot-0.1.6/examples/benchmark/results/matplotlib_lines_10000.png +0 -0
  211. glplot-0.1.6/examples/benchmark/results/matplotlib_lines_100000.png +0 -0
  212. glplot-0.1.6/examples/benchmark/results/vispy_gpu_lines_10.png +0 -0
  213. glplot-0.1.6/examples/benchmark/results/vispy_gpu_lines_100.png +0 -0
  214. glplot-0.1.6/examples/benchmark/results/vispy_gpu_lines_1000.png +0 -0
  215. glplot-0.1.6/examples/benchmark/results/vispy_gpu_lines_10000.png +0 -0
  216. glplot-0.1.6/examples/benchmark/results/vispy_gpu_lines_100000.png +0 -0
  217. glplot-0.1.6/examples/benchmark/results/vispy_gpu_lines_1000000.png +0 -0
  218. glplot-0.1.6/examples/benchmark/results/vispy_gpu_lines_10000000.png +0 -0
  219. glplot-0.1.6/examples/benchmark/vispy_interactive.py +0 -58
  220. glplot-0.1.6/examples/dataflow.png +0 -0
  221. glplot-0.1.6/examples/ex_aspect_ratio_fix.py +0 -61
  222. glplot-0.1.6/examples/ex_density.py +0 -48
  223. glplot-0.1.6/examples/ex_density_gain.py +0 -21
  224. glplot-0.1.6/examples/ex_expert_performance.py +0 -40
  225. glplot-0.1.6/examples/ex_full_showcase.py +0 -92
  226. glplot-0.1.6/examples/ex_function_plot.py +0 -151
  227. glplot-0.1.6/examples/ex_mandelbrot.py +0 -160
  228. glplot-0.1.6/examples/ex_mpl_bridge.py +0 -71
  229. glplot-0.1.6/examples/ex_read_density.py +0 -36
  230. glplot-0.1.6/examples/ex_scatter.py +0 -47
  231. glplot-0.1.6/examples/ex_simple.py +0 -22
  232. glplot-0.1.6/examples/ex_v2_layers.py +0 -60
  233. glplot-0.1.6/examples/ex_viewports.py +0 -50
  234. glplot-0.1.6/examples/free_energy_demo/compose.py +0 -101
  235. glplot-0.1.6/examples/free_energy_demo/data.py +0 -273
  236. glplot-0.1.6/examples/free_energy_demo/glplot_version.py +0 -608
  237. glplot-0.1.6/examples/free_energy_demo/mpl_version.py +0 -398
  238. glplot-0.1.6/examples/free_energy_demo/results/glplot_free_energy.png +0 -0
  239. glplot-0.1.6/examples/free_energy_demo/results/glplot_panels/a_inset.png +0 -0
  240. glplot-0.1.6/examples/free_energy_demo/results/glplot_panels/a_main.png +0 -0
  241. glplot-0.1.6/examples/free_energy_demo/results/glplot_panels/b_inset.png +0 -0
  242. glplot-0.1.6/examples/free_energy_demo/results/glplot_panels/b_main.png +0 -0
  243. glplot-0.1.6/examples/free_energy_demo/results/glplot_panels/c_inset.png +0 -0
  244. glplot-0.1.6/examples/free_energy_demo/results/glplot_panels/c_main.png +0 -0
  245. glplot-0.1.6/examples/free_energy_demo/results/glplot_panels/d_main.png +0 -0
  246. glplot-0.1.6/examples/free_energy_demo/results/glplot_panels/e_main.png +0 -0
  247. glplot-0.1.6/examples/free_energy_demo/results/glplot_panels/f_main.png +0 -0
  248. glplot-0.1.6/examples/free_energy_demo/results/matplotlib_free_energy.png +0 -0
  249. glplot-0.1.6/examples/free_energy_demo/results/mpl_panels/a_inset.png +0 -0
  250. glplot-0.1.6/examples/free_energy_demo/results/mpl_panels/a_main.png +0 -0
  251. glplot-0.1.6/examples/free_energy_demo/results/mpl_panels/b_inset.png +0 -0
  252. glplot-0.1.6/examples/free_energy_demo/results/mpl_panels/b_main.png +0 -0
  253. glplot-0.1.6/examples/free_energy_demo/results/mpl_panels/c_inset.png +0 -0
  254. glplot-0.1.6/examples/free_energy_demo/results/mpl_panels/c_main.png +0 -0
  255. glplot-0.1.6/examples/free_energy_demo/results/mpl_panels/d_main.png +0 -0
  256. glplot-0.1.6/examples/free_energy_demo/results/mpl_panels/e_main.png +0 -0
  257. glplot-0.1.6/examples/free_energy_demo/results/mpl_panels/f_main.png +0 -0
  258. glplot-0.1.6/examples/gallery/.gitignore +0 -1
  259. glplot-0.1.6/examples/gallery/01_line_plot.py +0 -25
  260. glplot-0.1.6/examples/gallery/02_scatter_fill.py +0 -27
  261. glplot-0.1.6/examples/gallery/03_bar_hist.py +0 -55
  262. glplot-0.1.6/examples/gallery/04_line_family_density.py +0 -32
  263. glplot-0.1.6/examples/gallery/05_guides_and_colormap.py +0 -34
  264. glplot-0.1.6/examples/gallery/06_signal_tools.py +0 -46
  265. glplot-0.1.6/examples/gallery/07_projected_3d_cloud.py +0 -33
  266. glplot-0.1.6/examples/gallery/08_vector_field_quiver.py +0 -39
  267. glplot-0.1.6/examples/gallery/09_large_matrix_heatmap.py +0 -21
  268. glplot-0.1.6/examples/gallery/10_massive_hist2d_density.py +0 -21
  269. glplot-0.1.6/examples/gallery/11_contour_pcolormesh_field.py +0 -32
  270. glplot-0.1.6/examples/gallery/12_surface_wireframe_bar3d.py +0 -60
  271. glplot-0.1.6/examples/gallery/13_volumetric_nebula.py +0 -48
  272. glplot-0.1.6/examples/gallery/14_bar3d_hex_box_city.py +0 -72
  273. glplot-0.1.6/examples/gallery/15_vector_field_3d.py +0 -63
  274. glplot-0.1.6/examples/gallery/16_ssao_comparison.py +0 -46
  275. glplot-0.1.6/examples/gallery/17_square_bars3d.py +0 -41
  276. glplot-0.1.6/examples/gallery/18_hex_bars3d.py +0 -40
  277. glplot-0.1.6/examples/gallery/19_turbulent_vector_field_3d.py +0 -106
  278. glplot-0.1.6/examples/gallery/20_categorical_bar_and_spines.py +0 -21
  279. glplot-0.1.6/examples/gallery/21_date_axis_and_text_bbox.py +0 -37
  280. glplot-0.1.6/examples/gallery/22_log_scale_plots.py +0 -21
  281. glplot-0.1.6/examples/gallery/23_symlog_scale.py +0 -23
  282. glplot-0.1.6/examples/gallery/24_log_scale_bar_chart.py +0 -18
  283. glplot-0.1.6/examples/gallery/25_log_scale_contourf.py +0 -21
  284. glplot-0.1.6/examples/gallery/26_logit_scale.py +0 -21
  285. glplot-0.1.6/examples/gallery/27_inset_axes_image.py +0 -51
  286. glplot-0.1.6/examples/gallery/README.md +0 -37
  287. glplot-0.1.6/examples/gallery/_preview.py +0 -1
  288. glplot-0.1.6/examples/gallery/results/.cache/matplotlib/fontlist-v330.json +0 -4884
  289. glplot-0.1.6/examples/gallery/results/.gitignore +0 -1
  290. glplot-0.1.6/examples/gallery/results/01_line_plot.png +0 -0
  291. glplot-0.1.6/examples/gallery/results/02_scatter_fill.png +0 -0
  292. glplot-0.1.6/examples/gallery/results/03_bar_hist.png +0 -0
  293. glplot-0.1.6/examples/gallery/results/04_line_family_density.png +0 -0
  294. glplot-0.1.6/examples/gallery/results/05_guides_and_colormap.png +0 -0
  295. glplot-0.1.6/examples/gallery/results/06_signal_tools.png +0 -0
  296. glplot-0.1.6/examples/gallery/results/07_projected_3d_cloud.png +0 -0
  297. glplot-0.1.6/examples/gallery/results/08_vector_field_quiver.png +0 -0
  298. glplot-0.1.6/examples/gallery/results/09_large_matrix_heatmap.png +0 -0
  299. glplot-0.1.6/examples/gallery/results/10_massive_hist2d_density.png +0 -0
  300. glplot-0.1.6/examples/gallery/results/11_contour_pcolormesh_field.png +0 -0
  301. glplot-0.1.6/examples/gallery/results/12_surface_wireframe_bar3d.png +0 -0
  302. glplot-0.1.6/examples/gallery/results/13_volumetric_nebula.png +0 -0
  303. glplot-0.1.6/examples/gallery/results/14_bar3d_hex_box_city.png +0 -0
  304. glplot-0.1.6/examples/gallery/results/15_vector_field_3d.png +0 -0
  305. glplot-0.1.6/examples/gallery/results/16_ssao_comparison.png +0 -0
  306. glplot-0.1.6/examples/gallery/results/17_square_bars3d.png +0 -0
  307. glplot-0.1.6/examples/gallery/results/18_hex_bars3d.png +0 -0
  308. glplot-0.1.6/examples/gallery/results/19_turbulent_vector_field_3d.png +0 -0
  309. glplot-0.1.6/examples/gallery/results/20_categorical_bar_and_spines.png +0 -0
  310. glplot-0.1.6/examples/gallery/results/21_date_axis_and_text_bbox.png +0 -0
  311. glplot-0.1.6/examples/gallery/results/22_log_scale_plots.png +0 -0
  312. glplot-0.1.6/examples/gallery/results/23_symlog_scale.png +0 -0
  313. glplot-0.1.6/examples/gallery/results/24_log_scale_bar_chart.png +0 -0
  314. glplot-0.1.6/examples/gallery/results/25_log_scale_contourf.png +0 -0
  315. glplot-0.1.6/examples/gallery/results/26_logit_scale.png +0 -0
  316. glplot-0.1.6/examples/gallery/results/27_inset_axes_image.png +0 -0
  317. glplot-0.1.6/examples/gallery/run_gallery.py +0 -39
  318. glplot-0.1.6/examples/showcase/01_colorful_particles_2d.py +0 -33
  319. glplot-0.1.6/examples/showcase/02_mandelbrot_zoom_2d.py +0 -50
  320. glplot-0.1.6/examples/showcase/03_spinning_torus_3d.py +0 -36
  321. glplot-0.1.6/examples/showcase/04_cosmic_sphere_3d.py +0 -45
  322. glplot-0.1.6/examples/showcase/README.md +0 -207
  323. glplot-0.1.6/examples/verify_polyline_cmap.py +0 -36
  324. glplot-0.1.6/glplot/utils/__init__.py +0 -0
  325. glplot-0.1.6/paper.md +0 -112
  326. glplot-0.1.6/plot_1784808407.png +0 -0
  327. glplot-0.1.6/scratch/check_gl_limits.py +0 -36
  328. glplot-0.1.6/scratch/check_runtime_math.py +0 -41
  329. glplot-0.1.6/scratch/diag_view.py +0 -62
  330. glplot-0.1.6/scratch/smoke_test.py +0 -24
  331. glplot-0.1.6/scratch/test_asymmetric_projection.py +0 -82
  332. glplot-0.1.6/scratch/test_autoscale_all.py +0 -38
  333. glplot-0.1.6/scratch/test_modular_export.py +0 -35
  334. glplot-0.1.6/tests/verify_blending_extension.py +0 -50
  335. glplot-0.1.6/tests/verify_density.py +0 -28
  336. glplot-0.1.6/tests/verify_headless.py +0 -28
  337. glplot-0.1.6/tests/verify_phase4.py +0 -34
  338. glplot-0.1.6/tests/verify_phase5_density.py +0 -45
  339. glplot-0.1.6/tools/README.md +0 -176
  340. glplot-0.1.6/tools/check_gl_capabilities.py +0 -107
  341. glplot-0.1.6/tools/diagnose_camera_state.py +0 -126
  342. glplot-0.1.6/tools/validate_runtime_math.py +0 -126
  343. {glplot-0.1.6 → glplot-0.1.8}/CHANGELOG.md +0 -0
  344. {glplot-0.1.6 → glplot-0.1.8}/LICENSE +0 -0
  345. {glplot-0.1.6 → glplot-0.1.8}/glplot/__main__.py +0 -0
  346. {glplot-0.1.6 → glplot-0.1.8}/glplot/anim/__init__.py +0 -0
  347. {glplot-0.1.6 → glplot-0.1.8}/glplot/anim/applier.py +0 -0
  348. {glplot-0.1.6 → glplot-0.1.8}/glplot/anim/primitives.py +0 -0
  349. {glplot-0.1.6 → glplot-0.1.8}/glplot/backend.py +0 -0
  350. {glplot-0.1.6 → glplot-0.1.8}/glplot/core/__init__.py +0 -0
  351. {glplot-0.1.6 → glplot-0.1.8}/glplot/core/layout.py +0 -0
  352. {glplot-0.1.6 → glplot-0.1.8}/glplot/core/legacy.py +0 -0
  353. {glplot-0.1.6 → glplot-0.1.8}/glplot/core/panel.py +0 -0
  354. {glplot-0.1.6 → glplot-0.1.8}/glplot/gui/__init__.py +0 -0
  355. {glplot-0.1.6 → glplot-0.1.8}/glplot/gui/app.py +0 -0
  356. {glplot-0.1.6 → glplot-0.1.8}/glplot/gui/clipboard.py +0 -0
  357. {glplot-0.1.6 → glplot-0.1.8}/glplot/gui/commands.py +0 -0
  358. {glplot-0.1.6 → glplot-0.1.8}/glplot/gui/dataio.py +0 -0
  359. {glplot-0.1.6 → glplot-0.1.8}/glplot/gui/datasets.py +0 -0
  360. {glplot-0.1.6 → glplot-0.1.8}/glplot/gui/expressions.py +0 -0
  361. {glplot-0.1.6 → glplot-0.1.8}/glplot/gui/fuzzy.py +0 -0
  362. {glplot-0.1.6 → glplot-0.1.8}/glplot/gui/history.py +0 -0
  363. {glplot-0.1.6 → glplot-0.1.8}/glplot/gui/layerops.py +0 -0
  364. {glplot-0.1.6 → glplot-0.1.8}/glplot/gui/layerops3d.py +0 -0
  365. {glplot-0.1.6 → glplot-0.1.8}/glplot/gui/panels/__init__.py +0 -0
  366. {glplot-0.1.6 → glplot-0.1.8}/glplot/gui/panels/base.py +0 -0
  367. {glplot-0.1.6 → glplot-0.1.8}/glplot/gui/pipeline.py +0 -0
  368. {glplot-0.1.6 → glplot-0.1.8}/glplot/managers/__init__.py +0 -0
  369. {glplot-0.1.6 → glplot-0.1.8}/glplot/options.py +0 -0
  370. {glplot-0.1.6 → glplot-0.1.8}/glplot/renderers/__init__.py +0 -0
  371. {glplot-0.1.6 → glplot-0.1.8}/glplot/renderers/base.py +0 -0
  372. {glplot-0.1.6 → glplot-0.1.8}/glplot/renderers/exact.py +0 -0
  373. {glplot-0.1.6 → glplot-0.1.8}/glplot/renderers/fractal.py +0 -0
  374. {glplot-0.1.6 → glplot-0.1.8}/glplot/renderers/geometry3d.py +0 -0
  375. {glplot-0.1.6 → glplot-0.1.8}/glplot/renderers/interaction.py +0 -0
  376. {glplot-0.1.6 → glplot-0.1.8}/glplot/renderers/polyline.py +0 -0
  377. {glplot-0.1.6/glplot/scratch → glplot-0.1.8/glplot/utils}/__init__.py +0 -0
  378. {glplot-0.1.6 → glplot-0.1.8}/glplot/utils/blending.py +0 -0
  379. {glplot-0.1.6 → glplot-0.1.8}/glplot/utils/export.py +0 -0
  380. {glplot-0.1.6 → glplot-0.1.8}/glplot/utils/mpl_bridge.py +0 -0
  381. {glplot-0.1.6 → glplot-0.1.8}/glplot/utils/mpl_process.py +0 -0
  382. {glplot-0.1.6 → glplot-0.1.8}/glplot/utils/scale.py +0 -0
  383. {glplot-0.1.6 → glplot-0.1.8}/tests/test_anim_applier.py +0 -0
  384. {glplot-0.1.6 → glplot-0.1.8}/tests/test_anim_export.py +0 -0
  385. {glplot-0.1.6 → glplot-0.1.8}/tests/test_anim_primitives.py +0 -0
  386. {glplot-0.1.6 → glplot-0.1.8}/tests/test_animation_integration.py +0 -0
  387. {glplot-0.1.6 → glplot-0.1.8}/tests/test_blending_3d.py +0 -0
  388. {glplot-0.1.6 → glplot-0.1.8}/tests/test_camera3d.py +0 -0
  389. {glplot-0.1.6 → glplot-0.1.8}/tests/test_compositing_3d.py +0 -0
  390. {glplot-0.1.6 → glplot-0.1.8}/tests/test_compositing_api.py +0 -0
  391. {glplot-0.1.6 → glplot-0.1.8}/tests/test_dataio.py +0 -0
  392. {glplot-0.1.6 → glplot-0.1.8}/tests/test_density_tint.py +0 -0
  393. {glplot-0.1.6 → glplot-0.1.8}/tests/test_edge_cases.py +0 -0
  394. {glplot-0.1.6 → glplot-0.1.8}/tests/test_effects_post.py +0 -0
  395. {glplot-0.1.6 → glplot-0.1.8}/tests/test_encodings.py +0 -0
  396. {glplot-0.1.6 → glplot-0.1.8}/tests/test_engine.py +0 -0
  397. {glplot-0.1.6 → glplot-0.1.8}/tests/test_fractal.py +0 -0
  398. {glplot-0.1.6 → glplot-0.1.8}/tests/test_generators3d.py +0 -0
  399. {glplot-0.1.6 → glplot-0.1.8}/tests/test_generators3d_extra.py +0 -0
  400. {glplot-0.1.6 → glplot-0.1.8}/tests/test_gui_clipboard.py +0 -0
  401. {glplot-0.1.6 → glplot-0.1.8}/tests/test_gui_commands.py +0 -0
  402. {glplot-0.1.6 → glplot-0.1.8}/tests/test_gui_data_editor.py +0 -0
  403. {glplot-0.1.6 → glplot-0.1.8}/tests/test_gui_datasets.py +0 -0
  404. {glplot-0.1.6 → glplot-0.1.8}/tests/test_gui_dynamics.py +0 -0
  405. {glplot-0.1.6 → glplot-0.1.8}/tests/test_gui_engine_integration.py +0 -0
  406. {glplot-0.1.6 → glplot-0.1.8}/tests/test_gui_expressions.py +0 -0
  407. {glplot-0.1.6 → glplot-0.1.8}/tests/test_gui_fields.py +0 -0
  408. {glplot-0.1.6 → glplot-0.1.8}/tests/test_gui_fuzzy.py +0 -0
  409. {glplot-0.1.6 → glplot-0.1.8}/tests/test_gui_history.py +0 -0
  410. {glplot-0.1.6 → glplot-0.1.8}/tests/test_gui_impostor_alignment.py +0 -0
  411. {glplot-0.1.6 → glplot-0.1.8}/tests/test_gui_keyboard_capture.py +0 -0
  412. {glplot-0.1.6 → glplot-0.1.8}/tests/test_gui_layer_colormaps.py +0 -0
  413. {glplot-0.1.6 → glplot-0.1.8}/tests/test_gui_mathops.py +0 -0
  414. {glplot-0.1.6 → glplot-0.1.8}/tests/test_gui_regression_r2.py +0 -0
  415. {glplot-0.1.6 → glplot-0.1.8}/tests/test_gui_scene_order.py +0 -0
  416. {glplot-0.1.6 → glplot-0.1.8}/tests/test_gui_styles.py +0 -0
  417. {glplot-0.1.6 → glplot-0.1.8}/tests/test_helpers.py +0 -0
  418. {glplot-0.1.6 → glplot-0.1.8}/tests/test_impostor_scatter_fidelity.py +0 -0
  419. {glplot-0.1.6 → glplot-0.1.8}/tests/test_layerops3d.py +0 -0
  420. {glplot-0.1.6 → glplot-0.1.8}/tests/test_mpl_compat_3d.py +0 -0
  421. {glplot-0.1.6 → glplot-0.1.8}/tests/test_mpl_process.py +0 -0
  422. {glplot-0.1.6 → glplot-0.1.8}/tests/test_outline.py +0 -0
  423. {glplot-0.1.6 → glplot-0.1.8}/tests/test_performance_benchmarks.py +0 -0
  424. {glplot-0.1.6 → glplot-0.1.8}/tests/test_plot_style_api.py +0 -0
  425. {glplot-0.1.6 → glplot-0.1.8}/tests/test_pyplot_3d.py +0 -0
  426. {glplot-0.1.6 → glplot-0.1.8}/tests/test_selection_model.py +0 -0
  427. {glplot-0.1.6 → glplot-0.1.8}/tests/test_timeline.py +0 -0
@@ -63,6 +63,10 @@ imgui.ini
63
63
  *.temp
64
64
  .scratch/
65
65
 
66
+ # Benchmark comparison output (regenerated locally, not referenced by any doc;
67
+ # unlike examples/gallery/results, which IS embedded in README.md and must stay tracked)
68
+ examples/benchmark/results/
69
+
66
70
  # Claude Code (local settings only, keep agents/)
67
71
  .claude/settings.json
68
72
  .claude/settings.local.json
@@ -1,21 +1,26 @@
1
1
  cff-version: 1.2.0
2
2
  title: GLPlot - High-Performance GPU-Accelerated Plotting Library for Python
3
- message: "If you use GLPlot in your research, please cite it as below. Scientific paper with full benchmarks and technical details is in preparation."
3
+ message: >-
4
+ If you use GLPlot in your research, please cite it as below. Felix Riccius, Julian
5
+ Holland and Gianmarco Ducci contributed equally to this work.
4
6
  type: software
5
7
  authors:
6
8
  - family-names: Lombardi
7
9
  given-names: Juan Manuel
8
10
  email: lombardi@fhi-berlin.mpg.de
9
11
  affiliation: "Fritz Haber Institute of the Max Planck Society"
10
- orcid: "https://orcid.org/0000-0000-0000-0000"
12
+ orcid: "https://orcid.org/0009-0002-3961-1426"
13
+ - family-names: Riccius
14
+ given-names: Felix
15
+ - family-names: Holland
16
+ given-names: Julian
17
+ - family-names: Ducci
18
+ given-names: Gianmarco
11
19
  identifiers:
12
20
  - type: url
13
21
  value: "https://github.com/AkarisDimitry/GLPlot"
14
22
  - type: url
15
23
  value: "https://gitlab.mpcdf.mpg.de/jmlombardi/glplot"
16
- - type: doi
17
- description: "Zenodo deposit (pending - will be assigned upon publication)"
18
- value: "10.5281/zenodo.pending"
19
24
  repository-code: "https://github.com/AkarisDimitry/GLPlot"
20
25
  repository: "https://github.com/AkarisDimitry/GLPlot"
21
26
  url: "https://github.com/AkarisDimitry/GLPlot"
@@ -41,6 +46,6 @@ keywords:
41
46
  - data visualization
42
47
  license: MIT
43
48
  status: "active development"
44
- version: 0.1.3
45
- date-released: 2026-07-07
49
+ version: 0.1.7
50
+ date-released: 2026-08-18
46
51
  development-status: "Beta"
glplot-0.1.8/PKG-INFO ADDED
@@ -0,0 +1,594 @@
1
+ Metadata-Version: 2.4
2
+ Name: glplot
3
+ Version: 0.1.8
4
+ Summary: High-performance OpenGL plotting library for Python
5
+ Project-URL: Homepage, https://github.com/AkarisDimitry/GLPlot
6
+ Project-URL: Repository, https://github.com/AkarisDimitry/GLPlot
7
+ Project-URL: Issues, https://github.com/AkarisDimitry/GLPlot/issues
8
+ Author: Felix Riccius, Julian Holland, Gianmarco Ducci
9
+ Author-email: Juan Manuel Lombardi <lombardi@fhi-berlin.mpg.de>
10
+ License: MIT
11
+ License-File: LICENSE
12
+ Keywords: gpu,opengl,plotting,scientific plotting,visualization
13
+ Classifier: Development Status :: 3 - Alpha
14
+ Classifier: Intended Audience :: Developers
15
+ Classifier: Intended Audience :: Science/Research
16
+ Classifier: License :: OSI Approved :: MIT License
17
+ Classifier: Operating System :: OS Independent
18
+ Classifier: Programming Language :: Python :: 3
19
+ Classifier: Programming Language :: Python :: 3.11
20
+ Classifier: Programming Language :: Python :: 3.12
21
+ Classifier: Programming Language :: Python :: 3.13
22
+ Classifier: Topic :: Scientific/Engineering :: Visualization
23
+ Classifier: Topic :: Software Development :: Libraries :: Python Modules
24
+ Requires-Python: >=3.11
25
+ Requires-Dist: glfw>=2.5
26
+ Requires-Dist: imgui-bundle>=1.92
27
+ Requires-Dist: matplotlib<3.10,>=3.6
28
+ Requires-Dist: numpy>=1.23
29
+ Requires-Dist: pyopengl>=3.1.6
30
+ Requires-Dist: scipy>=1.9
31
+ Provides-Extra: dev
32
+ Requires-Dist: build>=1.0; extra == 'dev'
33
+ Requires-Dist: pytest-cov>=4.0; extra == 'dev'
34
+ Requires-Dist: pytest-mock>=3.10; extra == 'dev'
35
+ Requires-Dist: pytest>=7.0; extra == 'dev'
36
+ Requires-Dist: twine>=4.0; extra == 'dev'
37
+ Provides-Extra: test
38
+ Requires-Dist: pytest-cov>=4.0; extra == 'test'
39
+ Requires-Dist: pytest-mock>=3.10; extra == 'test'
40
+ Requires-Dist: pytest>=7.0; extra == 'test'
41
+ Description-Content-Type: text/markdown
42
+
43
+ # GLPlot: GPU-Accelerated Plotting for Python
44
+
45
+ [![Tests](https://github.com/AkarisDimitry/GLPlot/workflows/Tests/badge.svg)](https://github.com/AkarisDimitry/GLPlot/actions/workflows/tests.yml)
46
+ [![Lint](https://github.com/AkarisDimitry/GLPlot/workflows/Lint/badge.svg)](https://github.com/AkarisDimitry/GLPlot/actions/workflows/lint.yml)
47
+ [![Build](https://github.com/AkarisDimitry/GLPlot/workflows/Build/badge.svg)](https://github.com/AkarisDimitry/GLPlot/actions/workflows/build.yml)
48
+ [![License: MIT](https://img.shields.io/badge/License-MIT-yellow.svg)](LICENSE)
49
+ [![Python Version](https://img.shields.io/badge/Python-3.11+-blue.svg)](pyproject.toml)
50
+
51
+ GLPlot is a Python plotting library with a Matplotlib-like API that renders on the GPU
52
+ through OpenGL instead of the CPU. Plots that make Matplotlib chug — millions of points,
53
+ dense line families, large 3D scenes — stay interactive: smooth pan, zoom, and rotation,
54
+ even at that scale. If you already know `plt.plot()` / `plt.scatter()`, most of what you
55
+ know carries over directly.
56
+
57
+ ## Install
58
+
59
+ ```bash
60
+ pip install glplot
61
+ ```
62
+
63
+ or from source:
64
+
65
+ ```bash
66
+ git clone https://github.com/AkarisDimitry/GLPlot.git
67
+ cd GLPlot
68
+ pip install -e .
69
+ ```
70
+
71
+ Requires Python 3.11+. Core dependencies: numpy, scipy, matplotlib, glfw, PyOpenGL,
72
+ `imgui-bundle` (for the on-screen control panel).
73
+
74
+ ## 30-second example
75
+
76
+ ```python
77
+ import numpy as np
78
+ import glplot.pyplot as plt
79
+
80
+ x = np.linspace(0, 10, 100)
81
+
82
+ plt.figure("My Plot", figsize=(8, 5))
83
+ plt.plot(x, np.sin(x), "r-", lw=2, label="sin(x)")
84
+ plt.scatter(x[::10], np.sin(x[::10]), c="blue", s=20)
85
+ plt.xlabel("x")
86
+ plt.ylabel("y")
87
+ plt.legend()
88
+ plt.show()
89
+ ```
90
+
91
+ That's it — a real window opens, fully interactive (pan/zoom/rotate) from the first frame.
92
+
93
+ ## Interactive Examples Gallery (Click any figure to view code)
94
+
95
+ Explore 2D plots, 3D scenes, and real-time animations. **Click on any figure or title below to expand its full Python code, or click the file link to view the script.**
96
+
97
+ ### 📊 2D Visualizations
98
+
99
+ <details>
100
+ <summary>
101
+ <img src="examples/gallery/results/02_scatter_fill.png" alt="10M-point spiral scatter" width="650"/>
102
+ <br><b>🔍 Click to view code: 10-Million Point Spiral Scatter (<a href="examples/gallery/02_scatter_fill.py"><code>02_scatter_fill.py</code></a>)</b>
103
+ </summary>
104
+
105
+ 📄 **Full script:** [`examples/gallery/02_scatter_fill.py`](examples/gallery/02_scatter_fill.py)
106
+
107
+ ```python
108
+ import numpy as np
109
+ import glplot.pyplot as plt
110
+
111
+ rng = np.random.default_rng(4)
112
+ n = 10_000_000
113
+ theta = rng.uniform(0, 18 * np.pi, n)
114
+ radius = 0.025 * theta + rng.gamma(1.5, 0.006, n)
115
+ x_pc = radius * np.cos(theta) + rng.normal(scale=0.012, size=n)
116
+ y_pc = radius * np.sin(theta) + rng.normal(scale=0.012, size=n)
117
+ formation_phase = theta + 6.0 * radius # proxy for age along the spiral arm
118
+
119
+ plt.figure("Simulated Spiral Star Field", figsize=(9, 6))
120
+ plt.scatter(x_pc, y_pc, c=formation_phase, cmap="turbo", s=1.5, alpha=0.72)
121
+ plt.title(f"Simulated stellar density along a spiral arm (N = {n:,} stars)")
122
+ plt.xlabel("x (pc)")
123
+ plt.ylabel("y (pc)")
124
+ plt.show()
125
+ ```
126
+ </details>
127
+
128
+ <details>
129
+ <summary>
130
+ <img src="examples/gallery/results/10_massive_hist2d_density.png" alt="10M-sample 2D density histogram" width="650"/>
131
+ <br><b>🔍 Click to view code: 10M-Sample 2D Density Histogram (<a href="examples/gallery/10_massive_hist2d_density.py"><code>10_massive_hist2d_density.py</code></a>)</b>
132
+ </summary>
133
+
134
+ 📄 **Full script:** [`examples/gallery/10_massive_hist2d_density.py`](examples/gallery/10_massive_hist2d_density.py)
135
+
136
+ ```python
137
+ import numpy as np
138
+ import glplot.pyplot as plt
139
+
140
+ rng = np.random.default_rng(123)
141
+ n = 10_000_000
142
+ theta = rng.uniform(0, 2 * np.pi, n)
143
+ r = rng.gamma(shape=2.2, scale=0.8, size=n)
144
+ mm_per_unit = 10.0
145
+ x = mm_per_unit * (r * np.cos(theta) + rng.normal(scale=0.08, size=n))
146
+ y = mm_per_unit * (r * np.sin(theta) + rng.normal(scale=0.08, size=n))
147
+
148
+ plt.figure("Detector Impact Density", figsize=(8, 6))
149
+ lim = 45.0
150
+ plt.hist2d(
151
+ x, y,
152
+ bins=170,
153
+ range=[[-lim, lim], [-lim, lim]],
154
+ cmap="plasma",
155
+ s=40.0,
156
+ label=f"{n:,} hits",
157
+ )
158
+ plt.title(f"{n:,}-hit density map on detector plane")
159
+ plt.xlabel("x (mm)")
160
+ plt.ylabel("y (mm)")
161
+ plt.legend()
162
+ plt.show()
163
+ ```
164
+ </details>
165
+
166
+ <details>
167
+ <summary>
168
+ <img src="examples/gallery/results/01_line_plot.png" alt="10,072-line oscilloscope ensemble" width="650"/>
169
+ <br><b>🔍 Click to view code: 10,072-Line Oscilloscope Ensemble (<a href="examples/gallery/01_line_plot.py"><code>01_line_plot.py</code></a>)</b>
170
+ </summary>
171
+
172
+ 📄 **Full script:** [`examples/gallery/01_line_plot.py`](examples/gallery/01_line_plot.py)
173
+
174
+ ```python
175
+ import colorsys
176
+ import numpy as np
177
+ import glplot.pyplot as plt
178
+
179
+ def chalk_color(hue: float, rng: np.random.Generator) -> tuple:
180
+ sat = rng.uniform(0.22, 0.42)
181
+ val = rng.uniform(0.90, 1.0)
182
+ return colorsys.hsv_to_rgb(hue % 1.0, sat, val)
183
+
184
+ rng = np.random.default_rng(101)
185
+ n_channels = 10_072
186
+ n_points = 180
187
+ t = np.linspace(0, 40 * np.pi, n_points)
188
+ t_ms = t * (50.0 / (40 * np.pi))
189
+ stimulus = np.sin(t) + 0.35 * np.sin(2.7 * t)
190
+
191
+ plt.figure("Oscilloscope Ensemble", figsize=(9, 5))
192
+ plt.plot_style("chalk", layers=False)
193
+
194
+ frac = np.linspace(0.0, 1.0, n_channels)
195
+ hues = (rng.uniform(0, 1) + frac + rng.uniform(-0.02, 0.02, n_channels)) % 1.0
196
+
197
+ for i in range(n_channels):
198
+ t_frac = frac[i]
199
+ phase = rng.uniform(0, 2 * np.pi)
200
+ amp = 0.12 + 0.781 * t_frac
201
+ freq = 1.1 + 0.852 * t_frac
202
+ offset = 3.195 * t_frac
203
+ channel = stimulus + amp * np.sin(freq * t + phase)
204
+ color = chalk_color(hues[i], rng)
205
+ plt.plot(t_ms, channel + offset, color=(*color, 0.35), lw=0.5)
206
+
207
+ plt.plot(t_ms, stimulus + 0.7, color=(0.95, 0.94, 0.90, 1.0), lw=3.0, label="Reference")
208
+ plt.xlabel("Time (ms)")
209
+ plt.ylabel("Amplitude")
210
+ plt.title(f"Traces from {n_channels} oscillator channels")
211
+ plt.legend()
212
+ plt.show()
213
+ ```
214
+ </details>
215
+
216
+ ### 🪐 3D Visualizations
217
+
218
+ <details>
219
+ <summary>
220
+ <img src="examples/gallery/results/07_projected_3d_cloud.png" alt="1M-point 3D Point Cloud" width="650"/>
221
+ <br><b>🔍 Click to view code: 1M-Point Circumstellar Dust Halo (<a href="examples/gallery/07_projected_3d_cloud.py"><code>07_projected_3d_cloud.py</code></a>)</b>
222
+ </summary>
223
+
224
+ 📄 **Full script:** [`examples/gallery/07_projected_3d_cloud.py`](examples/gallery/07_projected_3d_cloud.py)
225
+
226
+ ```python
227
+ import numpy as np
228
+ import glplot.pyplot as plt
229
+
230
+ rng = np.random.default_rng(77)
231
+ n = 1_000_000
232
+ sigma = 42.0
233
+ outer_radius = 2.5 * sigma
234
+ n_gen = 1_140_000
235
+ x = rng.normal(0.0, sigma, n_gen)
236
+ y = rng.normal(0.0, sigma, n_gen)
237
+ z = rng.normal(0.0, sigma, n_gen)
238
+ inside = (x**2 + y**2 + z**2) < outer_radius**2
239
+ x, y, z = x[inside][:n], y[inside][:n], z[inside][:n]
240
+
241
+ plt.figure("Circumstellar Dust Halo", figsize=(9, 6))
242
+ plt.scatter3d(
243
+ x, y, z,
244
+ c=z,
245
+ cmap="viridis",
246
+ s=1.1,
247
+ alpha=0.75,
248
+ elev=22,
249
+ azim=-42,
250
+ label=f"{n:,} grains",
251
+ )
252
+ plt.title(f"Simulated circumstellar dust halo ({n:,} grains)")
253
+ plt.xlabel("x (AU)")
254
+ plt.ylabel("y (AU)")
255
+ plt.zlabel("z (AU)")
256
+ plt.legend()
257
+ plt.show()
258
+ ```
259
+ </details>
260
+
261
+ <details>
262
+ <summary>
263
+ <img src="examples/gallery/results/13_volumetric_nebula.png" alt="1.75M-Point Volumetric Nebula" width="650"/>
264
+ <br><b>🔍 Click to view code: 1.75M-Point Volumetric Nebula (<a href="examples/gallery/13_volumetric_nebula.py"><code>13_volumetric_nebula.py</code></a>)</b>
265
+ </summary>
266
+
267
+ 📄 **Full script:** [`examples/gallery/13_volumetric_nebula.py`](examples/gallery/13_volumetric_nebula.py)
268
+
269
+ ```python
270
+ import numpy as np
271
+ import glplot.pyplot as plt
272
+
273
+ rng = np.random.default_rng(1313)
274
+ n = 1_750_000
275
+ outer_radius = 3.2
276
+ n_gen = 2_000_000
277
+ theta = rng.uniform(0, 8 * np.pi, n_gen)
278
+ phi = rng.normal(0.0, 0.48, n_gen)
279
+ r = rng.gamma(2.0, 0.8, n_gen)
280
+ inside = r < outer_radius
281
+ theta, phi, r = theta[inside][:n], phi[inside][:n], r[inside][:n]
282
+ arm = rng.integers(0, 4, n) * np.pi / 2
283
+ twist = theta + arm + 0.62 * r
284
+ x = r * np.cos(twist) + rng.normal(scale=0.06, size=n)
285
+ y = r * np.sin(twist) + rng.normal(scale=0.06, size=n)
286
+ z = 0.65 * r * np.sin(phi) + 0.18 * np.sin(theta)
287
+ emission = np.exp(-0.12 * r**2) + 0.28 * np.sin(3 * theta) ** 2
288
+
289
+ plt.figure("Volumetric 3D Nebula", figsize=(9, 6))
290
+ plt.volume3d(
291
+ x, y, z, emission,
292
+ threshold=0.14,
293
+ cmap="magma",
294
+ alpha=0.42,
295
+ s=1.2,
296
+ elev=24,
297
+ azim=-52,
298
+ label=f"{n:,} points",
299
+ )
300
+ plt.title(f"{n:,}-point volumetric emission nebula")
301
+ plt.xlabel("x (ly)")
302
+ plt.ylabel("y (ly)")
303
+ plt.zlabel("z (ly)")
304
+ plt.legend()
305
+ plt.show()
306
+ ```
307
+ </details>
308
+
309
+ <details>
310
+ <summary>
311
+ <img src="examples/gallery/results/19_turbulent_vector_field_3d.png" alt="3D Turbulent Vector Field" width="650"/>
312
+ <br><b>🔍 Click to view code: 3D Turbulent Vector Field (<a href="examples/gallery/19_turbulent_vector_field_3d.py"><code>19_turbulent_vector_field_3d.py</code></a>)</b>
313
+ </summary>
314
+
315
+ 📄 **Full script:** [`examples/gallery/19_turbulent_vector_field_3d.py`](examples/gallery/19_turbulent_vector_field_3d.py)
316
+
317
+ ```python
318
+ import numpy as np
319
+ import glplot.pyplot as plt
320
+
321
+ rng = np.random.default_rng(1919)
322
+ cloud_n = 950_000
323
+ t = rng.uniform(0.0, 18.0 * np.pi, cloud_n)
324
+ shell_raw = rng.gamma(2.2, 0.42, cloud_n)
325
+ shell = 2.0 * np.tanh(shell_raw / 2.0)
326
+ twist = 0.22 * np.sin(2.6 * t) + 0.18 * np.cos(1.4 * t)
327
+ cloud_x = shell * np.sin(t) + 0.28 * np.sin(3.0 * t)
328
+ cloud_y = shell * np.cos(1.17 * t) + 0.32 * np.cos(2.4 * t)
329
+ cloud_z = 0.58 * np.sin(0.52 * t + twist) + 0.32 * shell * np.cos(0.33 * t)
330
+ cloud_energy = np.exp(-0.22 * shell**2) + 0.33 * np.sin(1.7 * t) ** 2
331
+
332
+ plt.figure("Turbulent 3D Flow", figsize=(10, 7), ssao=True)
333
+ plt.volume3d(
334
+ cloud_x, cloud_y, cloud_z, cloud_energy,
335
+ threshold=0.22,
336
+ cmap="inferno",
337
+ alpha=0.17,
338
+ s=0.72,
339
+ elev=27,
340
+ azim=-49,
341
+ label=f"{cloud_n:,} volumetric samples",
342
+ )
343
+ plt.title("Massive 3D turbulent swirl")
344
+ plt.xlabel("x")
345
+ plt.ylabel("y")
346
+ plt.zlabel("z")
347
+ plt.legend()
348
+ plt.show()
349
+ ```
350
+ </details>
351
+
352
+ ### 🎬 Animated Visualizations
353
+
354
+ <details>
355
+ <summary>
356
+ <img src="examples/gallery/results/28_chladni_wave_animation.gif" alt="Chladni wave animation" width="650"/>
357
+ <br><b>🔍 Click to view code: Animated Standing-Wave Interference (<a href="examples/gallery/28_chladni_wave_animation.py"><code>28_chladni_wave_animation.py</code></a>)</b>
358
+ </summary>
359
+
360
+ 📄 **Full script:** [`examples/gallery/28_chladni_wave_animation.py`](examples/gallery/28_chladni_wave_animation.py)
361
+
362
+ ```python
363
+ import numpy as np
364
+ import glplot.animation as animation
365
+ import glplot.pyplot as plt
366
+
367
+ N = 360
368
+ x = np.linspace(-1.0, 1.0, N)
369
+ y = np.linspace(-1.0, 1.0, N)
370
+ X, Y = np.meshgrid(x, y)
371
+ FRAMES = 54
372
+
373
+ def chladni_field(m: float, n: float) -> np.ndarray:
374
+ return np.sin(m * np.pi * X) * np.cos(n * np.pi * Y) - np.sin(n * np.pi * X) * np.cos(m * np.pi * Y)
375
+
376
+ def mode_pair(frame: int) -> tuple:
377
+ t = frame / FRAMES
378
+ m = 2.2 + 4.3 * (0.5 - 0.5 * np.cos(2 * np.pi * t))
379
+ n = 3.1 + 3.6 * (0.5 - 0.5 * np.cos(2 * np.pi * t * 1.5 + 1.1))
380
+ return m, n
381
+
382
+ def zoom_span(frame: int) -> float:
383
+ t = frame / FRAMES
384
+ return 0.75 - 0.35 * np.cos(2 * np.pi * t)
385
+
386
+ fig = plt.figure("Animated Standing-Wave Interference", figsize=(7.8, 6.2))
387
+ plt.plot_style("blueprint")
388
+
389
+ def update(frame: int):
390
+ m, n = mode_pair(frame)
391
+ span = zoom_span(frame)
392
+ Z = chladni_field(m, n)
393
+ plt.cla()
394
+ plt.imshow(Z, extent=(-1, 1, -1, 1), origin="lower", cmap="RdBu_r", vmin=-1.0, vmax=1.0, aspect="equal")
395
+ plt.xlim(-span, span)
396
+ plt.ylim(-span, span)
397
+ plt.title(f"Standing-wave interference (m={m:.1f}, n={n:.1f})")
398
+ plt.xlabel("x (plate width)")
399
+ plt.ylabel("y (plate width)")
400
+ return []
401
+
402
+ ani = animation.FuncAnimation(fig, update, frames=FRAMES, interval=42)
403
+ ani.save("chladni_wave_animation.gif", fps=20)
404
+ plt.show()
405
+ ```
406
+ </details>
407
+
408
+ <details>
409
+ <summary>
410
+ <img src="examples/gallery/animations/results/03_spectrum_analyzer_bars.gif" alt="Audio spectrum analyzer bars" width="650"/>
411
+ <br><b>🔍 Click to view code: Real-Time Audio Spectrum Analyzer (<a href="examples/gallery/animations/03_spectrum_analyzer_bars.py"><code>03_spectrum_analyzer_bars.py</code></a>)</b>
412
+ </summary>
413
+
414
+ 📄 **Full script:** [`examples/gallery/animations/03_spectrum_analyzer_bars.py`](examples/gallery/animations/03_spectrum_analyzer_bars.py)
415
+
416
+ ```python
417
+ import numpy as np
418
+ import glplot.animation as animation
419
+ import glplot.pyplot as plt
420
+
421
+ N_BANDS = 64
422
+ FRAMES = 84
423
+ band_x = np.arange(N_BANDS)
424
+
425
+ fig = plt.figure("Audio Spectrum Analyzer", figsize=(9, 5))
426
+
427
+ def update(frame: int):
428
+ t = frame / FRAMES
429
+ levels = -25.0 + 18.0 * np.sin(np.linspace(0.2, 4.0 * np.pi, N_BANDS) + 2.0 * np.pi * t)
430
+ plt.cla()
431
+ plt.bar(band_x, levels, color="tab:cyan", alpha=0.85)
432
+ plt.ylim(-60, 0)
433
+ plt.title("Real-Time 64-Band Spectrum Analyzer")
434
+ plt.xlabel("Frequency Band")
435
+ plt.ylabel("Power (dBFS)")
436
+ return []
437
+
438
+ ani = animation.FuncAnimation(fig, update, frames=FRAMES, interval=33)
439
+ ani.save("spectrum_analyzer.gif", fps=30)
440
+ plt.show()
441
+ ```
442
+ </details>
443
+
444
+ <details>
445
+ <summary>
446
+ <img src="examples/gallery/animations/results/01_orbiting_star_cluster.gif" alt="Orbiting star cluster" width="650"/>
447
+ <br><b>🔍 Click to view code: Differential Keplerian Star Cluster (<a href="examples/gallery/animations/01_orbiting_star_cluster.py"><code>01_orbiting_star_cluster.py</code></a>)</b>
448
+ </summary>
449
+
450
+ 📄 **Full script:** [`examples/gallery/animations/01_orbiting_star_cluster.py`](examples/gallery/animations/01_orbiting_star_cluster.py)
451
+
452
+ ```python
453
+ import numpy as np
454
+ import glplot.animation as animation
455
+ import glplot.pyplot as plt
456
+
457
+ N_STARS = 20_000
458
+ FRAMES = 80
459
+ LIM = 6.8
460
+
461
+ rng = np.random.default_rng(42)
462
+ radius = rng.exponential(scale=1.35, size=N_STARS) + 0.10
463
+ arm_id = rng.integers(0, 3, N_STARS)
464
+ theta0 = arm_id * (2.0 * np.pi / 3) + 1.65 * np.log(radius / 0.10)
465
+ omega = 1.35 / np.sqrt(radius + 0.30)
466
+
467
+ fig = plt.figure("Orbiting Star Cluster", figsize=(8, 8))
468
+
469
+ def update(frame: int):
470
+ t = frame * 0.08
471
+ theta = theta0 + omega * t
472
+ x = radius * np.cos(theta)
473
+ y = radius * np.sin(theta)
474
+ plt.cla()
475
+ plt.scatter(x, y, c=radius, cmap="plasma", s=1.2, alpha=0.8)
476
+ plt.xlim(-LIM, LIM)
477
+ plt.ylim(-LIM, LIM)
478
+ plt.title(f"Differential Keplerian rotation ({N_STARS:,} stars)")
479
+ return []
480
+
481
+ ani = animation.FuncAnimation(fig, update, frames=FRAMES, interval=40)
482
+ ani.save("star_cluster.gif", fps=25)
483
+ plt.show()
484
+ ```
485
+ </details>
486
+
487
+ **All of the above render at 60+ FPS** with interactive panning, zooming, and rotation, regardless of point count. Discover more in the [example gallery](examples/gallery/README.md) (28 static scripts) and the [animated gallery](examples/gallery/animations/README.md) (15 animated scripts).
488
+
489
+ ## Features
490
+
491
+ - **Matplotlib-compatible API** — `plot`, `scatter`, `bar`, `hist`, `hist2d`, `imshow`,
492
+ `contour`/`contourf`, `quiver`, format strings (`"r-o"`, `"b--"`), and more
493
+ - **Millions of points, still interactive** — GPU instancing and density accumulation
494
+ instead of CPU-side geometry construction
495
+ - **Full 2D/3D** — lines, scatter, filled regions, bars, histograms, matrices, surfaces,
496
+ wireframes, 3D bars, vector fields, with SSAO depth shading in 3D
497
+ - **Real multi-panel subplots** — `plt.subplots()`, per-panel interaction
498
+ - **Animation** — `glplot.animation.FuncAnimation`/`ArtistAnimation`, exportable to GIF/video
499
+ - **A live control panel** — `python -m glplot` opens a workstation for editing a scene,
500
+ its layers, and its styling interactively, with undo history
501
+ - **Numerically stable at extreme zoom** — double-precision, viewport-relative coordinate
502
+ transforms avoid the jitter that single-precision GPU pipelines show at large offsets
503
+
504
+ ## Quick Reference Recipes
505
+
506
+ **A million lines at once (`plot_lines`)**
507
+
508
+ Ordinary plotting draws each line as CPU-generated geometry — a million calls to `plot()`
509
+ would build a million separate meshes. `plot_lines` instead uploads each line as an
510
+ `(a, b)` coefficient pair and lets the GPU work out what's visible:
511
+
512
+ ```python
513
+ import numpy as np
514
+ import glplot.pyplot as plt
515
+
516
+ n = 1_000_000
517
+ a = np.random.randn(n)
518
+ b = np.random.randn(n)
519
+
520
+ plt.figure("Density")
521
+ plt.plot_lines(a, b, x_range=(-2, 2))
522
+ plt.show(density=True)
523
+ ```
524
+
525
+ ## How it compares
526
+
527
+ | Feature | GLPlot | Matplotlib | Plotly | Datashader | VisPy |
528
+ |---|---|---|---|---|---|
529
+ | GPU acceleration | ✓ (OpenGL) | ✗ | ✗ | ✓ | ✓ |
530
+ | Matplotlib-style API | ✓ | ✓ | ✗ | ✗ | ✗ |
531
+ | Millions of points, interactive | ✓ | ✗ | Limited | ✓ | ✓ |
532
+ | Interactive 3D | ✓ | Limited | ✓ | Limited | ✓ |
533
+ | Density visualization | ✓ (HDR) | Basic | Limited | ✓ | ✗ |
534
+ | Precision at extreme zoom | ✓ (double precision) | ✓ | Basic | ✓ | ✗ |
535
+
536
+ GLPlot sits between "familiar API, CPU-bound" (Matplotlib) and "GPU-fast, low-level"
537
+ (VisPy): a Matplotlib-shaped surface backed by a GPU renderer.
538
+
539
+ ## Rendering architecture
540
+
541
+ GLPlot runs two rendering pipelines — one for 2D primitives (lines, scatter, density) and
542
+ one for 3D geometry (bars, surfaces, wireframes, `scatter3d`) — both driven from the CPU
543
+ but doing their actual work on the GPU. `glReadPixels` is only ever called for export; the
544
+ interactive path never reads pixels back to the CPU.
545
+
546
+ ![GLPlot rendering pipeline](examples/dataflow.png)
547
+
548
+ See [GLPlot_Architecture_and_Mathematical_Formulation.md](GLPlot_Architecture_and_Mathematical_Formulation.md)
549
+ for the full derivation of each stage, including the density-accumulation math and the
550
+ viewport-relative projection that keeps zoom numerically stable.
551
+
552
+ ## Testing
553
+
554
+ ```bash
555
+ pytest # run everything
556
+ pytest --cov=glplot --cov-report=html # with coverage
557
+ pytest tests/test_pyplot.py::test_plot_accepts_y_only_and_returns_artists # one test
558
+ ```
559
+
560
+ 6,800+ tests, run fully headless (no window is ever displayed) so they work in CI. The
561
+ matrix covers Python 3.11–3.13 on Ubuntu, macOS, and Windows; `black`, `isort`, and `flake8`
562
+ are enforced on every push. See `examples/benchmark/` for reproducible performance
563
+ comparisons against Matplotlib, VisPy, fastplotlib, Datashader, and hvPlot, and `tools/`
564
+ for GPU/environment diagnostics.
565
+
566
+ ## Documentation
567
+
568
+ - API reference: docstrings in `glplot.pyplot`, or the built docs — see [docs/README.md](docs/README.md)
569
+ - Architecture: [GLPlot_Architecture_and_Mathematical_Formulation.md](GLPlot_Architecture_and_Mathematical_Formulation.md)
570
+ - Dev tools: [tools/README.md](tools/README.md)
571
+ - Contributing: [CONTRIBUTING.md](CONTRIBUTING.md) · Code of conduct: [CODE_OF_CONDUCT.md](CODE_OF_CONDUCT.md)
572
+
573
+ ## Citation
574
+
575
+ ```bibtex
576
+ @software{lombardi2026glplot,
577
+ title={GLPlot: High-Performance GPU-Accelerated Plotting Library for Python},
578
+ author={Lombardi, Juan Manuel and Riccius, Felix and Holland, Julian and Ducci, Gianmarco},
579
+ year={2026},
580
+ url={https://github.com/AkarisDimitry/GLPlot},
581
+ doi={10.5281/zenodo.PLACEHOLDER}
582
+ }
583
+ ```
584
+
585
+ See [CITATION.cff](CITATION.cff) for other formats.
586
+
587
+ ## License
588
+
589
+ [MIT](LICENSE).
590
+
591
+ ## Acknowledgments
592
+
593
+ Built on PyOpenGL, GLFW, NumPy, SciPy, Matplotlib, and Dear ImGui — thanks to those
594
+ communities for the foundations this sits on.