vispy 0.14.0__cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl

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.

Potentially problematic release.


This version of vispy might be problematic. Click here for more details.

Files changed (519) hide show
  1. vispy/__init__.py +33 -0
  2. vispy/app/__init__.py +15 -0
  3. vispy/app/_default_app.py +76 -0
  4. vispy/app/_detect_eventloop.py +148 -0
  5. vispy/app/application.py +263 -0
  6. vispy/app/backends/__init__.py +52 -0
  7. vispy/app/backends/_egl.py +264 -0
  8. vispy/app/backends/_glfw.py +513 -0
  9. vispy/app/backends/_jupyter_rfb.py +278 -0
  10. vispy/app/backends/_offscreen_util.py +121 -0
  11. vispy/app/backends/_osmesa.py +235 -0
  12. vispy/app/backends/_pyglet.py +451 -0
  13. vispy/app/backends/_pyqt4.py +36 -0
  14. vispy/app/backends/_pyqt5.py +36 -0
  15. vispy/app/backends/_pyqt6.py +40 -0
  16. vispy/app/backends/_pyside.py +37 -0
  17. vispy/app/backends/_pyside2.py +52 -0
  18. vispy/app/backends/_pyside6.py +53 -0
  19. vispy/app/backends/_qt.py +968 -0
  20. vispy/app/backends/_sdl2.py +444 -0
  21. vispy/app/backends/_template.py +244 -0
  22. vispy/app/backends/_test.py +8 -0
  23. vispy/app/backends/_tk.py +800 -0
  24. vispy/app/backends/_wx.py +476 -0
  25. vispy/app/backends/tests/__init__.py +0 -0
  26. vispy/app/backends/tests/test_offscreen_util.py +52 -0
  27. vispy/app/backends/tests/test_rfb.py +77 -0
  28. vispy/app/base.py +294 -0
  29. vispy/app/canvas.py +828 -0
  30. vispy/app/qt.py +92 -0
  31. vispy/app/tests/__init__.py +0 -0
  32. vispy/app/tests/qt-designer.ui +58 -0
  33. vispy/app/tests/test_app.py +442 -0
  34. vispy/app/tests/test_backends.py +164 -0
  35. vispy/app/tests/test_canvas.py +122 -0
  36. vispy/app/tests/test_context.py +92 -0
  37. vispy/app/tests/test_qt.py +47 -0
  38. vispy/app/tests/test_simultaneous.py +134 -0
  39. vispy/app/timer.py +174 -0
  40. vispy/color/__init__.py +17 -0
  41. vispy/color/_color_dict.py +193 -0
  42. vispy/color/color_array.py +447 -0
  43. vispy/color/color_space.py +181 -0
  44. vispy/color/colormap.py +1134 -0
  45. vispy/color/tests/__init__.py +0 -0
  46. vispy/color/tests/test_color.py +352 -0
  47. vispy/conftest.py +12 -0
  48. vispy/ext/__init__.py +0 -0
  49. vispy/ext/cocoapy.py +1542 -0
  50. vispy/ext/cubehelix.py +138 -0
  51. vispy/ext/egl.py +375 -0
  52. vispy/ext/fontconfig.py +118 -0
  53. vispy/ext/gdi32plus.py +206 -0
  54. vispy/ext/osmesa.py +105 -0
  55. vispy/geometry/__init__.py +23 -0
  56. vispy/geometry/_triangulation_debugger.py +171 -0
  57. vispy/geometry/calculations.py +134 -0
  58. vispy/geometry/curves.py +399 -0
  59. vispy/geometry/generation.py +643 -0
  60. vispy/geometry/isocurve.py +175 -0
  61. vispy/geometry/isosurface.py +465 -0
  62. vispy/geometry/meshdata.py +698 -0
  63. vispy/geometry/normals.py +78 -0
  64. vispy/geometry/parametric.py +56 -0
  65. vispy/geometry/polygon.py +137 -0
  66. vispy/geometry/rect.py +210 -0
  67. vispy/geometry/tests/__init__.py +0 -0
  68. vispy/geometry/tests/test_calculations.py +23 -0
  69. vispy/geometry/tests/test_generation.py +56 -0
  70. vispy/geometry/tests/test_meshdata.py +106 -0
  71. vispy/geometry/tests/test_triangulation.py +506 -0
  72. vispy/geometry/torusknot.py +142 -0
  73. vispy/geometry/triangulation.py +876 -0
  74. vispy/gloo/__init__.py +56 -0
  75. vispy/gloo/buffer.py +505 -0
  76. vispy/gloo/context.py +272 -0
  77. vispy/gloo/framebuffer.py +257 -0
  78. vispy/gloo/gl/__init__.py +234 -0
  79. vispy/gloo/gl/_constants.py +332 -0
  80. vispy/gloo/gl/_es2.py +986 -0
  81. vispy/gloo/gl/_gl2.py +1365 -0
  82. vispy/gloo/gl/_proxy.py +499 -0
  83. vispy/gloo/gl/_pyopengl2.py +362 -0
  84. vispy/gloo/gl/dummy.py +24 -0
  85. vispy/gloo/gl/es2.py +62 -0
  86. vispy/gloo/gl/gl2.py +98 -0
  87. vispy/gloo/gl/glplus.py +168 -0
  88. vispy/gloo/gl/pyopengl2.py +97 -0
  89. vispy/gloo/gl/tests/__init__.py +0 -0
  90. vispy/gloo/gl/tests/test_basics.py +282 -0
  91. vispy/gloo/gl/tests/test_functionality.py +566 -0
  92. vispy/gloo/gl/tests/test_names.py +246 -0
  93. vispy/gloo/gl/tests/test_use.py +71 -0
  94. vispy/gloo/glir.py +1816 -0
  95. vispy/gloo/globject.py +101 -0
  96. vispy/gloo/preprocessor.py +67 -0
  97. vispy/gloo/program.py +543 -0
  98. vispy/gloo/tests/__init__.py +0 -0
  99. vispy/gloo/tests/test_buffer.py +558 -0
  100. vispy/gloo/tests/test_context.py +119 -0
  101. vispy/gloo/tests/test_framebuffer.py +195 -0
  102. vispy/gloo/tests/test_glir.py +307 -0
  103. vispy/gloo/tests/test_globject.py +35 -0
  104. vispy/gloo/tests/test_program.py +302 -0
  105. vispy/gloo/tests/test_texture.py +732 -0
  106. vispy/gloo/tests/test_use_gloo.py +187 -0
  107. vispy/gloo/tests/test_util.py +60 -0
  108. vispy/gloo/tests/test_wrappers.py +261 -0
  109. vispy/gloo/texture.py +1045 -0
  110. vispy/gloo/util.py +129 -0
  111. vispy/gloo/wrappers.py +762 -0
  112. vispy/glsl/__init__.py +42 -0
  113. vispy/glsl/antialias/antialias.glsl +7 -0
  114. vispy/glsl/antialias/cap-butt.glsl +31 -0
  115. vispy/glsl/antialias/cap-round.glsl +29 -0
  116. vispy/glsl/antialias/cap-square.glsl +30 -0
  117. vispy/glsl/antialias/cap-triangle-in.glsl +30 -0
  118. vispy/glsl/antialias/cap-triangle-out.glsl +30 -0
  119. vispy/glsl/antialias/cap.glsl +67 -0
  120. vispy/glsl/antialias/caps.glsl +67 -0
  121. vispy/glsl/antialias/filled.glsl +50 -0
  122. vispy/glsl/antialias/outline.glsl +40 -0
  123. vispy/glsl/antialias/stroke.glsl +43 -0
  124. vispy/glsl/arrowheads/angle.glsl +99 -0
  125. vispy/glsl/arrowheads/arrowheads.frag +60 -0
  126. vispy/glsl/arrowheads/arrowheads.glsl +12 -0
  127. vispy/glsl/arrowheads/arrowheads.vert +83 -0
  128. vispy/glsl/arrowheads/curved.glsl +48 -0
  129. vispy/glsl/arrowheads/inhibitor.glsl +26 -0
  130. vispy/glsl/arrowheads/stealth.glsl +46 -0
  131. vispy/glsl/arrowheads/triangle.glsl +97 -0
  132. vispy/glsl/arrowheads/util.glsl +13 -0
  133. vispy/glsl/arrows/angle-30.glsl +12 -0
  134. vispy/glsl/arrows/angle-60.glsl +12 -0
  135. vispy/glsl/arrows/angle-90.glsl +12 -0
  136. vispy/glsl/arrows/arrow.frag +39 -0
  137. vispy/glsl/arrows/arrow.vert +49 -0
  138. vispy/glsl/arrows/arrows.glsl +17 -0
  139. vispy/glsl/arrows/common.glsl +187 -0
  140. vispy/glsl/arrows/curved.glsl +63 -0
  141. vispy/glsl/arrows/stealth.glsl +50 -0
  142. vispy/glsl/arrows/triangle-30.glsl +12 -0
  143. vispy/glsl/arrows/triangle-60.glsl +12 -0
  144. vispy/glsl/arrows/triangle-90.glsl +12 -0
  145. vispy/glsl/arrows/util.glsl +98 -0
  146. vispy/glsl/build_spatial_filters.py +660 -0
  147. vispy/glsl/collections/agg-fast-path.frag +20 -0
  148. vispy/glsl/collections/agg-fast-path.vert +78 -0
  149. vispy/glsl/collections/agg-glyph.frag +60 -0
  150. vispy/glsl/collections/agg-glyph.vert +33 -0
  151. vispy/glsl/collections/agg-marker.frag +35 -0
  152. vispy/glsl/collections/agg-marker.vert +48 -0
  153. vispy/glsl/collections/agg-path.frag +55 -0
  154. vispy/glsl/collections/agg-path.vert +166 -0
  155. vispy/glsl/collections/agg-point.frag +21 -0
  156. vispy/glsl/collections/agg-point.vert +35 -0
  157. vispy/glsl/collections/agg-segment.frag +32 -0
  158. vispy/glsl/collections/agg-segment.vert +75 -0
  159. vispy/glsl/collections/marker.frag +38 -0
  160. vispy/glsl/collections/marker.vert +48 -0
  161. vispy/glsl/collections/raw-path.frag +15 -0
  162. vispy/glsl/collections/raw-path.vert +24 -0
  163. vispy/glsl/collections/raw-point.frag +14 -0
  164. vispy/glsl/collections/raw-point.vert +31 -0
  165. vispy/glsl/collections/raw-segment.frag +18 -0
  166. vispy/glsl/collections/raw-segment.vert +26 -0
  167. vispy/glsl/collections/raw-triangle.frag +13 -0
  168. vispy/glsl/collections/raw-triangle.vert +26 -0
  169. vispy/glsl/collections/sdf-glyph-ticks.vert +69 -0
  170. vispy/glsl/collections/sdf-glyph.frag +80 -0
  171. vispy/glsl/collections/sdf-glyph.vert +59 -0
  172. vispy/glsl/collections/tick-labels.vert +71 -0
  173. vispy/glsl/colormaps/autumn.glsl +20 -0
  174. vispy/glsl/colormaps/blues.glsl +20 -0
  175. vispy/glsl/colormaps/color-space.glsl +17 -0
  176. vispy/glsl/colormaps/colormaps.glsl +24 -0
  177. vispy/glsl/colormaps/cool.glsl +20 -0
  178. vispy/glsl/colormaps/fire.glsl +21 -0
  179. vispy/glsl/colormaps/gray.glsl +20 -0
  180. vispy/glsl/colormaps/greens.glsl +20 -0
  181. vispy/glsl/colormaps/hot.glsl +22 -0
  182. vispy/glsl/colormaps/ice.glsl +20 -0
  183. vispy/glsl/colormaps/icefire.glsl +23 -0
  184. vispy/glsl/colormaps/parse.py +40 -0
  185. vispy/glsl/colormaps/reds.glsl +20 -0
  186. vispy/glsl/colormaps/spring.glsl +20 -0
  187. vispy/glsl/colormaps/summer.glsl +20 -0
  188. vispy/glsl/colormaps/user.glsl +22 -0
  189. vispy/glsl/colormaps/util.glsl +41 -0
  190. vispy/glsl/colormaps/wheel.glsl +21 -0
  191. vispy/glsl/colormaps/winter.glsl +20 -0
  192. vispy/glsl/lines/agg.frag +320 -0
  193. vispy/glsl/lines/agg.vert +241 -0
  194. vispy/glsl/markers/arrow.glsl +12 -0
  195. vispy/glsl/markers/asterisk.glsl +16 -0
  196. vispy/glsl/markers/chevron.glsl +14 -0
  197. vispy/glsl/markers/clover.glsl +20 -0
  198. vispy/glsl/markers/club.glsl +31 -0
  199. vispy/glsl/markers/cross.glsl +17 -0
  200. vispy/glsl/markers/diamond.glsl +12 -0
  201. vispy/glsl/markers/disc.glsl +9 -0
  202. vispy/glsl/markers/ellipse.glsl +67 -0
  203. vispy/glsl/markers/hbar.glsl +9 -0
  204. vispy/glsl/markers/heart.glsl +15 -0
  205. vispy/glsl/markers/infinity.glsl +15 -0
  206. vispy/glsl/markers/marker-sdf.frag +74 -0
  207. vispy/glsl/markers/marker-sdf.vert +41 -0
  208. vispy/glsl/markers/marker.frag +36 -0
  209. vispy/glsl/markers/marker.vert +46 -0
  210. vispy/glsl/markers/markers.glsl +24 -0
  211. vispy/glsl/markers/pin.glsl +18 -0
  212. vispy/glsl/markers/ring.glsl +11 -0
  213. vispy/glsl/markers/spade.glsl +28 -0
  214. vispy/glsl/markers/square.glsl +10 -0
  215. vispy/glsl/markers/tag.glsl +11 -0
  216. vispy/glsl/markers/triangle.glsl +14 -0
  217. vispy/glsl/markers/vbar.glsl +9 -0
  218. vispy/glsl/math/circle-through-2-points.glsl +30 -0
  219. vispy/glsl/math/constants.glsl +48 -0
  220. vispy/glsl/math/double.glsl +114 -0
  221. vispy/glsl/math/functions.glsl +20 -0
  222. vispy/glsl/math/point-to-line-distance.glsl +31 -0
  223. vispy/glsl/math/point-to-line-projection.glsl +29 -0
  224. vispy/glsl/math/signed-line-distance.glsl +27 -0
  225. vispy/glsl/math/signed-segment-distance.glsl +30 -0
  226. vispy/glsl/misc/regular-grid.frag +244 -0
  227. vispy/glsl/misc/spatial-filters.frag +1407 -0
  228. vispy/glsl/misc/viewport-NDC.glsl +20 -0
  229. vispy/glsl/transforms/azimuthal-equal-area.glsl +32 -0
  230. vispy/glsl/transforms/azimuthal-equidistant.glsl +38 -0
  231. vispy/glsl/transforms/hammer.glsl +44 -0
  232. vispy/glsl/transforms/identity.glsl +6 -0
  233. vispy/glsl/transforms/identity_forward.glsl +23 -0
  234. vispy/glsl/transforms/identity_inverse.glsl +23 -0
  235. vispy/glsl/transforms/linear-scale.glsl +127 -0
  236. vispy/glsl/transforms/log-scale.glsl +126 -0
  237. vispy/glsl/transforms/mercator-transverse-forward.glsl +40 -0
  238. vispy/glsl/transforms/mercator-transverse-inverse.glsl +40 -0
  239. vispy/glsl/transforms/panzoom.glsl +10 -0
  240. vispy/glsl/transforms/polar.glsl +41 -0
  241. vispy/glsl/transforms/position.glsl +44 -0
  242. vispy/glsl/transforms/power-scale.glsl +139 -0
  243. vispy/glsl/transforms/projection.glsl +7 -0
  244. vispy/glsl/transforms/pvm.glsl +13 -0
  245. vispy/glsl/transforms/rotate.glsl +45 -0
  246. vispy/glsl/transforms/trackball.glsl +15 -0
  247. vispy/glsl/transforms/translate.glsl +35 -0
  248. vispy/glsl/transforms/transverse_mercator.glsl +38 -0
  249. vispy/glsl/transforms/viewport-clipping.glsl +14 -0
  250. vispy/glsl/transforms/viewport-transform.glsl +16 -0
  251. vispy/glsl/transforms/viewport.glsl +50 -0
  252. vispy/glsl/transforms/x.glsl +24 -0
  253. vispy/glsl/transforms/y.glsl +19 -0
  254. vispy/glsl/transforms/z.glsl +14 -0
  255. vispy/io/__init__.py +20 -0
  256. vispy/io/_data/spatial-filters.npy +0 -0
  257. vispy/io/datasets.py +94 -0
  258. vispy/io/image.py +231 -0
  259. vispy/io/mesh.py +122 -0
  260. vispy/io/stl.py +167 -0
  261. vispy/io/tests/__init__.py +0 -0
  262. vispy/io/tests/test_image.py +47 -0
  263. vispy/io/tests/test_io.py +121 -0
  264. vispy/io/wavefront.py +350 -0
  265. vispy/plot/__init__.py +36 -0
  266. vispy/plot/fig.py +58 -0
  267. vispy/plot/plotwidget.py +522 -0
  268. vispy/plot/tests/__init__.py +0 -0
  269. vispy/plot/tests/test_plot.py +46 -0
  270. vispy/scene/__init__.py +43 -0
  271. vispy/scene/cameras/__init__.py +27 -0
  272. vispy/scene/cameras/_base.py +38 -0
  273. vispy/scene/cameras/arcball.py +106 -0
  274. vispy/scene/cameras/base_camera.py +538 -0
  275. vispy/scene/cameras/fly.py +474 -0
  276. vispy/scene/cameras/magnify.py +163 -0
  277. vispy/scene/cameras/panzoom.py +308 -0
  278. vispy/scene/cameras/perspective.py +333 -0
  279. vispy/scene/cameras/tests/__init__.py +0 -0
  280. vispy/scene/cameras/tests/test_cameras.py +27 -0
  281. vispy/scene/cameras/tests/test_link.py +53 -0
  282. vispy/scene/cameras/tests/test_perspective.py +122 -0
  283. vispy/scene/cameras/turntable.py +173 -0
  284. vispy/scene/canvas.py +639 -0
  285. vispy/scene/events.py +85 -0
  286. vispy/scene/node.py +644 -0
  287. vispy/scene/subscene.py +20 -0
  288. vispy/scene/tests/__init__.py +0 -0
  289. vispy/scene/tests/test_canvas.py +119 -0
  290. vispy/scene/tests/test_node.py +142 -0
  291. vispy/scene/tests/test_visuals.py +141 -0
  292. vispy/scene/visuals.py +276 -0
  293. vispy/scene/widgets/__init__.py +18 -0
  294. vispy/scene/widgets/anchor.py +25 -0
  295. vispy/scene/widgets/axis.py +88 -0
  296. vispy/scene/widgets/colorbar.py +176 -0
  297. vispy/scene/widgets/console.py +351 -0
  298. vispy/scene/widgets/grid.py +509 -0
  299. vispy/scene/widgets/label.py +50 -0
  300. vispy/scene/widgets/tests/__init__.py +0 -0
  301. vispy/scene/widgets/tests/test_colorbar.py +47 -0
  302. vispy/scene/widgets/viewbox.py +199 -0
  303. vispy/scene/widgets/widget.py +478 -0
  304. vispy/testing/__init__.py +51 -0
  305. vispy/testing/_runners.py +446 -0
  306. vispy/testing/_testing.py +416 -0
  307. vispy/testing/image_tester.py +473 -0
  308. vispy/testing/rendered_array_tester.py +85 -0
  309. vispy/testing/tests/__init__.py +0 -0
  310. vispy/testing/tests/test_testing.py +20 -0
  311. vispy/util/__init__.py +17 -0
  312. vispy/util/bunch.py +15 -0
  313. vispy/util/check_environment.py +57 -0
  314. vispy/util/config.py +490 -0
  315. vispy/util/dpi/__init__.py +19 -0
  316. vispy/util/dpi/_linux.py +69 -0
  317. vispy/util/dpi/_quartz.py +26 -0
  318. vispy/util/dpi/_win32.py +34 -0
  319. vispy/util/dpi/tests/__init__.py +0 -0
  320. vispy/util/dpi/tests/test_dpi.py +16 -0
  321. vispy/util/eq.py +41 -0
  322. vispy/util/event.py +774 -0
  323. vispy/util/fetching.py +276 -0
  324. vispy/util/filter.py +44 -0
  325. vispy/util/fonts/__init__.py +14 -0
  326. vispy/util/fonts/_freetype.py +73 -0
  327. vispy/util/fonts/_quartz.py +192 -0
  328. vispy/util/fonts/_triage.py +36 -0
  329. vispy/util/fonts/_vispy_fonts.py +20 -0
  330. vispy/util/fonts/_win32.py +105 -0
  331. vispy/util/fonts/data/OpenSans-Bold.ttf +0 -0
  332. vispy/util/fonts/data/OpenSans-BoldItalic.ttf +0 -0
  333. vispy/util/fonts/data/OpenSans-Italic.ttf +0 -0
  334. vispy/util/fonts/data/OpenSans-Regular.ttf +0 -0
  335. vispy/util/fonts/tests/__init__.py +0 -0
  336. vispy/util/fonts/tests/test_font.py +45 -0
  337. vispy/util/fourier.py +69 -0
  338. vispy/util/frozen.py +25 -0
  339. vispy/util/gallery_scraper.py +268 -0
  340. vispy/util/keys.py +91 -0
  341. vispy/util/logs.py +358 -0
  342. vispy/util/osmesa_gl.py +17 -0
  343. vispy/util/profiler.py +135 -0
  344. vispy/util/ptime.py +16 -0
  345. vispy/util/quaternion.py +229 -0
  346. vispy/util/svg/__init__.py +18 -0
  347. vispy/util/svg/base.py +20 -0
  348. vispy/util/svg/color.py +219 -0
  349. vispy/util/svg/element.py +51 -0
  350. vispy/util/svg/geometry.py +478 -0
  351. vispy/util/svg/group.py +66 -0
  352. vispy/util/svg/length.py +81 -0
  353. vispy/util/svg/number.py +25 -0
  354. vispy/util/svg/path.py +332 -0
  355. vispy/util/svg/shapes.py +57 -0
  356. vispy/util/svg/style.py +59 -0
  357. vispy/util/svg/svg.py +40 -0
  358. vispy/util/svg/transform.py +223 -0
  359. vispy/util/svg/transformable.py +28 -0
  360. vispy/util/svg/viewport.py +73 -0
  361. vispy/util/tests/__init__.py +0 -0
  362. vispy/util/tests/test_config.py +58 -0
  363. vispy/util/tests/test_docstring_parameters.py +123 -0
  364. vispy/util/tests/test_emitter_group.py +262 -0
  365. vispy/util/tests/test_event_emitter.py +743 -0
  366. vispy/util/tests/test_fourier.py +35 -0
  367. vispy/util/tests/test_gallery_scraper.py +112 -0
  368. vispy/util/tests/test_import.py +127 -0
  369. vispy/util/tests/test_key.py +22 -0
  370. vispy/util/tests/test_logging.py +45 -0
  371. vispy/util/tests/test_run.py +14 -0
  372. vispy/util/tests/test_transforms.py +42 -0
  373. vispy/util/tests/test_vispy.py +48 -0
  374. vispy/util/transforms.py +201 -0
  375. vispy/util/wrappers.py +155 -0
  376. vispy/version.py +4 -0
  377. vispy/visuals/__init__.py +50 -0
  378. vispy/visuals/_scalable_textures.py +485 -0
  379. vispy/visuals/axis.py +678 -0
  380. vispy/visuals/border.py +208 -0
  381. vispy/visuals/box.py +79 -0
  382. vispy/visuals/collections/__init__.py +30 -0
  383. vispy/visuals/collections/agg_fast_path_collection.py +219 -0
  384. vispy/visuals/collections/agg_path_collection.py +197 -0
  385. vispy/visuals/collections/agg_point_collection.py +52 -0
  386. vispy/visuals/collections/agg_segment_collection.py +142 -0
  387. vispy/visuals/collections/array_list.py +401 -0
  388. vispy/visuals/collections/base_collection.py +482 -0
  389. vispy/visuals/collections/collection.py +253 -0
  390. vispy/visuals/collections/path_collection.py +23 -0
  391. vispy/visuals/collections/point_collection.py +19 -0
  392. vispy/visuals/collections/polygon_collection.py +25 -0
  393. vispy/visuals/collections/raw_path_collection.py +119 -0
  394. vispy/visuals/collections/raw_point_collection.py +113 -0
  395. vispy/visuals/collections/raw_polygon_collection.py +77 -0
  396. vispy/visuals/collections/raw_segment_collection.py +112 -0
  397. vispy/visuals/collections/raw_triangle_collection.py +78 -0
  398. vispy/visuals/collections/segment_collection.py +19 -0
  399. vispy/visuals/collections/triangle_collection.py +16 -0
  400. vispy/visuals/collections/util.py +168 -0
  401. vispy/visuals/colorbar.py +699 -0
  402. vispy/visuals/cube.py +41 -0
  403. vispy/visuals/ellipse.py +163 -0
  404. vispy/visuals/filters/__init__.py +10 -0
  405. vispy/visuals/filters/base_filter.py +242 -0
  406. vispy/visuals/filters/clipper.py +60 -0
  407. vispy/visuals/filters/clipping_planes.py +122 -0
  408. vispy/visuals/filters/color.py +181 -0
  409. vispy/visuals/filters/markers.py +28 -0
  410. vispy/visuals/filters/mesh.py +796 -0
  411. vispy/visuals/filters/picking.py +60 -0
  412. vispy/visuals/filters/tests/__init__.py +3 -0
  413. vispy/visuals/filters/tests/test_primitive_picking_filters.py +70 -0
  414. vispy/visuals/filters/tests/test_wireframe_filter.py +16 -0
  415. vispy/visuals/glsl/__init__.py +1 -0
  416. vispy/visuals/glsl/antialiasing.py +133 -0
  417. vispy/visuals/glsl/color.py +63 -0
  418. vispy/visuals/graphs/__init__.py +1 -0
  419. vispy/visuals/graphs/graph.py +240 -0
  420. vispy/visuals/graphs/layouts/__init__.py +55 -0
  421. vispy/visuals/graphs/layouts/circular.py +49 -0
  422. vispy/visuals/graphs/layouts/force_directed.py +211 -0
  423. vispy/visuals/graphs/layouts/networkx_layout.py +87 -0
  424. vispy/visuals/graphs/layouts/random.py +52 -0
  425. vispy/visuals/graphs/tests/__init__.py +1 -0
  426. vispy/visuals/graphs/tests/test_layouts.py +139 -0
  427. vispy/visuals/graphs/tests/test_networkx_layout.py +47 -0
  428. vispy/visuals/graphs/util.py +120 -0
  429. vispy/visuals/gridlines.py +105 -0
  430. vispy/visuals/gridmesh.py +98 -0
  431. vispy/visuals/histogram.py +58 -0
  432. vispy/visuals/image.py +688 -0
  433. vispy/visuals/image_complex.py +130 -0
  434. vispy/visuals/infinite_line.py +199 -0
  435. vispy/visuals/instanced_mesh.py +152 -0
  436. vispy/visuals/isocurve.py +213 -0
  437. vispy/visuals/isoline.py +241 -0
  438. vispy/visuals/isosurface.py +113 -0
  439. vispy/visuals/line/__init__.py +6 -0
  440. vispy/visuals/line/arrow.py +289 -0
  441. vispy/visuals/line/dash_atlas.py +90 -0
  442. vispy/visuals/line/line.py +545 -0
  443. vispy/visuals/line_plot.py +135 -0
  444. vispy/visuals/linear_region.py +199 -0
  445. vispy/visuals/markers.py +810 -0
  446. vispy/visuals/mesh.py +373 -0
  447. vispy/visuals/mesh_normals.py +159 -0
  448. vispy/visuals/plane.py +54 -0
  449. vispy/visuals/polygon.py +145 -0
  450. vispy/visuals/rectangle.py +196 -0
  451. vispy/visuals/regular_polygon.py +56 -0
  452. vispy/visuals/scrolling_lines.py +197 -0
  453. vispy/visuals/shaders/__init__.py +17 -0
  454. vispy/visuals/shaders/compiler.py +206 -0
  455. vispy/visuals/shaders/expression.py +99 -0
  456. vispy/visuals/shaders/function.py +788 -0
  457. vispy/visuals/shaders/multiprogram.py +145 -0
  458. vispy/visuals/shaders/parsing.py +140 -0
  459. vispy/visuals/shaders/program.py +161 -0
  460. vispy/visuals/shaders/shader_object.py +162 -0
  461. vispy/visuals/shaders/tests/__init__.py +0 -0
  462. vispy/visuals/shaders/tests/test_function.py +486 -0
  463. vispy/visuals/shaders/tests/test_multiprogram.py +78 -0
  464. vispy/visuals/shaders/tests/test_parsing.py +57 -0
  465. vispy/visuals/shaders/variable.py +272 -0
  466. vispy/visuals/spectrogram.py +169 -0
  467. vispy/visuals/sphere.py +80 -0
  468. vispy/visuals/surface_plot.py +192 -0
  469. vispy/visuals/tests/__init__.py +0 -0
  470. vispy/visuals/tests/test_arrows.py +109 -0
  471. vispy/visuals/tests/test_axis.py +120 -0
  472. vispy/visuals/tests/test_collections.py +15 -0
  473. vispy/visuals/tests/test_colorbar.py +179 -0
  474. vispy/visuals/tests/test_colormap.py +97 -0
  475. vispy/visuals/tests/test_ellipse.py +122 -0
  476. vispy/visuals/tests/test_histogram.py +24 -0
  477. vispy/visuals/tests/test_image.py +390 -0
  478. vispy/visuals/tests/test_image_complex.py +36 -0
  479. vispy/visuals/tests/test_infinite_line.py +53 -0
  480. vispy/visuals/tests/test_instanced_mesh.py +50 -0
  481. vispy/visuals/tests/test_isosurface.py +22 -0
  482. vispy/visuals/tests/test_linear_region.py +152 -0
  483. vispy/visuals/tests/test_markers.py +54 -0
  484. vispy/visuals/tests/test_mesh.py +261 -0
  485. vispy/visuals/tests/test_mesh_normals.py +218 -0
  486. vispy/visuals/tests/test_polygon.py +112 -0
  487. vispy/visuals/tests/test_rectangle.py +163 -0
  488. vispy/visuals/tests/test_regular_polygon.py +111 -0
  489. vispy/visuals/tests/test_scalable_textures.py +180 -0
  490. vispy/visuals/tests/test_sdf.py +73 -0
  491. vispy/visuals/tests/test_spectrogram.py +42 -0
  492. vispy/visuals/tests/test_text.py +95 -0
  493. vispy/visuals/tests/test_volume.py +542 -0
  494. vispy/visuals/tests/test_windbarb.py +33 -0
  495. vispy/visuals/text/__init__.py +7 -0
  496. vispy/visuals/text/_sdf_cpu.cpython-312-aarch64-linux-gnu.so +0 -0
  497. vispy/visuals/text/_sdf_cpu.pyx +110 -0
  498. vispy/visuals/text/_sdf_gpu.py +316 -0
  499. vispy/visuals/text/text.py +675 -0
  500. vispy/visuals/transforms/__init__.py +34 -0
  501. vispy/visuals/transforms/_util.py +191 -0
  502. vispy/visuals/transforms/base_transform.py +233 -0
  503. vispy/visuals/transforms/chain.py +300 -0
  504. vispy/visuals/transforms/interactive.py +98 -0
  505. vispy/visuals/transforms/linear.py +564 -0
  506. vispy/visuals/transforms/nonlinear.py +398 -0
  507. vispy/visuals/transforms/tests/__init__.py +0 -0
  508. vispy/visuals/transforms/tests/test_transforms.py +243 -0
  509. vispy/visuals/transforms/transform_system.py +339 -0
  510. vispy/visuals/tube.py +173 -0
  511. vispy/visuals/visual.py +923 -0
  512. vispy/visuals/volume.py +1335 -0
  513. vispy/visuals/windbarb.py +291 -0
  514. vispy/visuals/xyz_axis.py +34 -0
  515. vispy-0.14.0.dist-info/LICENSE.txt +36 -0
  516. vispy-0.14.0.dist-info/METADATA +218 -0
  517. vispy-0.14.0.dist-info/RECORD +519 -0
  518. vispy-0.14.0.dist-info/WHEEL +6 -0
  519. vispy-0.14.0.dist-info/top_level.txt +1 -0
