vispy 0.15.0__cp313-cp313-win_amd64.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 (521) 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 +1003 -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 +1213 -0
  45. vispy/color/tests/__init__.py +0 -0
  46. vispy/color/tests/test_color.py +378 -0
  47. vispy/conftest.py +12 -0
  48. vispy/ext/__init__.py +0 -0
  49. vispy/ext/cocoapy.py +1522 -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 +162 -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 +700 -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 +594 -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 +568 -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 +1824 -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 +1046 -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 +105 -0
  274. vispy/scene/cameras/base_camera.py +551 -0
  275. vispy/scene/cameras/fly.py +474 -0
  276. vispy/scene/cameras/magnify.py +163 -0
  277. vispy/scene/cameras/panzoom.py +311 -0
  278. vispy/scene/cameras/perspective.py +338 -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 +183 -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 +448 -0
  306. vispy/testing/_testing.py +416 -0
  307. vispy/testing/image_tester.py +494 -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 +32 -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 +21 -0
  377. vispy/visuals/__init__.py +50 -0
  378. vispy/visuals/_scalable_textures.py +487 -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 +162 -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 +801 -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 +161 -0
  430. vispy/visuals/gridmesh.py +98 -0
  431. vispy/visuals/histogram.py +58 -0
  432. vispy/visuals/image.py +701 -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 +819 -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_gridlines.py +30 -0
  477. vispy/visuals/tests/test_histogram.py +24 -0
  478. vispy/visuals/tests/test_image.py +392 -0
  479. vispy/visuals/tests/test_image_complex.py +36 -0
  480. vispy/visuals/tests/test_infinite_line.py +53 -0
  481. vispy/visuals/tests/test_instanced_mesh.py +50 -0
  482. vispy/visuals/tests/test_isosurface.py +22 -0
  483. vispy/visuals/tests/test_linear_region.py +152 -0
  484. vispy/visuals/tests/test_markers.py +54 -0
  485. vispy/visuals/tests/test_mesh.py +261 -0
  486. vispy/visuals/tests/test_mesh_normals.py +218 -0
  487. vispy/visuals/tests/test_polygon.py +112 -0
  488. vispy/visuals/tests/test_rectangle.py +163 -0
  489. vispy/visuals/tests/test_regular_polygon.py +111 -0
  490. vispy/visuals/tests/test_scalable_textures.py +196 -0
  491. vispy/visuals/tests/test_sdf.py +73 -0
  492. vispy/visuals/tests/test_spectrogram.py +42 -0
  493. vispy/visuals/tests/test_surface_plot.py +57 -0
  494. vispy/visuals/tests/test_text.py +95 -0
  495. vispy/visuals/tests/test_volume.py +542 -0
  496. vispy/visuals/tests/test_windbarb.py +33 -0
  497. vispy/visuals/text/__init__.py +7 -0
  498. vispy/visuals/text/_sdf_cpu.cp313-win_amd64.pyd +0 -0
  499. vispy/visuals/text/_sdf_cpu.pyx +112 -0
  500. vispy/visuals/text/_sdf_gpu.py +316 -0
  501. vispy/visuals/text/text.py +675 -0
  502. vispy/visuals/transforms/__init__.py +34 -0
  503. vispy/visuals/transforms/_util.py +191 -0
  504. vispy/visuals/transforms/base_transform.py +233 -0
  505. vispy/visuals/transforms/chain.py +300 -0
  506. vispy/visuals/transforms/interactive.py +98 -0
  507. vispy/visuals/transforms/linear.py +564 -0
  508. vispy/visuals/transforms/nonlinear.py +398 -0
  509. vispy/visuals/transforms/tests/__init__.py +0 -0
  510. vispy/visuals/transforms/tests/test_transforms.py +243 -0
  511. vispy/visuals/transforms/transform_system.py +339 -0
  512. vispy/visuals/tube.py +173 -0
  513. vispy/visuals/visual.py +923 -0
  514. vispy/visuals/volume.py +1366 -0
  515. vispy/visuals/windbarb.py +291 -0
  516. vispy/visuals/xyz_axis.py +34 -0
  517. vispy-0.15.0.dist-info/METADATA +243 -0
  518. vispy-0.15.0.dist-info/RECORD +521 -0
  519. vispy-0.15.0.dist-info/WHEEL +5 -0
  520. vispy-0.15.0.dist-info/licenses/LICENSE.txt +36 -0
  521. vispy-0.15.0.dist-info/top_level.txt +1 -0
