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