@@ -0,0 +1,130 @@
1
+ from .image import ImageVisual, _APPLY_CLIM_FLOAT, _APPLY_GAMMA_FLOAT
2
+ import numpy as np
3
+ from .shaders import Function, FunctionChain
4
+
5
+ # In a complex Image, the texture will be rg32f, where:
6
+ # data.r contains the real component
7
+ # data.g contains the imaginary component
8
+ COMPLEX_TRANSFORMS = {
9
+ "real": "float cplx2float(vec4 data) { return data.r; }",
10
+ "imaginary": "float cplx2float(vec4 data) { return data.g; }",
11
+ "magnitude": "float cplx2float(vec4 data) { return length(vec2(data)); }",
12
+ "phase": "float cplx2float(vec4 data) { return atan(data.g, data.r); }",
13
+ }
14
+ CPU_COMPLEX_TRANSFORMS = {
15
+ "magnitude": np.abs,
16
+ "phase": np.angle,
17
+ "real": np.real,
18
+ "imaginary": np.imag,
19
+ }
20
+
21
+
22
+ class ComplexImageVisual(ImageVisual):
23
+ """:class:`~vispy.visuals.ImageVisual` subclass displaying a complex-valued image.
24
+
25
+ This class handles complex values by using an rg32f float texture behind the scenes,
26
+ storing the real component in the "r" value and the imaginary in the "g" value.
27
+
28
+ Parameters
29
+ ----------
30
+ data : ndarray
31
+ Complex valued ImageVisual data. Should be a two dimensional array with a dtype
32
+ of np.complex64 or np.complex128.
33
+ complex_mode : str
34
+ The mode used to convert the complex value in each pixel into a scalar:
35
+ * 'real': show only the real component.
36
+ * 'imaginary': show only the imaginary component.
37
+ * 'magnitude': show the magnitude (`np.abs`) of the complex value.
38
+ * 'phase': show the phase (`np.angle`) of the complex value.
39
+ """
40
+ COMPLEX_MODES = set(COMPLEX_TRANSFORMS)
41
+
42
+ def __init__(self, data=None, complex_mode="magnitude", **kwargs):
43
+ if complex_mode not in self.COMPLEX_MODES:
44
+ raise ValueError(
45
+ "complex_mode must be one of %s" % ", ".join(self.COMPLEX_MODES)
46
+ )
47
+ self._data_is_complex = np.iscomplexobj(data)
48
+ self._complex_mode = complex_mode
49
+
50
+ if kwargs.get("clim", "auto") == "auto" and self._data_is_complex:
51
+ kwargs["clim"] = self._calc_complex_clim(data)
52
+
53
+ kwargs["texture_format"] = "r32f" if self._data_is_complex else "r32f"
54
+ if self._data_is_complex:
55
+ data = self._convert_complex_to_float_view(data)
56
+ super().__init__(data=data, **kwargs)
57
+
58
+ def _init_texture(self, data, texture_format, **texture_kwargs):
59
+ texture_kwargs = {}
60
+ if self._data_is_complex:
61
+ texture_kwargs["format"] = "rg"
62
+ return super()._init_texture(data, texture_format, **texture_kwargs)
63
+
64
+ def set_data(self, image):
65
+ data = np.asarray(image)
66
+ if np.iscomplexobj(data):
67
+ # Turn the texture into an rg32f texture
68
+ # where r = 'real' and g = 'imag'
69
+ self._data_is_complex = True
70
+ # FUTURE: Add formal way of defining texture format from set_data
71
+ self._texture._format = "rg"
72
+ data = self._convert_complex_to_float_view(data)
73
+ elif data.ndim == 3 and data.shape[-1] == 2:
74
+ # data was complex but was already converted to 32-bit float
75
+ # should really only occur from __init__
76
+ self._data_is_complex = True
77
+ else:
78
+ self._texture._format = None
79
+ return super().set_data(data)
80
+
81
+ @staticmethod
82
+ def _convert_complex_to_float_view(complex_arr):
83
+ # turn complex128 into complex64 if needed
84
+ complex64_arr = complex_arr.astype(np.complex64, copy=False)
85
+ float_view_arr = complex64_arr.view(dtype=np.float32).reshape((complex64_arr.shape + (2, )))
86
+ return float_view_arr
87
+
88
+ @property
89
+ def complex_mode(self):
90
+ return self._data_is_complex and self._complex_mode
91
+
92
+ @complex_mode.setter
93
+ def complex_mode(self, value):
94
+ if value not in self.COMPLEX_MODES:
95
+ raise ValueError(
96
+ "complex_mode must be one of %s" % ", ".join(self.COMPLEX_MODES)
97
+ )
98
+ if self._complex_mode != value:
99
+ self._complex_mode = value
100
+ self._need_colortransform_update = True
101
+ self.update()
102
+
103
+ def _build_color_transform(self):
104
+ if self.complex_mode:
105
+ fclim = Function(_APPLY_CLIM_FLOAT)
106
+ fgamma = Function(_APPLY_GAMMA_FLOAT)
107
+ chain = [
108
+ Function(COMPLEX_TRANSFORMS[self.complex_mode]),
109
+ fclim,
110
+ fgamma,
111
+ Function(self.cmap.glsl_map),
112
+ ]
113
+ fun = FunctionChain(None, chain)
114
+ fclim["clim"] = self._texture.clim_normalized
115
+ fgamma["gamma"] = self.gamma
116
+ return fun
117
+ return super()._build_color_transform()
118
+
119
+ @ImageVisual.clim.setter
120
+ def clim(self, clim):
121
+ if clim == "auto" and self.complex_mode:
122
+ clim = self._calc_complex_clim()
123
+ super(ComplexImageVisual, type(self)).clim.fset(self, clim)
124
+
125
+ def _calc_complex_clim(self, data=None):
126
+ # it would be nice if this could be done in the scalable texture mixin,
127
+ # but that would require the mixin knowing about the complex mode.
128
+ func = CPU_COMPLEX_TRANSFORMS[self.complex_mode]
129
+ _rendered = func(self._data if data is None else data)
130
+ return (_rendered.min(), _rendered.max())
@@ -0,0 +1,199 @@
1
+ import numpy as np
2
+
3
+ from .. import gloo
4
+ from .visual import Visual
5
+
6
+
7
+ _VERTEX_SHADER = """
8
+ attribute vec2 a_pos;
9
+ varying vec4 v_color;
10
+
11
+ void main() {
12
+ vec4 pos = vec4(a_pos, 0., 1.);
13
+
14
+ if($is_vertical==1)
15
+ {
16
+ pos.y = $render_to_visual(pos).y;
17
+ }
18
+ else
19
+ {
20
+ pos.x = $render_to_visual(pos).x;
21
+ }
22
+
23
+ gl_Position = $transform(pos);
24
+ gl_PointSize = 10.;
25
+ v_color = $color;
26
+ }
27
+ """
28
+
29
+ _FRAGMENT_SHADER = """
30
+ varying vec4 v_color;
31
+
32
+ void main() {
33
+ gl_FragColor = v_color;
34
+ }
35
+ """
36
+
37
+
38
+ class InfiniteLineVisual(Visual):
39
+ """Infinite horizontal or vertical line for 2D plots.
40
+
41
+ Parameters
42
+ ----------
43
+ pos : float
44
+ Position of the line along the axis.
45
+ color : list, tuple, or array
46
+ The color to use when drawing the line. If an array is given, it
47
+ must be of shape (1, 4) and provide one rgba color per vertex.
48
+ line_width: float
49
+ The width of the Infinite line, in pixels
50
+ antialias: bool
51
+ If the line is drawn with antialiasing
52
+ vertical:
53
+ True for drawing a vertical line, False for an horizontal line
54
+ """
55
+
56
+ _shaders = {
57
+ 'vertex': _VERTEX_SHADER,
58
+ 'fragment': _FRAGMENT_SHADER,
59
+ }
60
+
61
+ def __init__(self, pos=None, color=(1.0, 1.0, 1.0, 1.0), line_width=1.0, antialias=False,
62
+ vertical=True, **kwargs):
63
+ """
64
+
65
+ """
66
+ Visual.__init__(self, vcode=self._shaders['vertex'], fcode=self._shaders['fragment'])
67
+
68
+ self._changed = {'pos': False, 'color': False}
69
+
70
+ self.pos_buf = gloo.VertexBuffer()
71
+ # The Visual superclass contains a MultiProgram, which is an object
72
+ # that behaves like a normal shader program (you can assign shader
73
+ # code, upload values, set template variables, etc.) but internally
74
+ # manages multiple ModularProgram instances, one per view.
75
+
76
+ # The MultiProgram is accessed via the `shared_program` property, so
77
+ # the following modifications to the program will be applied to all
78
+ # views:
79
+ self.shared_program['a_pos'] = self.pos_buf
80
+ self._program.vert['is_vertical'] = 1 if vertical else 0
81
+
82
+ self._need_upload = False
83
+ self._is_vertical = bool(vertical)
84
+ self._pos = np.zeros((2, 2), dtype=np.float32)
85
+ self._color = np.ones(4, dtype=np.float32)
86
+ self._line_width = line_width
87
+ self._antialias = antialias
88
+
89
+ # Visual keeps track of draw mode, index buffer, and GL state. These
90
+ # are shared between all views.
91
+ self._draw_mode = 'line_strip'
92
+ self.set_gl_state('translucent', depth_test=False)
93
+
94
+ self.set_data(pos=pos, color=color)
95
+
96
+ def set_data(self, pos=None, color=None):
97
+ """Set the data
98
+
99
+ Parameters
100
+ ----------
101
+ pos : float
102
+ Position of the line along the axis.
103
+ color : list, tuple, or array
104
+ The color to use when drawing the line. If an array is given, it
105
+ must be of shape (1, 4) and provide one rgba color per vertex.
106
+ """
107
+ if pos is not None:
108
+ pos = float(pos)
109
+ xy = self._pos
110
+ if self._is_vertical:
111
+ xy[0, 0] = pos
112
+ xy[0, 1] = -1
113
+ xy[1, 0] = pos
114
+ xy[1, 1] = 1
115
+ else:
116
+ xy[0, 0] = -1
117
+ xy[0, 1] = pos
118
+ xy[1, 0] = 1
119
+ xy[1, 1] = pos
120
+ self._changed['pos'] = True
121
+
122
+ if color is not None:
123
+ color = np.array(color, dtype=np.float32)
124
+ if color.ndim != 1 or color.shape[0] != 4:
125
+ raise ValueError('color must be a 4 element float rgba tuple,'
126
+ ' list or array')
127
+ self._color = color
128
+ self._changed['color'] = True
129
+
130
+ @property
131
+ def color(self):
132
+ return self._color
133
+
134
+ @property
135
+ def pos(self):
136
+ if self._is_vertical:
137
+ return self._pos[0, 0]
138
+ else:
139
+ return self._pos[0, 1]
140
+
141
+ @property
142
+ def line_width(self):
143
+ return self._line_width
144
+
145
+ @line_width.setter
146
+ def line_width(self, val: float):
147
+ self._line_width = val
148
+
149
+ @property
150
+ def antialias(self):
151
+ return self._antialias
152
+
153
+ @antialias.setter
154
+ def antialias(self, val: float):
155
+ self._antialias = val
156
+
157
+ def _compute_bounds(self, axis, view):
158
+ """Return the (min, max) bounding values of this visual along *axis*
159
+ in the local coordinate system.
160
+ """
161
+ is_vertical = self._is_vertical
162
+ pos = self._pos
163
+ if axis == 0 and is_vertical:
164
+ return (pos[0, 0], pos[0, 0])
165
+ elif axis == 1 and not is_vertical:
166
+ return (self._pos[0, 1], self._pos[0, 1])
167
+
168
+ return None
169
+
170
+ @property
171
+ def is_vertical(self):
172
+ return self._is_vertical
173
+
174
+ def _prepare_transforms(self, view=None):
175
+ program = view.view_program
176
+ transforms = view.transforms
177
+ program.vert['render_to_visual'] = transforms.get_transform('render',
178
+ 'visual')
179
+ program.vert['transform'] = transforms.get_transform('visual',
180
+ 'render')
181
+
182
+ def _prepare_draw(self, view=None):
183
+ """This method is called immediately before each draw.
184
+
185
+ The *view* argument indicates which view is about to be drawn.
186
+ """
187
+
188
+ self.update_gl_state(line_smooth=self._antialias)
189
+ px_scale = self.transforms.pixel_scale
190
+ width = px_scale * self._line_width
191
+ self.update_gl_state(line_width=max(width, 1.0))
192
+
193
+ if self._changed['pos']:
194
+ self.pos_buf.set_data(self._pos)
195
+ self._changed['pos'] = False
196
+
197
+ if self._changed['color']:
198
+ self._program.vert['color'] = self._color
199
+ self._changed['color'] = False
@@ -0,0 +1,152 @@
1
+ # -*- coding: utf-8 -*-
2
+ # -----------------------------------------------------------------------------
3
+ # Copyright (c) Vispy Development Team. All Rights Reserved.
4
+ # Distributed under the (new) BSD License. See LICENSE.txt for more info.
5
+ # -----------------------------------------------------------------------------
6
+
7
+ """An instanced version of MeshVisual with arbitrary shifts, transforms, and colors."""
8
+
9
+ from __future__ import division
10
+
11
+ import numpy as np
12
+
13
+ from ..gloo import VertexBuffer
14
+ from ..gloo.texture import downcast_to_32bit_if_needed
15
+ from ..color import ColorArray
16
+ from .filters import InstancedShadingFilter
17
+ from .shaders import Variable
18
+
19
+ from .mesh import MeshVisual
20
+
21
+
22
+ _VERTEX_SHADER = """
23
+ uniform bool use_instance_colors;
24
+
25
+ // these attributes will be defined on an instance basis
26
+ attribute vec3 shift;
27
+ attribute vec3 transform_x;
28
+ attribute vec3 transform_y;
29
+ attribute vec3 transform_z;
30
+
31
+ varying vec4 v_base_color;
32
+ void main() {
33
+
34
+ v_base_color = $color_transform($base_color);
35
+
36
+ // transform is generated from column vectors (new basis vectors)
37
+ // https://en.wikibooks.org/wiki/GLSL_Programming/Vector_and_Matrix_Operations#Constructors
38
+ mat3 instance_transform = mat3(transform_x, transform_y, transform_z);
39
+ vec3 pos_rotated = instance_transform * $to_vec4($position).xyz;
40
+ vec4 pos_shifted = $to_vec4(pos_rotated + shift);
41
+ gl_Position = $transform(pos_shifted);
42
+ }
43
+ """
44
+
45
+
46
+ class InstancedMeshVisual(MeshVisual):
47
+ """Instanced Mesh visual.
48
+
49
+ Mostly identical to MeshVisual, but additionally takes arrays of
50
+ of positions and transforms (optionally colors) to create multiple
51
+ instances of the mesh.
52
+
53
+ Instancing is a rendering technique that re-uses the same mesh data
54
+ by applying transformations to vertices and vertex data or textures,
55
+ wich can drastically improve performance compared to having many
56
+ simple MeshVisuals.
57
+
58
+ Parameters
59
+ ----------
60
+ instance_positions : (I, 3) array
61
+ Coordinates for each instance of the mesh.
62
+ instance_transforms : (I, 3, 3) array
63
+ Matrices for the transforms to apply to each instance.
64
+ instance_colors : ColorArray
65
+ Matrices of colors for each instance. Colors
66
+ *args : list
67
+ Positional arguments to pass to :class:`~vispy.visuals.mesh.MeshVisual`.
68
+ **kwargs : dict
69
+ Keyword arguments to pass to :class:`~vispy.visuals.mesh.MeshVisual`.
70
+
71
+ Examples
72
+ --------
73
+ See example `scene/instanced_mesh_visual.py` in the gallery.
74
+ """
75
+
76
+ _shaders = {
77
+ 'vertex': _VERTEX_SHADER,
78
+ 'fragment': MeshVisual._shaders['fragment'],
79
+ }
80
+
81
+ _shading_filter_class = InstancedShadingFilter
82
+
83
+ def __init__(self, *args, instance_positions, instance_transforms, instance_colors=None, **kwargs):
84
+ self._instance_positions = None
85
+ self._instance_positions_vbo = None
86
+ self._instance_transforms = None
87
+ self._instance_transforms_vbos = None
88
+ self._instance_colors = None
89
+ self._instance_colors_vbo = None
90
+ super().__init__(*args, **kwargs)
91
+ self.instance_positions = instance_positions
92
+ self.instance_transforms = instance_transforms
93
+ self.instance_colors = instance_colors
94
+
95
+ @property
96
+ def instance_positions(self):
97
+ return self._instance_positions
98
+
99
+ @instance_positions.setter
100
+ def instance_positions(self, pos):
101
+ pos = np.reshape(pos, (-1, 3))
102
+ if pos.ndim != 2 or pos.shape[-1] != 3:
103
+ raise ValueError(f'positions must be 3D coordinates, but provided data has shape {pos.shape}')
104
+ self._instance_positions = downcast_to_32bit_if_needed(pos, dtype=np.float32)
105
+ self._instance_positions_vbo = VertexBuffer(self._instance_positions, divisor=1)
106
+ self.mesh_data_changed()
107
+
108
+ @property
109
+ def instance_transforms(self):
110
+ return self._instance_transforms
111
+
112
+ @instance_transforms.setter
113
+ def instance_transforms(self, matrix):
114
+ matrix = np.reshape(matrix, (-1, 3, 3))
115
+ if matrix.ndim != 3 or matrix.shape[1:] != (3, 3):
116
+ raise ValueError(f'transforms must be an array of 3x3 matrices, but provided data has shape {matrix.shape}')
117
+ self._instance_transforms = downcast_to_32bit_if_needed(matrix, dtype=np.float32)
118
+ # copy if not c contiguous
119
+ self._instance_transforms_vbos = (
120
+ VertexBuffer(np.ascontiguousarray(self._instance_transforms[..., 0]), divisor=1),
121
+ VertexBuffer(np.ascontiguousarray(self._instance_transforms[..., 1]), divisor=1),
122
+ VertexBuffer(np.ascontiguousarray(self._instance_transforms[..., 2]), divisor=1),
123
+ )
124
+ self.mesh_data_changed()
125
+
126
+ @property
127
+ def instance_colors(self):
128
+ return self._instance_colors
129
+
130
+ @instance_colors.setter
131
+ def instance_colors(self, colors):
132
+ if colors is not None:
133
+ colors = ColorArray(colors)
134
+ self._instance_colors_vbo = VertexBuffer(colors.rgba, divisor=1)
135
+ else:
136
+ self._instance_colors_vbo = Variable('base_color', self._color.rgba)
137
+
138
+ self._instance_colors = colors
139
+ self.mesh_data_changed()
140
+
141
+ def _update_data(self):
142
+ with self.events.data_updated.blocker():
143
+ super()._update_data()
144
+
145
+ # set instance buffers
146
+ self.shared_program.vert['base_color'] = self._instance_colors_vbo
147
+ self.shared_program['transform_x'] = self._instance_transforms_vbos[0]
148
+ self.shared_program['transform_y'] = self._instance_transforms_vbos[1]
149
+ self.shared_program['transform_z'] = self._instance_transforms_vbos[2]
150
+ self.shared_program['shift'] = self._instance_positions_vbo
151
+
152
+ self.events.data_updated()
@@ -0,0 +1,213 @@
1
+ # -*- coding: utf-8 -*-
2
+ # Copyright (c) Vispy Development Team. All Rights Reserved.
3
+ # Distributed under the (new) BSD License. See LICENSE.txt for more info.
4
+
5
+ from __future__ import division
6
+
7
+ import numpy as np
8
+
9
+ from .line import LineVisual
10
+ from ..color import ColorArray
11
+ from ..color.colormap import _normalize, get_colormap
12
+ from ..geometry.isocurve import isocurve
13
+
14
+
15
+ class IsocurveVisual(LineVisual):
16
+ """Displays an isocurve of a 2D scalar array.
17
+
18
+ Parameters
19
+ ----------
20
+ data : ndarray | None
21
+ 2D scalar array.
22
+ levels : ndarray, shape (Nlev,) | None
23
+ The levels at which the isocurve is constructed from "*data*".
24
+ color_lev : Color, colormap name, tuple, list or array
25
+ The color to use when drawing the line. If a list is given, it
26
+ must be of shape (Nlev), if an array is given, it must be of
27
+ shape (Nlev, ...). and provide one color per level (rgba, colorname).
28
+ clim : tuple
29
+ (min, max) limits to apply when mapping level values through a
30
+ colormap.
31
+ **kwargs : dict
32
+ Keyword arguments to pass to `LineVisual`.
33
+ """
34
+
35
+ def __init__(self, data=None, levels=None, color_lev=None, clim=None,
36
+ **kwargs):
37
+ self._data = None
38
+ self._levels = levels
39
+ self._color_lev = color_lev
40
+ self._clim = clim
41
+ self._need_color_update = True
42
+ self._need_level_update = True
43
+ self._need_recompute = True
44
+ self._level_min = None
45
+ self._data_is_uniform = False
46
+ self._lc = None
47
+ self._cl = None
48
+ self._li = None
49
+ self._connect = None
50
+ self._verts = None
51
+ kwargs['method'] = 'gl'
52
+ kwargs['antialias'] = False
53
+ LineVisual.__init__(self, **kwargs)
54
+ if data is not None:
55
+ self.set_data(data)
56
+
57
+ @property
58
+ def levels(self):
59
+ """The threshold at which the isocurve is constructed from the
60
+ 2D data.
61
+ """
62
+ return self._levels
63
+
64
+ @levels.setter
65
+ def levels(self, levels):
66
+ self._levels = levels
67
+ self._need_level_update = True
68
+ self._need_recompute = True
69
+ self.update()
70
+
71
+ @property
72
+ def color(self):
73
+ return self._color_lev
74
+
75
+ @color.setter
76
+ def color(self, color):
77
+ self._color_lev = color
78
+ self._need_level_update = True
79
+ self._need_color_update = True
80
+ self.update()
81
+
82
+ def set_data(self, data):
83
+ """Set the scalar array data
84
+
85
+ Parameters
86
+ ----------
87
+ data : ndarray
88
+ A 2D array of scalar values. The isocurve is constructed to show
89
+ all locations in the scalar field equal to ``self.levels``.
90
+ """
91
+ self._data = data
92
+
93
+ if self._clim is None:
94
+ self._clim = (data.min(), data.max())
95
+
96
+ # sanity check,
97
+ # should we raise an error here, since no isolines can be drawn?
98
+ # for now, _prepare_draw returns False if no isoline can be drawn
99
+ if self._data.min() != self._data.max():
100
+ self._data_is_uniform = False
101
+ else:
102
+ self._data_is_uniform = True
103
+
104
+ self._need_recompute = True
105
+ self.update()
106
+
107
+ def _get_verts_and_connect(self, paths):
108
+ """Retrieve vertices and connects from given paths-list"""
109
+ verts = np.vstack(paths)
110
+ gaps = np.add.accumulate(np.array([len(x) for x in paths])) - 1
111
+ connect = np.ones(gaps[-1], dtype=bool)
112
+ connect[gaps[:-1]] = False
113
+ return verts, connect
114
+
115
+ def _compute_iso_line(self):
116
+ """Compute LineVisual vertices, connects and color-index"""
117
+ level_index = []
118
+ connects = []
119
+ verts = []
120
+
121
+ # calculate which level are within data range
122
+ # this works for now and the existing examples, but should be tested
123
+ # thoroughly also with the data-sanity check in set_data-function
124
+ choice = np.nonzero((self.levels > self._data.min()) &
125
+ (self.levels < self._data.max()))
126
+ levels_to_calc = np.array(self.levels)[choice]
127
+
128
+ # save minimum level index
129
+ self._level_min = choice[0][0]
130
+
131
+ try:
132
+ from skimage.measure import find_contours
133
+ except ImportError:
134
+ find_contours = None
135
+
136
+ for level in levels_to_calc:
137
+ # if we use skimage isoline algorithm we need to add half a
138
+ # pixel in both (x,y) dimensions because isolines are aligned to
139
+ # pixel centers
140
+ if find_contours is not None:
141
+ contours = find_contours(self._data, level,
142
+ positive_orientation='high')
143
+ v, c = self._get_verts_and_connect(contours)
144
+ # swap row, column to column, row (x, y)
145
+ v[:, [0, 1]] = v[:, [1, 0]]
146
+ v += np.array([0.5, 0.5])
147
+ else:
148
+ paths = isocurve(self._data.astype(float).T, level,
149
+ extend_to_edge=True, connected=True)
150
+ v, c = self._get_verts_and_connect(paths)
151
+
152
+ level_index.append(v.shape[0])
153
+ connects.append(np.hstack((c, [False])))
154
+ verts.append(v)
155
+
156
+ self._li = np.hstack(level_index)
157
+ self._connect = np.hstack(connects)
158
+ self._verts = np.vstack(verts)
159
+
160
+ def _compute_iso_color(self):
161
+ """Compute LineVisual color from level index and corresponding color"""
162
+ level_color = []
163
+ colors = self._lc
164
+ for i, index in enumerate(self._li):
165
+ level_color.append(np.zeros((index, 4)) +
166
+ colors[i+self._level_min])
167
+ self._cl = np.vstack(level_color)
168
+
169
+ def _levels_to_colors(self):
170
+ # computes ColorArrays for given levels
171
+ # try _color_lev as colormap, except as everything else
172
+ try:
173
+ f_color_levs = get_colormap(self._color_lev)
174
+ except (KeyError, TypeError):
175
+ colors = ColorArray(self._color_lev).rgba
176
+ else:
177
+ lev = _normalize(self._levels, self._clim[0], self._clim[1])
178
+ # map function expects (Nlev,1)!
179
+ colors = f_color_levs.map(lev[:, np.newaxis])
180
+
181
+ # broadcast to (nlev, 4) array
182
+ if len(colors) == 1:
183
+ colors = colors * np.ones((len(self._levels), 1))
184
+
185
+ # detect color_lev/levels mismatch and raise error
186
+ if (len(colors) != len(self._levels)):
187
+ raise TypeError("Color/level mismatch. Color must be of shape "
188
+ "(Nlev, ...) and provide one color per level")
189
+
190
+ self._lc = colors
191
+
192
+ def _prepare_draw(self, view):
193
+ if (self._data is None or self._levels is None or
194
+ self._color_lev is None or self._data_is_uniform):
195
+ return False
196
+
197
+ if self._need_level_update:
198
+ self._levels_to_colors()
199
+ self._need_level_update = False
200
+
201
+ if self._need_recompute:
202
+ self._compute_iso_line()
203
+ self._compute_iso_color()
204
+ LineVisual.set_data(self, pos=self._verts, connect=self._connect,
205
+ color=self._cl)
206
+ self._need_recompute = False
207
+
208
+ if self._need_color_update:
209
+ self._compute_iso_color()
210
+ LineVisual.set_data(self, color=self._cl)
211
+ self._need_color_update = False
212
+
213
+ return LineVisual._prepare_draw(self, view)