@@ -0,0 +1,97 @@
1
+ # -*- coding: utf-8 -*-
2
+
3
+ """
4
+ Tests for texture-based colormap
5
+ All images are of size (100,100) to keep a small file size
6
+ """
7
+
8
+ import numpy as np
9
+
10
+ from vispy.scene.visuals import Image
11
+ from vispy.testing import (requires_application, TestingCanvas,
12
+ run_tests_if_main)
13
+ from vispy.testing.image_tester import assert_image_approved
14
+ from vispy.color import Colormap
15
+
16
+ size = (100, 100)
17
+
18
+
19
+ @requires_application()
20
+ def test_colormap():
21
+ """Test colormap support for non-uniformly distributed control-points"""
22
+ with TestingCanvas(size=size, bgcolor='w') as c:
23
+ idata = np.linspace(255, 0, size[0]*size[1]).astype(np.ubyte)
24
+ data = idata.reshape((size[0], size[1]))
25
+ image = Image(cmap=Colormap(colors=['k', 'w', 'r'],
26
+ controls=[0.0, 0.1, 1.0]),
27
+ clim='auto', parent=c.scene)
28
+ image.set_data(data)
29
+ assert_image_approved(c.render(), "visuals/colormap_kwr.png")
30
+
31
+
32
+ @requires_application()
33
+ def test_colormap_discrete():
34
+ """Test discrete RGB colormap"""
35
+ with TestingCanvas(size=size, bgcolor='w') as c:
36
+ idata = np.linspace(255, 0, size[0]*size[1]).astype(np.ubyte)
37
+ data = idata.reshape((size[0], size[1]))
38
+ image = Image(cmap=Colormap(colors=['r', 'g', 'b'],
39
+ interpolation='zero'),
40
+ clim='auto', parent=c.scene)
41
+ image.set_data(data)
42
+ assert_image_approved(c.render(), "visuals/colormap_rgb.png")
43
+
44
+
45
+ @requires_application()
46
+ def test_colormap_discrete_nu():
47
+ """Test discrete colormap with non-uniformly distributed control-points"""
48
+ with TestingCanvas(size=size, bgcolor='w') as c:
49
+ idata = np.linspace(255, 0, size[0]*size[1]).astype(np.ubyte)
50
+ data = idata.reshape((size[0], size[1]))
51
+ image = Image(cmap=Colormap(np.array([[0, .75, 0], [.75, .25, .5]]),
52
+ [0., .25, 1.], interpolation='zero'),
53
+ clim='auto', parent=c.scene)
54
+ image.set_data(data)
55
+ assert_image_approved(c.render(), "visuals/colormap_nu.png")
56
+
57
+
58
+ @requires_application()
59
+ def test_colormap_single_hue():
60
+ """Test colormap support using a single hue()"""
61
+ from vispy.color.colormap import SingleHue
62
+ with TestingCanvas(size=size, bgcolor='w') as c:
63
+ idata = np.linspace(255, 0, size[0]*size[1]).astype(np.ubyte)
64
+ data = idata.reshape((size[0], size[1]))
65
+ cmap = SingleHue(255)
66
+ image = Image(cmap=cmap,
67
+ clim='auto', parent=c.scene)
68
+ image.set_data(data)
69
+ assert_image_approved(c.render(), "visuals/colormap_hue.png")
70
+
71
+
72
+ @requires_application()
73
+ def test_colormap_coolwarm():
74
+ """Test colormap support using coolwarm preset colormap"""
75
+ with TestingCanvas(size=size, bgcolor='w') as c:
76
+ idata = np.linspace(255, 0, size[0]*size[1]).astype(np.ubyte)
77
+ data = idata.reshape((size[0], size[1]))
78
+ image = Image(cmap='coolwarm', clim='auto', parent=c.scene)
79
+ image.set_data(data)
80
+ assert_image_approved(c.render(), "visuals/colormap_coolwarm.png")
81
+
82
+
83
+ @requires_application()
84
+ def test_colormap_CubeHelix():
85
+ """Test colormap support using cubehelix colormap in only blues"""
86
+ from vispy.color.colormap import CubeHelixColormap
87
+ with TestingCanvas(size=size, bgcolor='w') as c:
88
+ idata = np.linspace(255, 0, size[0]*size[1]).astype(np.ubyte)
89
+ data = idata.reshape((size[0], size[1]))
90
+ cmap = CubeHelixColormap(rot=0, start=0)
91
+ image = Image(cmap=cmap,
92
+ clim='auto', parent=c.scene)
93
+ image.set_data(data)
94
+ assert_image_approved(c.render(), "visuals/colormap_cubehelix.png")
95
+
96
+
97
+ run_tests_if_main()
@@ -0,0 +1,122 @@
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
+ """
6
+ Tests for EllipseVisual
7
+ All images are of size (100,100) to keep a small file size
8
+ """
9
+
10
+ from vispy.scene import visuals, transforms
11
+ from vispy.testing import (requires_application, TestingCanvas,
12
+ run_tests_if_main)
13
+ from vispy.testing.image_tester import assert_image_approved
14
+
15
+
16
+ @requires_application()
17
+ def test_circle_draw():
18
+ """Test drawing circles without transform using EllipseVisual"""
19
+ with TestingCanvas() as c:
20
+ ellipse = visuals.Ellipse(center=(75, 35, 0), radius=20,
21
+ color=(1, 0, 0, 1),
22
+ parent=c.scene)
23
+ assert_image_approved(c.render(), 'visuals/circle1.png')
24
+
25
+ ellipse.parent = None
26
+ ellipse = visuals.Ellipse(center=(75, 35, 0), radius=20,
27
+ color=(1, 0, 0, 1),
28
+ border_color=(0, 1, 1, 1),
29
+ parent=c.scene)
30
+ assert_image_approved(c.render(), 'visuals/circle2.png')
31
+
32
+ ellipse.parent = None
33
+ ellipse = visuals.Ellipse(center=(75, 35, 0), radius=20,
34
+ border_color=(0, 1, 1, 1),
35
+ parent=c.scene)
36
+
37
+ # low corr here because borders have some variability
38
+ # esp. w/HiDPI
39
+ assert_image_approved(c.render(), 'visuals/circle3.png',
40
+ min_corr=0.7)
41
+
42
+
43
+ @requires_application()
44
+ def test_ellipse_draw():
45
+ """Test drawing transformed ellipses using EllipseVisual"""
46
+ with TestingCanvas() as c:
47
+ ellipse = visuals.Ellipse(center=(0., 0.), radius=(20, 15),
48
+ color=(0, 0, 1, 1),
49
+ parent=c.scene)
50
+ ellipse.transform = transforms.STTransform(scale=(2.0, 3.0),
51
+ translate=(50, 50))
52
+ assert_image_approved(c.render(), 'visuals/ellipse1.png')
53
+
54
+ ellipse.parent = None
55
+ ellipse = visuals.Ellipse(center=(0., 0.), radius=(20, 15),
56
+ color=(0, 0, 1, 1),
57
+ border_color=(1, 0, 0, 1),
58
+ parent=c.scene)
59
+ ellipse.transform = transforms.STTransform(scale=(2.0, 3.0),
60
+ translate=(50, 50))
61
+ assert_image_approved(c.render(), 'visuals/ellipse2.png')
62
+
63
+ ellipse.parent = None
64
+ ellipse = visuals.Ellipse(center=(0., 0.), radius=(20, 15),
65
+ border_color=(1, 0, 0, 1),
66
+ parent=c.scene)
67
+ ellipse.transform = transforms.STTransform(scale=(2.0, 3.0),
68
+ translate=(50, 50))
69
+ assert_image_approved(c.render(), 'visuals/ellipse3.png',
70
+ min_corr=0.7)
71
+
72
+
73
+ @requires_application()
74
+ def test_arc_draw1():
75
+ """Test drawing arcs using EllipseVisual"""
76
+ with TestingCanvas() as c:
77
+ ellipse = visuals.Ellipse(center=(50., 50.), radius=(20, 15),
78
+ start_angle=150., span_angle=120.,
79
+ color=(0, 0, 1, 1),
80
+ parent=c.scene)
81
+ assert_image_approved(c.render(), 'visuals/arc1.png')
82
+
83
+ ellipse.parent = None
84
+ ellipse = visuals.Ellipse(center=(50., 50.), radius=(20, 15),
85
+ start_angle=150., span_angle=120.,
86
+ border_color=(1, 0, 0, 1),
87
+ parent=c.scene)
88
+ assert_image_approved(c.render(), 'visuals/arc2.png',
89
+ min_corr=0.6)
90
+
91
+
92
+ @requires_application()
93
+ def test_reactive_draw():
94
+ """Test reactive ellipse attributes"""
95
+ with TestingCanvas() as c:
96
+ ellipse = visuals.Ellipse(center=[75, 35, 0.], radius=[20, 15],
97
+ color='yellow',
98
+ parent=c.scene)
99
+
100
+ ellipse.center = [70, 40, 0.]
101
+ assert_image_approved(c.render(), 'visuals/reactive_ellipse1.png')
102
+
103
+ ellipse.radius = 25
104
+ assert_image_approved(c.render(), 'visuals/reactive_ellipse2.png')
105
+
106
+ ellipse.color = 'red'
107
+ assert_image_approved(c.render(), 'visuals/reactive_ellipse3.png')
108
+
109
+ ellipse.border_color = 'yellow'
110
+ assert_image_approved(c.render(), 'visuals/reactive_ellipse4.png')
111
+
112
+ ellipse.start_angle = 140.
113
+ assert_image_approved(c.render(), 'visuals/reactive_ellipse5.png')
114
+
115
+ ellipse.span_angle = 100.
116
+ assert_image_approved(c.render(), 'visuals/reactive_ellipse6.png')
117
+
118
+ ellipse.num_segments = 10.
119
+ assert_image_approved(c.render(), 'visuals/reactive_ellipse7.png')
120
+
121
+
122
+ run_tests_if_main()
@@ -0,0 +1,30 @@
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
+ """
6
+ Tests for GridLines
7
+ """
8
+
9
+ import numpy as np
10
+
11
+ from vispy.scene import GridLines, STTransform
12
+ from vispy.testing import (requires_application, TestingCanvas,
13
+ run_tests_if_main)
14
+
15
+
16
+ @requires_application()
17
+ def test_gridlines():
18
+ with TestingCanvas(size=(80, 80)) as c:
19
+ grid = GridLines(parent=c.scene)
20
+ grid.transform = STTransform(translate=(40, 40))
21
+ render = c.render()
22
+ np.testing.assert_array_equal(render[40, 40], (151, 151, 151, 255))
23
+ np.testing.assert_array_equal(render[50, 50], (0, 0, 0, 255))
24
+
25
+ grid.grid_bounds = (-10, 10, -10, 10)
26
+ render = c.render()
27
+ np.testing.assert_array_equal(render[50, 50], (255, 255, 255, 255))
28
+
29
+
30
+ run_tests_if_main()
@@ -0,0 +1,24 @@
1
+ # -*- coding: utf-8 -*-
2
+ import numpy as np
3
+
4
+ from vispy.visuals.transforms import STTransform
5
+ from vispy.scene.visuals import Histogram
6
+ from vispy.testing import (requires_application, TestingCanvas,
7
+ run_tests_if_main)
8
+ from vispy.testing.image_tester import assert_image_approved
9
+
10
+
11
+ @requires_application()
12
+ def test_histogram():
13
+ """Test histogram visual"""
14
+ size = (200, 100)
15
+ with TestingCanvas(size=size, bgcolor='w') as c:
16
+ np.random.seed(2397)
17
+ data = np.random.normal(size=100)
18
+ hist = Histogram(data, bins=20, color='k', parent=c.scene)
19
+ hist.transform = STTransform((size[0] // 10, -size[1] // 20, 1),
20
+ (100, size[1]))
21
+ assert_image_approved(c.render(), "visuals/histogram.png")
22
+
23
+
24
+ run_tests_if_main()
@@ -0,0 +1,392 @@
1
+ # -*- coding: utf-8 -*-
2
+ from unittest import mock
3
+
4
+ from vispy.scene import Image, PanZoomCamera
5
+ from vispy.testing import (requires_application, TestingCanvas,
6
+ run_tests_if_main, IS_CI)
7
+ from vispy.testing.image_tester import assert_image_approved, downsample
8
+
9
+ import numpy as np
10
+ import pytest
11
+
12
+ from vispy.testing.rendered_array_tester import compare_render, max_for_dtype
13
+
14
+
15
+ @requires_application()
16
+ @pytest.mark.parametrize('is_3d', [True, False])
17
+ def test_image(is_3d):
18
+ """Test image visual"""
19
+ size = (100, 50)
20
+ with TestingCanvas(size=size, bgcolor='w') as c:
21
+ image = Image(cmap='grays', clim=[0, 1], parent=c.scene)
22
+ shape = (size[1]-10, size[0]-10) + ((3,) if is_3d else ())
23
+ np.random.seed(379823)
24
+ data = np.random.rand(*shape)
25
+ image.set_data(data)
26
+ assert_image_approved(c.render(), "visuals/image%s.png" %
27
+ ("_rgb" if is_3d else "_mono"))
28
+
29
+ # change to auto clims after first draw
30
+ image.clim = "auto"
31
+ assert_image_approved(c.render(), "visuals/image%s.png" %
32
+ ("_rgb" if is_3d else "_mono"))
33
+
34
+
35
+ @requires_application()
36
+ @pytest.mark.parametrize('gamma', [None, -0.5, "0.5"])
37
+ def test_bad_init_gamma(gamma):
38
+ """Test creating an Image with a bad gamma value."""
39
+ with TestingCanvas(size=(100, 50)) as c:
40
+ pytest.raises((TypeError, ValueError), Image, gamma=gamma, parent=c.scene)
41
+
42
+
43
+ def _make_test_data(shape, input_dtype):
44
+ data = np.random.random_sample(shape)
45
+ if data.ndim == 3 and data.shape[-1] == 4:
46
+ # RGBA - make alpha fully opaque
47
+ data[..., -1] = 1.0
48
+ max_val = max_for_dtype(input_dtype)
49
+ if max_val != 1:
50
+ data *= max_val
51
+ data = data.astype(input_dtype)
52
+ return data
53
+
54
+
55
+ def _set_image_data(image, data, should_fail):
56
+ if should_fail:
57
+ pytest.raises(ValueError, image.set_data, data)
58
+ return
59
+ image.set_data(data)
60
+
61
+
62
+ def _get_orig_and_new_clims(input_dtype):
63
+ new_clim = (0.3, 0.8)
64
+ max_val = max_for_dtype(input_dtype)
65
+ if np.issubdtype(input_dtype, np.integer):
66
+ new_clim = (int(new_clim[0] * max_val), int(new_clim[1] * max_val))
67
+ return (0, max_val), new_clim
68
+
69
+
70
+ @requires_application()
71
+ @pytest.mark.parametrize('data_on_init', [False, True])
72
+ @pytest.mark.parametrize('clim_on_init', [False, True])
73
+ @pytest.mark.parametrize('num_channels', [0, 1, 3, 4])
74
+ @pytest.mark.parametrize('texture_format', [None, '__dtype__', 'auto'])
75
+ @pytest.mark.parametrize('input_dtype', [np.uint8, np.uint16, np.float32, np.float64])
76
+ def test_image_clims_and_gamma(input_dtype, texture_format, num_channels,
77
+ clim_on_init, data_on_init):
78
+ """Test image visual with clims and gamma on shader."""
79
+ size = (80, 80)
80
+ if texture_format == '__dtype__':
81
+ texture_format = input_dtype
82
+ shape = size + (num_channels,) if num_channels > 0 else size
83
+ np.random.seed(0)
84
+ data = _make_test_data(shape, input_dtype)
85
+ orig_clim, new_clim = _get_orig_and_new_clims(input_dtype)
86
+ # 16-bit integers and above seem to have precision loss when scaled on the CPU
87
+ is_16int_cpu_scaled = (np.dtype(input_dtype).itemsize >= 2 and
88
+ np.issubdtype(input_dtype, np.integer) and
89
+ texture_format is None)
90
+ clim_atol = 2 if is_16int_cpu_scaled else 1
91
+ gamma_atol = 3 if is_16int_cpu_scaled else 2
92
+
93
+ kwargs = {}
94
+ if clim_on_init:
95
+ kwargs['clim'] = orig_clim
96
+ if data_on_init:
97
+ kwargs['data'] = data
98
+ # default is RGBA, anything except auto requires reformat
99
+ set_data_fails = (num_channels != 4 and
100
+ texture_format is not None and
101
+ texture_format != 'auto')
102
+
103
+ with TestingCanvas(size=size[::-1], bgcolor="w") as c:
104
+ image = Image(cmap='grays', texture_format=texture_format,
105
+ parent=c.scene, **kwargs)
106
+ if not data_on_init:
107
+ _set_image_data(image, data, set_data_fails)
108
+ if set_data_fails:
109
+ return
110
+ rendered = c.render()
111
+ _dtype = rendered.dtype
112
+ shape_ratio = rendered.shape[0] // data.shape[0]
113
+ rendered1 = downsample(rendered, shape_ratio, axis=(0, 1)).astype(_dtype)
114
+ compare_render(data, rendered1)
115
+
116
+ # adjust color limits
117
+ image.clim = new_clim
118
+ rendered2 = downsample(c.render(), shape_ratio, axis=(0, 1)).astype(_dtype)
119
+ scaled_data = (np.clip(data, new_clim[0], new_clim[1]) - new_clim[0]) / (new_clim[1] - new_clim[0])
120
+ compare_render(scaled_data, rendered2, rendered1, atol=clim_atol)
121
+
122
+ # adjust gamma
123
+ image.gamma = 2
124
+ rendered3 = downsample(c.render(), shape_ratio, axis=(0, 1)).astype(_dtype)
125
+ compare_render(scaled_data ** 2, rendered3, rendered2, atol=gamma_atol)
126
+
127
+
128
+ @pytest.mark.xfail(IS_CI, reason="CI environments sometimes treat NaN as 0")
129
+ @requires_application()
130
+ @pytest.mark.parametrize('texture_format', [None, 'auto'])
131
+ @pytest.mark.parametrize('bad_color', [None, (1, 0, 0, 1)])
132
+ def test_image_nan(texture_format, bad_color):
133
+ size = (80, 80)
134
+ data = np.ones(size)
135
+ data[:20, :20] = np.nan
136
+ data[-20: -20:] = 0
137
+
138
+ expected = (np.ones(size + (4,)) * 255).astype(np.uint8)
139
+ expected[-20: -20:] = (0, 0, 0, 225)
140
+ if texture_format is None:
141
+ # CPU scaling's NaNs get converted to 0s
142
+ expected[:20, :20] = (0, 0, 0, 255)
143
+ else:
144
+ # GPU receives NaNs
145
+ # nan - mapped to bad color
146
+ if bad_color is None:
147
+ # no bad color means transparent, so we should see the green canvas
148
+ bad_color = (0, 1, 0, 1)
149
+ expected[:20, :20] = np.array(bad_color) * 255
150
+
151
+ with TestingCanvas(size=size[::-1], bgcolor=(0, 1, 0)) as c:
152
+ image = Image(data, cmap='grays', clim=(0, 1),
153
+ texture_format=texture_format, parent=c.scene)
154
+ image.bad_color = bad_color
155
+ rendered = c.render()
156
+ np.testing.assert_allclose(rendered, expected)
157
+
158
+
159
+ @requires_application()
160
+ @pytest.mark.parametrize('num_bands', [3, 4])
161
+ @pytest.mark.parametrize('texture_format', [None, 'auto'])
162
+ def test_image_nan_rgb(texture_format, num_bands):
163
+ size = (40, 40)
164
+ data = np.ones((40, 40, num_bands))
165
+ data[:5, :5, :3] = np.nan # upper left - RGB all NaN
166
+ data[:5, 20:25, 0] = np.nan # upper middle - R NaN
167
+ data[:5, -5:, :3] = 0 # upper right - opaque RGB black square
168
+ data[-5:, -5:, :] = np.nan # lower right RGBA all NaN
169
+ if num_bands == 4:
170
+ data[-5:, :5, 3] = np.nan # lower left - Alpha NaN
171
+
172
+ expected = (np.ones((40, 40, 4)) * 255).astype(np.uint8)
173
+ # upper left - NaN goes to opaque black
174
+ expected[:5, :5, :3] = 0
175
+ # upper middle -> NaN R goes to 0
176
+ expected[:5, 20:25, 0] = 0
177
+ # upper right - opaque RGB black square
178
+ expected[:5, -5:, :3] = 0
179
+ # lower right - NaN RGB/A goes to 0
180
+ # RGBA case - we see the green background behind the image
181
+ expected[-5:, -5:, 0] = 0
182
+ expected[-5:, -5:, 2] = 0
183
+ if num_bands == 3:
184
+ # RGB case - opaque black because Alpha defaults 1
185
+ expected[-5:, -5:, 1] = 0
186
+ # lower left - NaN Alpha goes to 0
187
+ if num_bands == 4:
188
+ # see the green background behind the image
189
+ expected[-5:, :5, 0] = 0
190
+ expected[-5:, :5, 2] = 0
191
+
192
+ with TestingCanvas(size=size[::-1], bgcolor=(0, 1, 0)) as c:
193
+ Image(data, cmap='grays',
194
+ texture_format=texture_format, parent=c.scene)
195
+ rendered = c.render()
196
+ np.testing.assert_allclose(rendered, expected)
197
+
198
+
199
+ @requires_application()
200
+ @pytest.mark.parametrize('num_channels', [0, 1, 3, 4])
201
+ @pytest.mark.parametrize('texture_format', [None, 'auto'])
202
+ def test_image_equal_clims(texture_format, num_channels):
203
+ """Test image visual with equal clims."""
204
+ size = (40, 40)
205
+ input_dtype = np.uint8
206
+ shape = size + (num_channels,) if num_channels > 0 else size
207
+ np.random.seed(0)
208
+ data = _make_test_data(shape, input_dtype)
209
+ with TestingCanvas(size=size[::-1], bgcolor="w") as c:
210
+ Image(data, cmap='viridis',
211
+ texture_format=texture_format,
212
+ clim=(128.0, 128.0),
213
+ parent=c.scene)
214
+ rendered = c.render()[..., :3]
215
+
216
+ if num_channels >= 3:
217
+ # RGBs don't have colormaps
218
+ assert rendered.sum() == 0
219
+ return
220
+
221
+ # not all black
222
+ assert rendered.sum() != 0
223
+ # not all white
224
+ assert rendered.sum() != 255 * rendered.size
225
+ # should be all the same value
226
+ r_unique = np.unique(rendered[..., 0])
227
+ g_unique = np.unique(rendered[..., 1])
228
+ b_unique = np.unique(rendered[..., 2])
229
+ assert r_unique.size == 1
230
+ assert g_unique.size == 1
231
+ assert b_unique.size == 1
232
+
233
+
234
+ @requires_application()
235
+ def test_image_vertex_updates():
236
+ """Test image visual coordinates are only built when needed."""
237
+ size = (40, 40)
238
+ with TestingCanvas(size=size, bgcolor="w") as c:
239
+ shape = size + (3,)
240
+ np.random.seed(0)
241
+ image = Image(cmap='grays', clim=[0, 1], parent=c.scene)
242
+ with mock.patch.object(
243
+ image, '_build_vertex_data',
244
+ wraps=image._build_vertex_data) as build_vertex_mock:
245
+ data = np.random.rand(*shape)
246
+ image.set_data(data)
247
+ c.render()
248
+ build_vertex_mock.assert_called_once()
249
+ build_vertex_mock.reset_mock() # reset the count to 0
250
+
251
+ # rendering again shouldn't cause vertex coordinates to be built
252
+ c.render()
253
+ build_vertex_mock.assert_not_called()
254
+
255
+ # changing to data of the same shape shouldn't cause it
256
+ data = np.zeros_like(data)
257
+ image.set_data(data)
258
+ c.render()
259
+ build_vertex_mock.assert_not_called()
260
+
261
+ # changing to another shape should
262
+ data = data[:-5, :-5]
263
+ image.set_data(data)
264
+ c.render()
265
+ build_vertex_mock.assert_called_once()
266
+
267
+
268
+ @requires_application()
269
+ @pytest.mark.parametrize(
270
+ ("dtype", "init_clim"),
271
+ [
272
+ (np.float32, "auto"),
273
+ (np.float32, (0, 5)),
274
+ (np.uint8, "auto"),
275
+ (np.uint8, (0, 5)),
276
+ ]
277
+ )
278
+ def test_change_clim_float(dtype, init_clim):
279
+ """Test that with an image of floats, clim is correctly set from the first try.
280
+
281
+ See https://github.com/vispy/vispy/pull/2245.
282
+ """
283
+ size = (40, 40)
284
+ np.random.seed(0)
285
+ data = (np.random.rand(*size) * 100).astype(dtype)
286
+
287
+ with TestingCanvas(size=size[::-1], bgcolor="w") as c:
288
+ image = Image(data=data, clim=init_clim, parent=c.scene)
289
+
290
+ # needed to properly initialize the canvas
291
+ c.render()
292
+
293
+ image.clim = 0, 10
294
+ rendered1 = c.render()
295
+ # set clim to same values
296
+ image.clim = 0, 10
297
+ rendered2 = c.render()
298
+
299
+ assert np.allclose(rendered1, rendered2)
300
+
301
+
302
+ @requires_application()
303
+ def test_image_interpolation():
304
+ """Test different interpolations"""
305
+ size = (81, 81)
306
+ data = np.array([[0, 1]], dtype=int)
307
+ left = (40, 0)
308
+ right = (40, 80)
309
+ center_left = (40, 39)
310
+ center = (40, 40)
311
+ center_right = (40, 41)
312
+ white = (255, 255, 255, 255)
313
+ black = (0, 0, 0, 255)
314
+ gray = (128, 128, 128, 255)
315
+
316
+ with TestingCanvas(size=size[::-1], bgcolor="w") as c:
317
+ view = c.central_widget.add_view(border_width=0)
318
+ view.camera = PanZoomCamera((0, 0, 2, 1))
319
+ image = Image(data=data, cmap='grays',
320
+ parent=view.scene)
321
+
322
+ # needed to properly initialize the canvas
323
+ render = c.render()
324
+
325
+ image.interpolation = 'nearest'
326
+ render = c.render()
327
+ assert np.allclose(render[left], black)
328
+ assert np.allclose(render[right], white)
329
+ assert np.allclose(render[center_left], black)
330
+ assert np.allclose(render[center_right], white)
331
+
332
+ image.interpolation = 'linear'
333
+ render = c.render()
334
+ assert np.allclose(render[left], black)
335
+ assert np.allclose(render[right], white)
336
+ assert np.allclose(render[center], gray, atol=5) # we just want gray, this is not quantitative
337
+
338
+ image.interpolation = 'custom'
339
+ image.custom_kernel = np.array([[0]]) # no sampling
340
+ render = c.render()
341
+ assert np.allclose(render[left], black)
342
+ assert np.allclose(render[right], black)
343
+ assert np.allclose(render[center], black)
344
+
345
+ image.custom_kernel = np.array([[1]]) # same as linear
346
+ render = c.render()
347
+ assert np.allclose(render[left], black)
348
+ assert np.allclose(render[right], white)
349
+ assert np.allclose(render[center], gray, atol=5) # we just want gray, this is not quantitative
350
+
351
+
352
+ @requires_application()
353
+ def test_image_set_data_different_dtype():
354
+ size = (80, 80)
355
+ data = np.array([[0, 127]], dtype=np.int8)
356
+ left = (40, 10)
357
+ right = (40, 70)
358
+ white = (255, 255, 255, 255)
359
+ black = (0, 0, 0, 255)
360
+
361
+ with TestingCanvas(size=size[::-1], bgcolor="w") as c:
362
+ view = c.central_widget.add_view()
363
+ view.camera = PanZoomCamera((0, 0, 2, 1))
364
+ image = Image(data=data, cmap='grays', clim=[0, 127],
365
+ parent=view.scene)
366
+
367
+ render = c.render()
368
+ assert np.allclose(render[left], black)
369
+ assert np.allclose(render[right], white)
370
+
371
+ # same data as float should change nothing
372
+ image.set_data(data.astype(np.float32))
373
+ render = c.render()
374
+ assert np.allclose(render[left], black)
375
+ assert np.allclose(render[right], white)
376
+
377
+ # something inverted, different dtype
378
+ new_data = np.array([[127, 0]], dtype=np.float16)
379
+ image.set_data(new_data)
380
+ render = c.render()
381
+ assert np.allclose(render[left], white)
382
+ assert np.allclose(render[right], black)
383
+
384
+ # out of bounds should clip (2000 > 127)
385
+ new_data = np.array([[0, 2000]], dtype=np.float64)
386
+ image.set_data(new_data)
387
+ render = c.render()
388
+ assert np.allclose(render[left], black)
389
+ assert np.allclose(render[right], white)
390
+
391
+
392
+ run_tests_if_main()