wxPython 4.3.2__cp315-cp315-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.
Files changed (472) hide show
  1. wx/WebView2Loader.dll +0 -0
  2. wx/__init__.py +22 -0
  3. wx/__init__.pyi +10 -0
  4. wx/__version__.py +9 -0
  5. wx/__version__.pyi +15 -0
  6. wx/_adv.cp315-win_amd64.pyd +0 -0
  7. wx/_aui.cp315-win_amd64.pyd +0 -0
  8. wx/_core.cp315-win_amd64.pyd +0 -0
  9. wx/_dataview.cp315-win_amd64.pyd +0 -0
  10. wx/_glcanvas.cp315-win_amd64.pyd +0 -0
  11. wx/_grid.cp315-win_amd64.pyd +0 -0
  12. wx/_html.cp315-win_amd64.pyd +0 -0
  13. wx/_html2.cp315-win_amd64.pyd +0 -0
  14. wx/_media.cp315-win_amd64.pyd +0 -0
  15. wx/_msw.cp315-win_amd64.pyd +0 -0
  16. wx/_propgrid.cp315-win_amd64.pyd +0 -0
  17. wx/_ribbon.cp315-win_amd64.pyd +0 -0
  18. wx/_richtext.cp315-win_amd64.pyd +0 -0
  19. wx/_stc.cp315-win_amd64.pyd +0 -0
  20. wx/_xml.cp315-win_amd64.pyd +0 -0
  21. wx/_xrc.cp315-win_amd64.pyd +0 -0
  22. wx/adv.py +127 -0
  23. wx/adv.pyi +5931 -0
  24. wx/aui.py +70 -0
  25. wx/aui.pyi +4805 -0
  26. wx/core.py +3417 -0
  27. wx/core.pyi +62949 -0
  28. wx/dataview.py +176 -0
  29. wx/dataview.pyi +3828 -0
  30. wx/gizmos.py +18 -0
  31. wx/glcanvas.py +13 -0
  32. wx/glcanvas.pyi +544 -0
  33. wx/grid.py +237 -0
  34. wx/grid.pyi +5678 -0
  35. wx/html.py +38 -0
  36. wx/html.pyi +3283 -0
  37. wx/html2.py +46 -0
  38. wx/html2.pyi +1301 -0
  39. wx/include/wxPython/sip.h +1938 -0
  40. wx/include/wxPython/wxpy_api.h +418 -0
  41. wx/lib/CDate.py +201 -0
  42. wx/lib/ClickableHtmlWindow.py +57 -0
  43. wx/lib/__init__.py +0 -0
  44. wx/lib/activex.py +178 -0
  45. wx/lib/activexwrapper.py +153 -0
  46. wx/lib/agw/__init__.py +128 -0
  47. wx/lib/agw/advancedsplash.py +563 -0
  48. wx/lib/agw/aquabutton.py +1127 -0
  49. wx/lib/agw/artmanager.py +2110 -0
  50. wx/lib/agw/aui/__init__.py +295 -0
  51. wx/lib/agw/aui/aui_constants.py +2616 -0
  52. wx/lib/agw/aui/aui_switcherdialog.py +1232 -0
  53. wx/lib/agw/aui/aui_utilities.py +648 -0
  54. wx/lib/agw/aui/auibar.py +4045 -0
  55. wx/lib/agw/aui/auibook.py +6288 -0
  56. wx/lib/agw/aui/dockart.py +1198 -0
  57. wx/lib/agw/aui/framemanager.py +10485 -0
  58. wx/lib/agw/aui/tabart.py +2749 -0
  59. wx/lib/agw/aui/tabmdi.py +679 -0
  60. wx/lib/agw/balloontip.py +1157 -0
  61. wx/lib/agw/buttonpanel.py +2787 -0
  62. wx/lib/agw/cubecolourdialog.py +3529 -0
  63. wx/lib/agw/customtreectrl.py +9908 -0
  64. wx/lib/agw/data/ShortcutEditor_1.png +0 -0
  65. wx/lib/agw/data/ShortcutEditor_1_thumb.png +0 -0
  66. wx/lib/agw/data/ShortcutEditor_2.png +0 -0
  67. wx/lib/agw/data/ShortcutEditor_2_thumb.png +0 -0
  68. wx/lib/agw/data/ShortcutEditor_3.png +0 -0
  69. wx/lib/agw/data/ShortcutEditor_3_thumb.png +0 -0
  70. wx/lib/agw/data/ShortcutEditor_4.png +0 -0
  71. wx/lib/agw/data/ShortcutEditor_4_thumb.png +0 -0
  72. wx/lib/agw/data/default_help_text.html +105 -0
  73. wx/lib/agw/flatmenu.py +7392 -0
  74. wx/lib/agw/flatnotebook.py +6669 -0
  75. wx/lib/agw/floatspin.py +1820 -0
  76. wx/lib/agw/fmcustomizedlg.py +535 -0
  77. wx/lib/agw/fmresources.py +407 -0
  78. wx/lib/agw/foldpanelbar.py +2282 -0
  79. wx/lib/agw/fourwaysplitter.py +1130 -0
  80. wx/lib/agw/genericmessagedialog.py +1549 -0
  81. wx/lib/agw/gradientbutton.py +731 -0
  82. wx/lib/agw/hyperlink.py +664 -0
  83. wx/lib/agw/hypertreelist.py +5756 -0
  84. wx/lib/agw/infobar.py +885 -0
  85. wx/lib/agw/knobctrl.py +944 -0
  86. wx/lib/agw/labelbook.py +3028 -0
  87. wx/lib/agw/multidirdialog.py +581 -0
  88. wx/lib/agw/peakmeter.py +1028 -0
  89. wx/lib/agw/persist/__init__.py +188 -0
  90. wx/lib/agw/persist/persist_constants.py +283 -0
  91. wx/lib/agw/persist/persist_handlers.py +2614 -0
  92. wx/lib/agw/persist/persistencemanager.py +863 -0
  93. wx/lib/agw/piectrl.py +1082 -0
  94. wx/lib/agw/pybusyinfo.py +399 -0
  95. wx/lib/agw/pycollapsiblepane.py +940 -0
  96. wx/lib/agw/pygauge.py +570 -0
  97. wx/lib/agw/pyprogress.py +916 -0
  98. wx/lib/agw/ribbon/__init__.py +198 -0
  99. wx/lib/agw/ribbon/art.py +219 -0
  100. wx/lib/agw/ribbon/art_aui.py +1283 -0
  101. wx/lib/agw/ribbon/art_default.py +81 -0
  102. wx/lib/agw/ribbon/art_internal.py +248 -0
  103. wx/lib/agw/ribbon/art_msw.py +2735 -0
  104. wx/lib/agw/ribbon/art_osx.py +52 -0
  105. wx/lib/agw/ribbon/bar.py +1259 -0
  106. wx/lib/agw/ribbon/buttonbar.py +1317 -0
  107. wx/lib/agw/ribbon/control.py +205 -0
  108. wx/lib/agw/ribbon/gallery.py +973 -0
  109. wx/lib/agw/ribbon/page.py +946 -0
  110. wx/lib/agw/ribbon/panel.py +1170 -0
  111. wx/lib/agw/ribbon/toolbar.py +1441 -0
  112. wx/lib/agw/rulerctrl.py +1885 -0
  113. wx/lib/agw/scrolledthumbnail.py +2116 -0
  114. wx/lib/agw/shapedbutton.py +1809 -0
  115. wx/lib/agw/shortcuteditor.py +2642 -0
  116. wx/lib/agw/speedmeter.py +1800 -0
  117. wx/lib/agw/supertooltip.py +1443 -0
  118. wx/lib/agw/thumbnailctrl.py +529 -0
  119. wx/lib/agw/toasterbox.py +1327 -0
  120. wx/lib/agw/ultimatelistctrl.py +13671 -0
  121. wx/lib/agw/xlsgrid.py +2111 -0
  122. wx/lib/agw/zoombar.py +1336 -0
  123. wx/lib/analogclock/__init__.py +140 -0
  124. wx/lib/analogclock/analogclock.py +630 -0
  125. wx/lib/analogclock/helpers.py +986 -0
  126. wx/lib/analogclock/lib_setup/__init__.py +0 -0
  127. wx/lib/analogclock/lib_setup/buttontreectrlpanel.py +297 -0
  128. wx/lib/analogclock/lib_setup/fontselect.py +57 -0
  129. wx/lib/analogclock/setup.py +490 -0
  130. wx/lib/analogclock/styles.py +47 -0
  131. wx/lib/anchors.py +103 -0
  132. wx/lib/art/__init__.py +4 -0
  133. wx/lib/art/flagart.py +1583 -0
  134. wx/lib/art/img2pyartprov.py +56 -0
  135. wx/lib/busy.py +152 -0
  136. wx/lib/buttons.py +1140 -0
  137. wx/lib/calendar.py +1596 -0
  138. wx/lib/checkbox.py +837 -0
  139. wx/lib/colourchooser/__init__.py +36 -0
  140. wx/lib/colourchooser/canvas.py +145 -0
  141. wx/lib/colourchooser/intl.py +24 -0
  142. wx/lib/colourchooser/pycolourbox.py +89 -0
  143. wx/lib/colourchooser/pycolourchooser.py +626 -0
  144. wx/lib/colourchooser/pycolourslider.py +98 -0
  145. wx/lib/colourchooser/pypalette.py +208 -0
  146. wx/lib/colourdb.py +740 -0
  147. wx/lib/colourselect.py +385 -0
  148. wx/lib/colourutils.py +118 -0
  149. wx/lib/combotreebox.py +944 -0
  150. wx/lib/delayedresult.py +420 -0
  151. wx/lib/dialogs.py +510 -0
  152. wx/lib/docview.py +3210 -0
  153. wx/lib/dragscroller.py +79 -0
  154. wx/lib/editor/README.txt +77 -0
  155. wx/lib/editor/__init__.py +24 -0
  156. wx/lib/editor/editor.py +974 -0
  157. wx/lib/editor/images.py +15 -0
  158. wx/lib/editor/selection.py +44 -0
  159. wx/lib/embeddedimage.py +76 -0
  160. wx/lib/eventStack.py +136 -0
  161. wx/lib/eventwatcher.py +440 -0
  162. wx/lib/evtmgr.py +521 -0
  163. wx/lib/expando.py +393 -0
  164. wx/lib/fancytext.py +494 -0
  165. wx/lib/filebrowsebutton.py +461 -0
  166. wx/lib/flashwin.py +262 -0
  167. wx/lib/flashwin_old.py +651 -0
  168. wx/lib/floatcanvas/FCEvents.py +53 -0
  169. wx/lib/floatcanvas/FCObjects.py +2910 -0
  170. wx/lib/floatcanvas/FloatCanvas.py +1025 -0
  171. wx/lib/floatcanvas/GUIMode.py +396 -0
  172. wx/lib/floatcanvas/NavCanvas.py +162 -0
  173. wx/lib/floatcanvas/Resources.py +319 -0
  174. wx/lib/floatcanvas/ScreenShot.py +1788 -0
  175. wx/lib/floatcanvas/Utilities/BBox.py +313 -0
  176. wx/lib/floatcanvas/Utilities/Colors.py +137 -0
  177. wx/lib/floatcanvas/Utilities/GUI.py +91 -0
  178. wx/lib/floatcanvas/Utilities/__init__.py +7 -0
  179. wx/lib/floatcanvas/__init__.py +124 -0
  180. wx/lib/foldmenu.py +89 -0
  181. wx/lib/gestures.py +310 -0
  182. wx/lib/gizmos/__init__.py +18 -0
  183. wx/lib/gizmos/dynamicsash.py +1202 -0
  184. wx/lib/gizmos/ledctrl.py +299 -0
  185. wx/lib/gizmos/treelistctrl.py +87 -0
  186. wx/lib/graphics.py +1942 -0
  187. wx/lib/gridmovers.py +516 -0
  188. wx/lib/iewin.py +249 -0
  189. wx/lib/iewin_old.py +894 -0
  190. wx/lib/imagebrowser.py +853 -0
  191. wx/lib/imageutils.py +163 -0
  192. wx/lib/infoframe.py +490 -0
  193. wx/lib/inspection.py +1254 -0
  194. wx/lib/intctrl.py +990 -0
  195. wx/lib/itemspicker.py +256 -0
  196. wx/lib/langlistctrl.py +480 -0
  197. wx/lib/layoutf.py +271 -0
  198. wx/lib/masked/__init__.py +27 -0
  199. wx/lib/masked/combobox.py +839 -0
  200. wx/lib/masked/ctrl.py +108 -0
  201. wx/lib/masked/ipaddrctrl.py +241 -0
  202. wx/lib/masked/maskededit.py +7262 -0
  203. wx/lib/masked/numctrl.py +2000 -0
  204. wx/lib/masked/textctrl.py +465 -0
  205. wx/lib/masked/timectrl.py +1465 -0
  206. wx/lib/mixins/__init__.py +17 -0
  207. wx/lib/mixins/grid.py +47 -0
  208. wx/lib/mixins/gridlabelrenderer.py +277 -0
  209. wx/lib/mixins/imagelist.py +77 -0
  210. wx/lib/mixins/inspection.py +184 -0
  211. wx/lib/mixins/listctrl.py +893 -0
  212. wx/lib/mixins/rubberband.py +403 -0
  213. wx/lib/mixins/treemixin.py +678 -0
  214. wx/lib/msgpanel.py +95 -0
  215. wx/lib/multisash.py +746 -0
  216. wx/lib/myole4ax.idl +178 -0
  217. wx/lib/myole4ax.tlb +0 -0
  218. wx/lib/newevent.py +229 -0
  219. wx/lib/newevent.pyi +25 -0
  220. wx/lib/nvdlg.py +156 -0
  221. wx/lib/ogl/__init__.py +13 -0
  222. wx/lib/ogl/basic.py +3989 -0
  223. wx/lib/ogl/bmpshape.py +86 -0
  224. wx/lib/ogl/canvas.py +467 -0
  225. wx/lib/ogl/composit.py +1576 -0
  226. wx/lib/ogl/diagram.py +230 -0
  227. wx/lib/ogl/divided.py +482 -0
  228. wx/lib/ogl/drawn.py +898 -0
  229. wx/lib/ogl/lines.py +1809 -0
  230. wx/lib/ogl/oglmisc.py +607 -0
  231. wx/lib/pdfviewer/__init__.py +113 -0
  232. wx/lib/pdfviewer/bitmaps/ArrowLeft.png +0 -0
  233. wx/lib/pdfviewer/bitmaps/ArrowRight.png +0 -0
  234. wx/lib/pdfviewer/bitmaps/DirectionH.png +0 -0
  235. wx/lib/pdfviewer/bitmaps/DirectionV.png +0 -0
  236. wx/lib/pdfviewer/bitmaps/PlayerFirst.png +0 -0
  237. wx/lib/pdfviewer/bitmaps/PlayerLast.png +0 -0
  238. wx/lib/pdfviewer/bitmaps/PlayerNext.png +0 -0
  239. wx/lib/pdfviewer/bitmaps/PlayerPrev.png +0 -0
  240. wx/lib/pdfviewer/bitmaps/Printer.png +0 -0
  241. wx/lib/pdfviewer/bitmaps/ReadMe.txt +28 -0
  242. wx/lib/pdfviewer/bitmaps/Save.png +0 -0
  243. wx/lib/pdfviewer/bitmaps/ZoomIn.png +0 -0
  244. wx/lib/pdfviewer/bitmaps/ZoomOut.png +0 -0
  245. wx/lib/pdfviewer/bitmaps/encode_bitmaps.py +37 -0
  246. wx/lib/pdfviewer/buttonpanel.py +285 -0
  247. wx/lib/pdfviewer/images.py +240 -0
  248. wx/lib/pdfviewer/viewer.py +1118 -0
  249. wx/lib/pdfwin.py +295 -0
  250. wx/lib/pdfwin_old.py +789 -0
  251. wx/lib/platebtn.py +789 -0
  252. wx/lib/plot/CHANGELOG.md +150 -0
  253. wx/lib/plot/README.md +16 -0
  254. wx/lib/plot/__init__.py +46 -0
  255. wx/lib/plot/__main__.py +5 -0
  256. wx/lib/plot/examples/__init__.py +0 -0
  257. wx/lib/plot/examples/demo.py +1010 -0
  258. wx/lib/plot/examples/simple_example.py +56 -0
  259. wx/lib/plot/plotcanvas.py +2985 -0
  260. wx/lib/plot/polyobjects.py +1524 -0
  261. wx/lib/plot/utils.py +334 -0
  262. wx/lib/popupctl.py +251 -0
  263. wx/lib/printout.py +1155 -0
  264. wx/lib/progressindicator.py +151 -0
  265. wx/lib/pubsub/LICENSE_BSD_Simple.txt +23 -0
  266. wx/lib/pubsub/README_WxPython.txt +22 -0
  267. wx/lib/pubsub/RELEASE_NOTES.txt +71 -0
  268. wx/lib/pubsub/__init__.py +25 -0
  269. wx/lib/pubsub/core/__init__.py +92 -0
  270. wx/lib/pubsub/core/arg1/__init__.py +16 -0
  271. wx/lib/pubsub/core/arg1/listenerimpl.py +97 -0
  272. wx/lib/pubsub/core/arg1/publisher.py +40 -0
  273. wx/lib/pubsub/core/arg1/publishermixin.py +34 -0
  274. wx/lib/pubsub/core/arg1/topicargspecimpl.py +66 -0
  275. wx/lib/pubsub/core/arg1/topicmgrimpl.py +19 -0
  276. wx/lib/pubsub/core/callables.py +198 -0
  277. wx/lib/pubsub/core/imp2.py +62 -0
  278. wx/lib/pubsub/core/itopicdefnprovider.py +0 -0
  279. wx/lib/pubsub/core/kwargs/__init__.py +16 -0
  280. wx/lib/pubsub/core/kwargs/datamsg.py +27 -0
  281. wx/lib/pubsub/core/kwargs/listenerimpl.py +93 -0
  282. wx/lib/pubsub/core/kwargs/publisher.py +77 -0
  283. wx/lib/pubsub/core/kwargs/publishermixin.py +65 -0
  284. wx/lib/pubsub/core/kwargs/topicargspecimpl.py +216 -0
  285. wx/lib/pubsub/core/kwargs/topicmgrimpl.py +13 -0
  286. wx/lib/pubsub/core/listener.py +40 -0
  287. wx/lib/pubsub/core/listenerbase.py +185 -0
  288. wx/lib/pubsub/core/notificationmgr.py +185 -0
  289. wx/lib/pubsub/core/publisherbase.py +189 -0
  290. wx/lib/pubsub/core/topicargspec.py +77 -0
  291. wx/lib/pubsub/core/topicdefnprovider.py +631 -0
  292. wx/lib/pubsub/core/topicexc.py +72 -0
  293. wx/lib/pubsub/core/topicmgr.py +454 -0
  294. wx/lib/pubsub/core/topicobj.py +472 -0
  295. wx/lib/pubsub/core/topictreetraverser.py +143 -0
  296. wx/lib/pubsub/core/topicutils.py +119 -0
  297. wx/lib/pubsub/core/treeconfig.py +21 -0
  298. wx/lib/pubsub/core/validatedefnargs.py +29 -0
  299. wx/lib/pubsub/core/weakmethod.py +102 -0
  300. wx/lib/pubsub/policies.py +24 -0
  301. wx/lib/pubsub/pub.py +199 -0
  302. wx/lib/pubsub/setuparg1.py +47 -0
  303. wx/lib/pubsub/setupkwargs.py +29 -0
  304. wx/lib/pubsub/utils/__init__.py +27 -0
  305. wx/lib/pubsub/utils/exchandling.py +100 -0
  306. wx/lib/pubsub/utils/misc.py +99 -0
  307. wx/lib/pubsub/utils/notification.py +331 -0
  308. wx/lib/pubsub/utils/topictreeprinter.py +195 -0
  309. wx/lib/pubsub/utils/xmltopicdefnprovider.py +286 -0
  310. wx/lib/pydocview.py +3300 -0
  311. wx/lib/rcsizer.py +227 -0
  312. wx/lib/resizewidget.py +357 -0
  313. wx/lib/scrolledpanel.py +243 -0
  314. wx/lib/sheet.py +350 -0
  315. wx/lib/sized_controls.py +691 -0
  316. wx/lib/softwareupdate.py +355 -0
  317. wx/lib/splitter.py +925 -0
  318. wx/lib/statbmp.py +199 -0
  319. wx/lib/stattext.py +321 -0
  320. wx/lib/throbber.py +424 -0
  321. wx/lib/ticker.py +306 -0
  322. wx/lib/ticker_xrc.py +48 -0
  323. wx/lib/utils.py +89 -0
  324. wx/lib/wordwrap.py +97 -0
  325. wx/lib/wxcairo/__init__.py +139 -0
  326. wx/lib/wxcairo/wx_cairocffi.py +200 -0
  327. wx/lib/wxcairo/wx_pycairo.py +455 -0
  328. wx/lib/wxpTag.py +274 -0
  329. wx/libcairo-2.dll +0 -0
  330. wx/locale/af/LC_MESSAGES/wxstd.mo +0 -0
  331. wx/locale/an/LC_MESSAGES/wxstd.mo +0 -0
  332. wx/locale/ar/LC_MESSAGES/wxstd.mo +0 -0
  333. wx/locale/ca/LC_MESSAGES/wxstd.mo +0 -0
  334. wx/locale/ca@valencia/LC_MESSAGES/wxstd.mo +0 -0
  335. wx/locale/co/LC_MESSAGES/wxstd.mo +0 -0
  336. wx/locale/cs/LC_MESSAGES/wxstd.mo +0 -0
  337. wx/locale/da/LC_MESSAGES/wxstd.mo +0 -0
  338. wx/locale/de/LC_MESSAGES/wxstd.mo +0 -0
  339. wx/locale/el/LC_MESSAGES/wxstd.mo +0 -0
  340. wx/locale/es/LC_MESSAGES/wxstd.mo +0 -0
  341. wx/locale/eu/LC_MESSAGES/wxstd.mo +0 -0
  342. wx/locale/fa_IR/LC_MESSAGES/wxstd.mo +0 -0
  343. wx/locale/fi/LC_MESSAGES/wxstd.mo +0 -0
  344. wx/locale/fr/LC_MESSAGES/wxstd.mo +0 -0
  345. wx/locale/gl_ES/LC_MESSAGES/wxstd.mo +0 -0
  346. wx/locale/hi/LC_MESSAGES/wxstd.mo +0 -0
  347. wx/locale/hr/LC_MESSAGES/wxstd.mo +0 -0
  348. wx/locale/hu/LC_MESSAGES/wxstd.mo +0 -0
  349. wx/locale/id/LC_MESSAGES/wxstd.mo +0 -0
  350. wx/locale/it/LC_MESSAGES/wxstd.mo +0 -0
  351. wx/locale/ja/LC_MESSAGES/wxstd.mo +0 -0
  352. wx/locale/ka/LC_MESSAGES/wxstd.mo +0 -0
  353. wx/locale/ko_KR/LC_MESSAGES/wxstd.mo +0 -0
  354. wx/locale/lt/LC_MESSAGES/wxstd.mo +0 -0
  355. wx/locale/lv/LC_MESSAGES/wxstd.mo +0 -0
  356. wx/locale/ms/LC_MESSAGES/wxstd.mo +0 -0
  357. wx/locale/nb/LC_MESSAGES/wxstd.mo +0 -0
  358. wx/locale/ne/LC_MESSAGES/wxstd.mo +0 -0
  359. wx/locale/nl/LC_MESSAGES/wxstd.mo +0 -0
  360. wx/locale/pl/LC_MESSAGES/wxstd.mo +0 -0
  361. wx/locale/pt/LC_MESSAGES/wxstd.mo +0 -0
  362. wx/locale/pt_BR/LC_MESSAGES/wxstd.mo +0 -0
  363. wx/locale/ro/LC_MESSAGES/wxstd.mo +0 -0
  364. wx/locale/ru/LC_MESSAGES/wxstd.mo +0 -0
  365. wx/locale/sk/LC_MESSAGES/wxstd.mo +0 -0
  366. wx/locale/sl/LC_MESSAGES/wxstd.mo +0 -0
  367. wx/locale/sq/LC_MESSAGES/wxstd.mo +0 -0
  368. wx/locale/sr/LC_MESSAGES/wxstd.mo +0 -0
  369. wx/locale/sv/LC_MESSAGES/wxstd.mo +0 -0
  370. wx/locale/ta/LC_MESSAGES/wxstd.mo +0 -0
  371. wx/locale/tr/LC_MESSAGES/wxstd.mo +0 -0
  372. wx/locale/uk/LC_MESSAGES/wxstd.mo +0 -0
  373. wx/locale/vi/LC_MESSAGES/wxstd.mo +0 -0
  374. wx/locale/zh_CN/LC_MESSAGES/wxstd.mo +0 -0
  375. wx/locale/zh_TW/LC_MESSAGES/wxstd.mo +0 -0
  376. wx/media.py +30 -0
  377. wx/media.pyi +272 -0
  378. wx/msw.py +16 -0
  379. wx/msw.pyi +91 -0
  380. wx/propgrid.py +498 -0
  381. wx/propgrid.pyi +7427 -0
  382. wx/py/CHANGES.txt +796 -0
  383. wx/py/Py.ico +0 -0
  384. wx/py/PyAlaCarte.py +34 -0
  385. wx/py/PyAlaMode.py +34 -0
  386. wx/py/PyAlaModeTest.py +33 -0
  387. wx/py/PyCrust.ico +0 -0
  388. wx/py/PyCrust.py +78 -0
  389. wx/py/PyCrust_16.png +0 -0
  390. wx/py/PyCrust_32.png +0 -0
  391. wx/py/PyFilling.py +35 -0
  392. wx/py/PyShell.py +78 -0
  393. wx/py/PySlices.ico +0 -0
  394. wx/py/PySlices.py +98 -0
  395. wx/py/PySlicesShell.py +94 -0
  396. wx/py/PySlices_16.png +0 -0
  397. wx/py/PySlices_32.png +0 -0
  398. wx/py/PyWrap.py +52 -0
  399. wx/py/README.txt +77 -0
  400. wx/py/__init__.py +20 -0
  401. wx/py/buffer.py +136 -0
  402. wx/py/crust.py +403 -0
  403. wx/py/crustslices.py +403 -0
  404. wx/py/dispatcher.py +259 -0
  405. wx/py/document.py +37 -0
  406. wx/py/editor.py +844 -0
  407. wx/py/editwindow.py +316 -0
  408. wx/py/filling.py +358 -0
  409. wx/py/frame.py +976 -0
  410. wx/py/images.py +212 -0
  411. wx/py/interpreter.py +161 -0
  412. wx/py/introspect.py +402 -0
  413. wx/py/magic.py +98 -0
  414. wx/py/parse.py +134 -0
  415. wx/py/path.py +36 -0
  416. wx/py/pseudo.py +99 -0
  417. wx/py/shell.py +1579 -0
  418. wx/py/sliceshell.py +3805 -0
  419. wx/py/tests/test_interpreter.py +71 -0
  420. wx/py/tests/test_introspect.py +810 -0
  421. wx/py/tests/test_pseudo.py +70 -0
  422. wx/py/tests/test_version.py +36 -0
  423. wx/py/tests/testall.py +22 -0
  424. wx/py/version.py +7 -0
  425. wx/py.typed +0 -0
  426. wx/ribbon.py +48 -0
  427. wx/ribbon.pyi +3099 -0
  428. wx/richtext.py +141 -0
  429. wx/richtext.pyi +13581 -0
  430. wx/siplib.cp315-win_amd64.pyd +0 -0
  431. wx/siplib.pyi +19 -0
  432. wx/stc.py +59 -0
  433. wx/stc.pyi +9918 -0
  434. wx/svg/__init__.py +363 -0
  435. wx/svg/_nanosvg.cp315-win_amd64.pyd +0 -0
  436. wx/tools/__init__.py +18 -0
  437. wx/tools/dbg.py +268 -0
  438. wx/tools/genaxmodule.py +50 -0
  439. wx/tools/helpviewer.py +92 -0
  440. wx/tools/img2img.py +85 -0
  441. wx/tools/img2png.py +54 -0
  442. wx/tools/img2py.py +306 -0
  443. wx/tools/img2xpm.py +54 -0
  444. wx/tools/pywxrc.py +951 -0
  445. wx/tools/wxget.py +254 -0
  446. wx/tools/wxget_docs_demo.py +183 -0
  447. wx/wxbase334u_net_vc140_x64.dll +0 -0
  448. wx/wxbase334u_vc140_x64.dll +0 -0
  449. wx/wxbase334u_xml_vc140_x64.dll +0 -0
  450. wx/wxmsw334u_adv_vc140_x64.dll +0 -0
  451. wx/wxmsw334u_aui_vc140_x64.dll +0 -0
  452. wx/wxmsw334u_core_vc140_x64.dll +0 -0
  453. wx/wxmsw334u_gl_vc140_x64.dll +0 -0
  454. wx/wxmsw334u_html_vc140_x64.dll +0 -0
  455. wx/wxmsw334u_media_vc140_x64.dll +0 -0
  456. wx/wxmsw334u_propgrid_vc140_x64.dll +0 -0
  457. wx/wxmsw334u_qa_vc140_x64.dll +0 -0
  458. wx/wxmsw334u_ribbon_vc140_x64.dll +0 -0
  459. wx/wxmsw334u_richtext_vc140_x64.dll +0 -0
  460. wx/wxmsw334u_stc_vc140_x64.dll +0 -0
  461. wx/wxmsw334u_webview_vc140_x64.dll +0 -0
  462. wx/wxmsw334u_xrc_vc140_x64.dll +0 -0
  463. wx/xml.py +18 -0
  464. wx/xml.pyi +728 -0
  465. wx/xrc.py +68 -0
  466. wx/xrc.pyi +896 -0
  467. wxpython-4.3.2.dist-info/METADATA +71 -0
  468. wxpython-4.3.2.dist-info/RECORD +472 -0
  469. wxpython-4.3.2.dist-info/WHEEL +5 -0
  470. wxpython-4.3.2.dist-info/entry_points.txt +13 -0
  471. wxpython-4.3.2.dist-info/licenses/LICENSE.txt +610 -0
  472. wxpython-4.3.2.dist-info/top_level.txt +1 -0
@@ -0,0 +1,2985 @@
1
+ # -*- coding: utf-8 -*-
2
+ # pylint: disable=E1101, C0330, C0103
3
+ # E1101: Module X has no Y member
4
+ # C0330: Wrong continued indentation
5
+ # C0103: Invalid attribute/variable/method name
6
+ """
7
+ plotcanvas.py
8
+ =============
9
+
10
+ This is the main window that you will want to import into your application.
11
+
12
+ """
13
+ __docformat__ = "restructuredtext en"
14
+
15
+ # Standard Library
16
+ import sys
17
+ import time as _time
18
+
19
+ # Third-Party
20
+ import wx
21
+ import numpy as np
22
+
23
+ # Package
24
+ from .polyobjects import PlotPrintout
25
+ from .polyobjects import PolyMarker, PolyLine, PolyBoxPlot
26
+ from .utils import DisplaySide
27
+ from .utils import set_displayside
28
+ from .utils import pendingDeprecation
29
+ from .utils import TempStyle
30
+ from .utils import scale_and_shift_point
31
+
32
+
33
+ class PlotCanvas(wx.Panel):
34
+ """
35
+ Creates a PlotCanvas object.
36
+
37
+ Subclass of a wx.Panel which holds two scrollbars and the actual
38
+ plotting canvas (self.canvas). It allows for simple general plotting
39
+ of data with zoom, labels, and automatic axis scaling.
40
+
41
+ This is the main window that you will want to import into your
42
+ application.
43
+
44
+ Parameters for ``__init__`` are the same as any :class:`wx.Panel`.
45
+ """
46
+
47
+ def __init__(self, parent, id=wx.ID_ANY, pos=wx.DefaultPosition,
48
+ size=wx.DefaultSize, style=0, name="plotCanvas"):
49
+ wx.Panel.__init__(self, parent, id, pos, size, style, name)
50
+
51
+ sizer = wx.FlexGridSizer(2, 2, 0, 0)
52
+ self.canvas = wx.Window(self, -1)
53
+ self.sb_vert = wx.ScrollBar(self, -1, style=wx.SB_VERTICAL)
54
+ self.sb_vert.SetScrollbar(0, 1000, 1000, 1000)
55
+ self.sb_hor = wx.ScrollBar(self, -1, style=wx.SB_HORIZONTAL)
56
+ self.sb_hor.SetScrollbar(0, 1000, 1000, 1000)
57
+
58
+ sizer.Add(self.canvas, 1, wx.EXPAND)
59
+ sizer.Add(self.sb_vert, 0, wx.EXPAND)
60
+ sizer.Add(self.sb_hor, 0, wx.EXPAND)
61
+ sizer.Add((0, 0))
62
+
63
+ self.sb_vert.Show(False)
64
+ self.sb_hor.Show(False)
65
+
66
+ self.SetSizer(sizer)
67
+ sizer.AddGrowableRow(0, 1)
68
+ sizer.AddGrowableCol(0, 1)
69
+ self.Fit()
70
+
71
+ self.border = (1, 1)
72
+
73
+ self.SetBackgroundColour("white")
74
+ self.SetForegroundColour("black")
75
+
76
+ # Create some mouse events for zooming
77
+ self.canvas.Bind(wx.EVT_LEFT_DOWN, self.OnMouseLeftDown)
78
+ self.canvas.Bind(wx.EVT_LEFT_UP, self.OnMouseLeftUp)
79
+ self.canvas.Bind(wx.EVT_MOTION, self.OnMotion)
80
+ self.canvas.Bind(wx.EVT_LEFT_DCLICK, self.OnMouseDoubleClick)
81
+ self.canvas.Bind(wx.EVT_RIGHT_DOWN, self.OnMouseRightDown)
82
+
83
+ # scrollbar events
84
+ self.Bind(wx.EVT_SCROLL_THUMBTRACK, self.OnScroll)
85
+ self.Bind(wx.EVT_SCROLL_PAGEUP, self.OnScroll)
86
+ self.Bind(wx.EVT_SCROLL_PAGEDOWN, self.OnScroll)
87
+ self.Bind(wx.EVT_SCROLL_LINEUP, self.OnScroll)
88
+ self.Bind(wx.EVT_SCROLL_LINEDOWN, self.OnScroll)
89
+
90
+ # set cursor as cross-hairs
91
+ self.defaultCursor = wx.Cursor(wx.CURSOR_ARROW)
92
+ self.HandCursor = wx.Cursor(wx.CURSOR_SIZING)
93
+ self.GrabHandCursor = wx.Cursor(wx.CURSOR_SIZING)
94
+ self.MagCursor = wx.Cursor(wx.CURSOR_MAGNIFIER)
95
+ self.canvas.SetCursor(self.defaultCursor)
96
+
97
+ # Things for printing
98
+ self._print_data = None
99
+ self._pageSetupData = None
100
+ self.printerScale = 1
101
+ self.parent = parent
102
+
103
+ # scrollbar variables
104
+ self._sb_ignore = False
105
+ self._sb_show = False
106
+ self._adjustingSB = False
107
+ self._sb_xfullrange = 0
108
+ self._sb_yfullrange = 0
109
+ self._sb_xunit = 0
110
+ self._sb_yunit = 0
111
+
112
+ self._screenCoordinates = np.array([0.0, 0.0])
113
+
114
+ # Zooming variables
115
+ self._zoomInFactor = 0.5
116
+ self._zoomOutFactor = 2
117
+ self._zoomCorner1 = np.array([0.0, 0.0]) # left mouse down corner
118
+ self._zoomCorner2 = np.array([0.0, 0.0]) # left mouse up corner
119
+ self._zoomEnabled = False
120
+ self._hasDragged = False
121
+
122
+ # Drawing Variables
123
+ self.last_draw = None
124
+ self._pointScale = 1
125
+ self._pointShift = 0
126
+ self._xSpec = 'auto'
127
+ self._ySpec = 'auto'
128
+
129
+ # Initial Plot Options
130
+ self._dragEnabled = False
131
+ self._logscale = (False, False)
132
+ self._absScale = (False, False)
133
+ self._gridEnabled = (True, True)
134
+ self._legendEnabled = False
135
+ self._titleEnabled = True
136
+ self._xAxisLabelEnabled = True
137
+ self._yAxisLabelEnabled = True
138
+ self._axesLabelsEnabled = True
139
+ self._centerLinesEnabled = False
140
+ self._diagonalsEnabled = False
141
+ self._ticksEnabled = DisplaySide(False, False, False, False)
142
+ self._axesEnabled = DisplaySide(True, True, True, True)
143
+ self._axesValuesEnabled = DisplaySide(True, True, False, False)
144
+
145
+ # Fonts
146
+ self._fontCache = {}
147
+ self._fontSizeAxis = 10
148
+ self._fontSizeTitle = 15
149
+ self._fontSizeLegend = 7
150
+
151
+ # pointLabels
152
+ self._pointLabelEnabled = False
153
+ self.last_PointLabel = None
154
+ self._pointLabelFunc = None
155
+ self.canvas.Bind(wx.EVT_LEAVE_WINDOW, self.OnLeave)
156
+ if sys.platform != "darwin":
157
+ self._logicalFunction = wx.EQUIV # (NOT src) XOR dst
158
+ else:
159
+ # wx.EQUIV not supported on Mac OS X
160
+ self._logicalFunction = wx.COPY
161
+
162
+ self._useScientificNotation = False
163
+
164
+ self._antiAliasingEnabled = False
165
+ self._hiResEnabled = False
166
+ self._pointSize = (1.0, 1.0)
167
+ self._fontScale = 1.0
168
+
169
+ self.canvas.Bind(wx.EVT_PAINT, self.OnPaint)
170
+ self.canvas.Bind(wx.EVT_SIZE, self.OnSize)
171
+ # OnSize called to make sure the buffer is initialized.
172
+ # This might result in OnSize getting called twice on some
173
+ # platforms at initialization, but little harm done.
174
+ self.OnSize(None) # sets the initial size based on client size
175
+
176
+ # Default Pens
177
+ self._gridPen = wx.Pen(wx.Colour(180, 180, 180, 255),
178
+ int(self._pointSize[0]),
179
+ wx.PENSTYLE_DOT)
180
+
181
+ self._centerLinePen = wx.Pen(wx.RED,
182
+ int(self._pointSize[0]),
183
+ wx.PENSTYLE_SHORT_DASH)
184
+
185
+ self._axesPen = wx.Pen(wx.BLACK,
186
+ int(self._pointSize[0]),
187
+ wx.PENSTYLE_SOLID)
188
+
189
+ self._tickPen = wx.Pen(wx.BLACK,
190
+ int(self._pointSize[0]),
191
+ wx.PENSTYLE_SOLID)
192
+ self._tickLength = tuple(-x * 2 for x in self._pointSize)
193
+
194
+ self._diagonalPen = wx.Pen(wx.BLUE,
195
+ int(self._pointSize[0]),
196
+ wx.PENSTYLE_DOT_DASH)
197
+
198
+ def SetCursor(self, cursor):
199
+ self.canvas.SetCursor(cursor)
200
+
201
+ ### Pen Properties
202
+ @property
203
+ def gridPen(self):
204
+ """
205
+ The :class:`wx.Pen` used to draw the grid lines on the plot.
206
+
207
+ :getter: Returns the :class:`wx.Pen` used for drawing the grid
208
+ lines.
209
+ :setter: Sets the :class:`wx.Pen` use for drawging the grid lines.
210
+ :type: :class:`wx.Pen`
211
+ :raise: `TypeError` when setting a value that is not a
212
+ :class:`wx.Pen`.
213
+ """
214
+ return self._gridPen
215
+
216
+ @gridPen.setter
217
+ def gridPen(self, pen):
218
+ if not isinstance(pen, wx.Pen):
219
+ raise TypeError("pen must be an instance of wx.Pen")
220
+ self._gridPen = pen
221
+
222
+ @property
223
+ def diagonalPen(self):
224
+ """
225
+ The :class:`wx.Pen` used to draw the diagonal lines on the plot.
226
+
227
+ :getter: Returns the :class:`wx.Pen` used for drawing the diagonal
228
+ lines.
229
+ :setter: Sets the :class:`wx.Pen` use for drawging the diagonal lines.
230
+ :type: :class:`wx.Pen`
231
+ :raise: `TypeError` when setting a value that is not a
232
+ :class:`wx.Pen`.
233
+ """
234
+ return self._diagonalPen
235
+
236
+ @diagonalPen.setter
237
+ def diagonalPen(self, pen):
238
+ if not isinstance(pen, wx.Pen):
239
+ raise TypeError("pen must be an instance of wx.Pen")
240
+ self._diagonalPen = pen
241
+
242
+ @property
243
+ def centerLinePen(self):
244
+ """
245
+ The :class:`wx.Pen` used to draw the center lines on the plot.
246
+
247
+ :getter: Returns the :class:`wx.Pen` used for drawing the center
248
+ lines.
249
+ :setter: Sets the :class:`wx.Pen` use for drawging the center lines.
250
+ :type: :class:`wx.Pen`
251
+ :raise: `TypeError` when setting a value that is not a
252
+ :class:`wx.Pen`.
253
+ """
254
+ return self._centerLinePen
255
+
256
+ @centerLinePen.setter
257
+ def centerLinePen(self, pen):
258
+ if not isinstance(pen, wx.Pen):
259
+ raise TypeError("pen must be an instance of wx.Pen")
260
+ self._centerLinePen = pen
261
+
262
+ @property
263
+ def axesPen(self):
264
+ """
265
+ The :class:`wx.Pen` used to draw the axes lines on the plot.
266
+
267
+ :getter: Returns the :class:`wx.Pen` used for drawing the axes
268
+ lines.
269
+ :setter: Sets the :class:`wx.Pen` use for drawging the axes lines.
270
+ :type: :class:`wx.Pen`
271
+ :raise: `TypeError` when setting a value that is not a
272
+ :class:`wx.Pen`.
273
+ """
274
+ return self._axesPen
275
+
276
+ @axesPen.setter
277
+ def axesPen(self, pen):
278
+ if not isinstance(pen, wx.Pen):
279
+ raise TypeError("pen must be an instance of wx.Pen")
280
+ self._axesPen = pen
281
+
282
+ @property
283
+ def tickPen(self):
284
+ """
285
+ The :class:`wx.Pen` used to draw the tick marks on the plot.
286
+
287
+ :getter: Returns the :class:`wx.Pen` used for drawing the tick marks.
288
+ :setter: Sets the :class:`wx.Pen` use for drawging the tick marks.
289
+ :type: :class:`wx.Pen`
290
+ :raise: `TypeError` when setting a value that is not a
291
+ :class:`wx.Pen`.
292
+ """
293
+ return self._tickPen
294
+
295
+ @tickPen.setter
296
+ def tickPen(self, pen):
297
+ if not isinstance(pen, wx.Pen):
298
+ raise TypeError("pen must be an instance of wx.Pen")
299
+ self._tickPen = pen
300
+
301
+ @property
302
+ def tickLength(self):
303
+ """
304
+ The length of the tick marks on an axis.
305
+
306
+ :getter: Returns the length of the tick marks.
307
+ :setter: Sets the length of the tick marks.
308
+ :type: tuple of (xlength, ylength): int or float
309
+ :raise: `TypeError` when setting a value that is not an int or float.
310
+ """
311
+ return self._tickLength
312
+
313
+ @tickLength.setter
314
+ def tickLength(self, length):
315
+ if not isinstance(length, (tuple, list)):
316
+ raise TypeError("`length` must be a 2-tuple of ints or floats")
317
+ self._tickLength = length
318
+
319
+ @property
320
+ def tickLengthPrinterScale(self):
321
+ return (3 * self.printerScale * self._tickLength[0],
322
+ 3 * self.printerScale * self._tickLength[1])
323
+
324
+ # SaveFile
325
+ def SaveFile(self, fileName=''):
326
+ """
327
+ Saves the file to the type specified in the extension. If no file
328
+ name is specified a dialog box is provided. Returns True if
329
+ successful, otherwise False.
330
+
331
+ .bmp Save a Windows bitmap file.
332
+ .xbm Save an X bitmap file.
333
+ .xpm Save an XPM bitmap file.
334
+ .png Save a Portable Network Graphics file.
335
+ .jpg Save a Joint Photographic Experts Group file.
336
+
337
+ """
338
+ extensions = {
339
+ "bmp": wx.BITMAP_TYPE_BMP, # Save a Windows bitmap file.
340
+ "xbm": wx.BITMAP_TYPE_XBM, # Save an X bitmap file.
341
+ "xpm": wx.BITMAP_TYPE_XPM, # Save an XPM bitmap file.
342
+ "jpg": wx.BITMAP_TYPE_JPEG, # Save a JPG file.
343
+ "png": wx.BITMAP_TYPE_PNG, # Save a PNG file.
344
+ }
345
+
346
+ fType = fileName[-3:].lower()
347
+ dlg1 = None
348
+ while fType not in extensions:
349
+
350
+ msg_txt = ('File name extension\n' # implicit str concat
351
+ 'must be one of\nbmp, xbm, xpm, png, or jpg')
352
+
353
+ if dlg1: # FileDialog exists: Check for extension
354
+ dlg2 = wx.MessageDialog(self, msg_txt, 'File Name Error',
355
+ wx.OK | wx.ICON_ERROR)
356
+ try:
357
+ dlg2.ShowModal()
358
+ finally:
359
+ dlg2.Destroy()
360
+ # FileDialog doesn't exist: just check one
361
+ else:
362
+ msg_txt = ("Choose a file with extension bmp, "
363
+ "gif, xbm, xpm, png, or jpg")
364
+ wildcard_str = ("BMP files (*.bmp)|*.bmp|XBM files (*.xbm)|"
365
+ "*.xbm|XPM file (*.xpm)|*.xpm|"
366
+ "PNG files (*.png)|*.png|"
367
+ "JPG files (*.jpg)|*.jpg")
368
+ dlg1 = wx.FileDialog(self,
369
+ msg_txt,
370
+ ".",
371
+ "",
372
+ wildcard_str,
373
+ wx.FD_SAVE | wx.FD_OVERWRITE_PROMPT,
374
+ )
375
+
376
+ if dlg1.ShowModal() == wx.ID_OK:
377
+ fileName = dlg1.GetPath()
378
+ fType = fileName[-3:].lower()
379
+ else: # exit without saving
380
+ dlg1.Destroy()
381
+ return False
382
+
383
+ if dlg1:
384
+ dlg1.Destroy()
385
+
386
+ # Save Bitmap
387
+ res = self._Buffer.SaveFile(fileName, extensions[fType])
388
+ return res
389
+
390
+ @property
391
+ def print_data(self):
392
+ if not self._print_data:
393
+ self._print_data = wx.PrintData()
394
+ self._print_data.SetPaperId(wx.PAPER_LETTER)
395
+ self._print_data.SetOrientation(wx.LANDSCAPE)
396
+ return self._print_data
397
+
398
+ @property
399
+ def pageSetupData(self):
400
+ if not self._pageSetupData:
401
+ self._pageSetupData = wx.PageSetupDialogData()
402
+ self._pageSetupData.SetMarginBottomRight((25, 25))
403
+ self._pageSetupData.SetMarginTopLeft((25, 25))
404
+ self._pageSetupData.SetPrintData(self.print_data)
405
+ return self._pageSetupData
406
+
407
+ def PageSetup(self):
408
+ """Brings up the page setup dialog"""
409
+ data = self.pageSetupData
410
+ data.SetPrintData(self.print_data)
411
+ dlg = wx.PageSetupDialog(self.parent, data)
412
+ try:
413
+ if dlg.ShowModal() == wx.ID_OK:
414
+ data = dlg.GetPageSetupData()
415
+ # updates page parameters from dialog
416
+ self.pageSetupData.SetMarginBottomRight(
417
+ data.GetMarginBottomRight())
418
+ self.pageSetupData.SetMarginTopLeft(data.GetMarginTopLeft())
419
+ self.pageSetupData.SetPrintData(data.GetPrintData())
420
+ self._print_data = wx.PrintData(
421
+ data.GetPrintData()) # updates print_data
422
+ finally:
423
+ dlg.Destroy()
424
+
425
+ def Printout(self, paper=None):
426
+ """Print current plot."""
427
+ if paper is not None:
428
+ self.print_data.SetPaperId(paper)
429
+ pdd = wx.PrintDialogData(self.print_data)
430
+ printer = wx.Printer(pdd)
431
+ out = PlotPrintout(self)
432
+ print_ok = printer.Print(self.parent, out)
433
+ if print_ok:
434
+ self._print_data = wx.PrintData(
435
+ printer.GetPrintDialogData().GetPrintData())
436
+ out.Destroy()
437
+
438
+ def PrintPreview(self):
439
+ """Print-preview current plot."""
440
+ printout = PlotPrintout(self)
441
+ printout2 = PlotPrintout(self)
442
+ self.preview = wx.PrintPreview(printout, printout2, self.print_data)
443
+ if not self.preview.IsOk():
444
+ wx.MessageDialog(self, "Print Preview failed.\n"
445
+ "Check that default printer is configured\n",
446
+ "Print error", wx.OK | wx.CENTRE).ShowModal()
447
+ self.preview.SetZoom(40)
448
+ # search up tree to find frame instance
449
+ frameInst = self
450
+ while not isinstance(frameInst, wx.Frame):
451
+ frameInst = frameInst.GetParent()
452
+ frame = wx.PreviewFrame(self.preview, frameInst, "Preview")
453
+ frame.Initialize()
454
+ frame.SetPosition(self.GetPosition())
455
+ frame.SetSize((600, 550))
456
+ frame.Centre(wx.BOTH)
457
+ frame.Show(True)
458
+
459
+ def setLogScale(self, logscale):
460
+ """
461
+ Set the log scale boolean value.
462
+
463
+ .. deprecated:: Feb 27, 2016
464
+
465
+ Use the :attr:`~wx.lib.plot.plotcanvas.PlotCanvas.logScale`
466
+ property instead.
467
+ """
468
+ pendingDeprecation("self.logScale property")
469
+ self.logScale = logscale
470
+
471
+ def getLogScale(self):
472
+ """
473
+ Set the log scale boolean value.
474
+
475
+ .. deprecated:: Feb 27, 2016
476
+
477
+ Use the :attr:`~wx.lib.plot.plotcanvas.PlotCanvas.logScale`
478
+ property instead.
479
+ """
480
+ pendingDeprecation("self.logScale property")
481
+ return self.logScale
482
+
483
+ @property
484
+ def logScale(self):
485
+ """
486
+ The logScale value as a 2-tuple of bools:
487
+ ``(x_axis_is_log_scale, y_axis_is_log_scale)``.
488
+
489
+ :getter: Returns the value of logScale.
490
+ :setter: Sets the value of logScale.
491
+ :type: tuple of bools, length 2
492
+ :raise: `TypeError` when setting an invalid value.
493
+ """
494
+ return self._logscale
495
+
496
+ @logScale.setter
497
+ def logScale(self, logscale):
498
+ if type(logscale) != tuple:
499
+ raise TypeError(
500
+ 'logscale must be a tuple of bools, e.g. (False, False)'
501
+ )
502
+ if self.last_draw is not None:
503
+ graphics, xAxis, yAxis = self.last_draw
504
+ graphics.logScale = logscale
505
+ self.last_draw = (graphics, None, None)
506
+ self.xSpec = 'min'
507
+ self.ySpec = 'min'
508
+ self._logscale = logscale
509
+
510
+ @property
511
+ def absScale(self):
512
+ """
513
+ The absScale value as a 2-tuple of bools:
514
+ ``(x_axis_is_abs_scale, y_axis_is_abs_scale)``.
515
+
516
+ :getter: Returns the value of absScale.
517
+ :setter: Sets the value of absScale.
518
+ :type: tuple of bools, length 2
519
+ :raise: `TypeError` when setting an invalid value.
520
+ """
521
+ return self._absScale
522
+
523
+ @absScale.setter
524
+ def absScale(self, absscale):
525
+ if not isinstance(absscale, tuple):
526
+ raise TypeError(
527
+ "absscale must be tuple of bools, e.g. (False, False)"
528
+ )
529
+ if self.last_draw is not None:
530
+ graphics, xAxis, yAxis = self.last_draw
531
+ graphics.absScale = absscale
532
+ self.last_draw = (graphics, None, None)
533
+ self.xSpec = 'min'
534
+ self.ySpec = 'min'
535
+ self._absScale = absscale
536
+
537
+ def SetFontSizeAxis(self, point=10):
538
+ """
539
+ Set the tick and axis label font size (default is 10 point)
540
+
541
+ .. deprecated:: Feb 27, 2016
542
+
543
+ Use the :attr:`~wx.lib.plot.plotcanvas.PlotCanvas.fontSizeAxis`
544
+ property
545
+ instead.
546
+ """
547
+ pendingDeprecation("self.fontSizeAxis property")
548
+ self.fontSizeAxis = point
549
+
550
+ def GetFontSizeAxis(self):
551
+ """
552
+ Get current tick and axis label font size in points
553
+
554
+ .. deprecated:: Feb 27, 2016
555
+
556
+ Use the :attr:`~wx.lib.plot.plotcanvas.PlotCanvas.fontSizeAxis`
557
+ property
558
+ instead.
559
+ """
560
+ pendingDeprecation("self.fontSizeAxis property")
561
+ return self.fontSizeAxis
562
+
563
+ @property
564
+ def fontSizeAxis(self):
565
+ """
566
+ The current tick and axis label font size in points.
567
+
568
+ Default is 10pt font.
569
+
570
+ :getter: Returns the value of fontSizeAxis.
571
+ :setter: Sets the value of fontSizeAxis.
572
+ :type: int or float
573
+ """
574
+ return self._fontSizeAxis
575
+
576
+ @fontSizeAxis.setter
577
+ def fontSizeAxis(self, value):
578
+ self._fontSizeAxis = value
579
+
580
+ def SetFontSizeTitle(self, point=15):
581
+ """
582
+ Set Title font size (default is 15 point)
583
+
584
+ .. deprecated:: Feb 27, 2016
585
+
586
+ Use the :attr:`~wx.lib.plot.plotcanvas.PlotCanvas.fontSizeTitle`
587
+ property instead.
588
+ """
589
+ pendingDeprecation("self.fontSizeTitle property")
590
+ self.fontSizeTitle = point
591
+
592
+ def GetFontSizeTitle(self):
593
+ """
594
+ Get Title font size (default is 15 point)
595
+
596
+ .. deprecated:: Feb 27, 2016
597
+
598
+ Use the :attr:`~wx.lib.plot.plotcanvas.PlotCanvas.fontSizeTitle`
599
+ property instead.
600
+ """
601
+ pendingDeprecation("self.fontSizeTitle property")
602
+ return self.fontSizeTitle
603
+
604
+ @property
605
+ def fontSizeTitle(self):
606
+ """
607
+ The current Title font size in points.
608
+
609
+ Default is 15pt font.
610
+
611
+ :getter: Returns the value of fontSizeTitle.
612
+ :setter: Sets the value of fontSizeTitle.
613
+ :type: int or float
614
+ """
615
+ return self._fontSizeTitle
616
+
617
+ @fontSizeTitle.setter
618
+ def fontSizeTitle(self, pointsize):
619
+ self._fontSizeTitle = pointsize
620
+
621
+ def SetFontSizeLegend(self, point=7):
622
+ """
623
+ Set legend font size (default is 7 point)
624
+
625
+ .. deprecated:: Feb 27, 2016
626
+
627
+ Use the :attr:`~wx.lib.plot.plotcanvas.PlotCanvas.fontSizeLegend'
628
+ property instead.
629
+ """
630
+ pendingDeprecation("self.fontSizeLegend property")
631
+ self.fontSizeLegend = point
632
+
633
+ def GetFontSizeLegend(self):
634
+ """
635
+ Get legend font size (default is 7 point)
636
+
637
+ .. deprecated:: Feb 27, 2016
638
+
639
+ Use the :attr:`~wx.lib.plot.plotcanvas.PlotCanvas.fontSizeLegend'
640
+ property instead.
641
+ """
642
+ return self.fontSizeLegend
643
+
644
+ @property
645
+ def fontSizeLegend(self):
646
+ """
647
+ The current Legned font size in points.
648
+
649
+ Default is 7pt font.
650
+
651
+ :getter: Returns the value of fontSizeLegend.
652
+ :setter: Sets the value of fontSizeLegend.
653
+ :type: int or float
654
+ """
655
+ return self._fontSizeLegend
656
+
657
+ @fontSizeLegend.setter
658
+ def fontSizeLegend(self, point):
659
+ self._fontSizeLegend = point
660
+
661
+ def SetShowScrollbars(self, value):
662
+ """
663
+ Set the showScrollbars value.
664
+
665
+ .. deprecated:: Feb 27, 2016
666
+
667
+ Use the :attr:`~wx.lib.plot.plotcanvas.PlotCanvas.showScrollbars`
668
+ property instead.
669
+ """
670
+ pendingDeprecation("self.showScrollbars property")
671
+ self.showScrollbars = value
672
+
673
+ def GetShowScrollbars(self):
674
+ """
675
+ Get the showScrollbars value.
676
+
677
+ .. deprecated:: Feb 27, 2016
678
+
679
+ Use the :attr:`~wx.lib.plot.plotcanvas.PlotCanvas.showScrollbars`
680
+ property instead.
681
+ """
682
+ pendingDeprecation("self.showScrollbars property")
683
+ return self.showScrollbars
684
+
685
+ @property
686
+ def showScrollbars(self):
687
+ """
688
+ The current showScrollbars value.
689
+
690
+ :getter: Returns the value of showScrollbars.
691
+ :setter: Sets the value of showScrollbars.
692
+ :type: bool
693
+ :raises: `TypeError` if setting a non-boolean value.
694
+ """
695
+ return self._sb_show
696
+
697
+ @showScrollbars.setter
698
+ def showScrollbars(self, value):
699
+ if not isinstance(value, bool):
700
+ raise TypeError("Value should be True or False")
701
+ if value == self._sb_show:
702
+ # no change, so don't do anything
703
+ return
704
+ self._sb_show = value
705
+ self.sb_vert.Show(value)
706
+ self.sb_hor.Show(value)
707
+
708
+ def _do_update():
709
+ self.Layout()
710
+ if self.last_draw is not None:
711
+ self._adjustScrollbars()
712
+ wx.CallAfter(_do_update)
713
+
714
+ def SetUseScientificNotation(self, useScientificNotation):
715
+ """
716
+ Set the useScientificNotation value.
717
+
718
+ .. deprecated:: Feb 27, 2016
719
+
720
+ Use the
721
+ :attr:`~wx.lib.plot.plotcanvas.PlotCanvas.useScientificNotation`
722
+ property instead.
723
+ """
724
+ pendingDeprecation("self.useScientificNotation property")
725
+ self.useScientificNotation = useScientificNotation
726
+
727
+ def GetUseScientificNotation(self):
728
+ """
729
+ Get the useScientificNotation value.
730
+
731
+ .. deprecated:: Feb 27, 2016
732
+
733
+ Use the
734
+ :attr:`~wx.lib.plot.plotcanvas.PlotCanvas.useScientificNotation`
735
+ property instead.
736
+ """
737
+ pendingDeprecation("self.useScientificNotation property")
738
+ return self.useScientificNotation
739
+
740
+ @property
741
+ def useScientificNotation(self):
742
+ """
743
+ The current useScientificNotation value.
744
+
745
+ :getter: Returns the value of useScientificNotation.
746
+ :setter: Sets the value of useScientificNotation.
747
+ :type: bool
748
+ :raises: `TypeError` if setting a non-boolean value.
749
+ """
750
+ return self._useScientificNotation
751
+
752
+ @useScientificNotation.setter
753
+ def useScientificNotation(self, value):
754
+ if not isinstance(value, bool):
755
+ raise TypeError("Value should be True or False")
756
+ self._useScientificNotation = value
757
+
758
+ def SetEnableAntiAliasing(self, enableAntiAliasing):
759
+ """
760
+ Set the enableAntiAliasing value.
761
+
762
+ .. deprecated:: Feb 27, 2016
763
+
764
+ Use the
765
+ :attr:`~wx.lib.plot.plotcanvas.PlotCanvas.enableAntiAliasing`
766
+ property instead.
767
+ """
768
+ pendingDeprecation("self.enableAntiAliasing property")
769
+ self.enableAntiAliasing = enableAntiAliasing
770
+
771
+ def GetEnableAntiAliasing(self):
772
+ """
773
+ Get the enableAntiAliasing value.
774
+
775
+ .. deprecated:: Feb 27, 2016
776
+
777
+ Use the
778
+ :attr:`~wx.lib.plot.plotcanvas.PlotCanvas.enableAntiAliasing`
779
+ property instead.
780
+ """
781
+ pendingDeprecation("self.enableAntiAliasing property")
782
+ return self.enableAntiAliasing
783
+
784
+ @property
785
+ def enableAntiAliasing(self):
786
+ """
787
+ The current enableAntiAliasing value.
788
+
789
+ :getter: Returns the value of enableAntiAliasing.
790
+ :setter: Sets the value of enableAntiAliasing.
791
+ :type: bool
792
+ :raises: `TypeError` if setting a non-boolean value.
793
+ """
794
+ return self._antiAliasingEnabled
795
+
796
+ @enableAntiAliasing.setter
797
+ def enableAntiAliasing(self, value):
798
+ if not isinstance(value, bool):
799
+ raise TypeError("Value should be True or False")
800
+ self._antiAliasingEnabled = value
801
+ self.Redraw()
802
+
803
+ def SetEnableHiRes(self, enableHiRes):
804
+ """
805
+ Set the enableHiRes value.
806
+
807
+ .. deprecated:: Feb 27, 2016
808
+
809
+ Use the :attr:`~wx.lib.plot.plotcanvas.PlotCanvas.enableHiRes`
810
+ property instead.
811
+ """
812
+ pendingDeprecation("self.enableHiRes property")
813
+ self.enableHiRes = enableHiRes
814
+
815
+ def GetEnableHiRes(self):
816
+ """
817
+ Get the enableHiRes value.
818
+
819
+ .. deprecated:: Feb 27, 2016
820
+
821
+ Use the :attr:`~wx.lib.plot.plotcanvas.PlotCanvas.enableHiRes`
822
+ property instead.
823
+ """
824
+ pendingDeprecation("self.enableHiRes property")
825
+ return self._hiResEnabled
826
+
827
+ @property
828
+ def enableHiRes(self):
829
+ """
830
+ The current enableHiRes value.
831
+
832
+ :getter: Returns the value of enableHiRes.
833
+ :setter: Sets the value of enableHiRes.
834
+ :type: bool
835
+ :raises: `TypeError` if setting a non-boolean value.
836
+ """
837
+ return self._hiResEnabled
838
+
839
+ @enableHiRes.setter
840
+ def enableHiRes(self, value):
841
+ if not isinstance(value, bool):
842
+ raise TypeError("Value should be True or False")
843
+ self._hiResEnabled = value
844
+ self.Redraw()
845
+
846
+ def SetEnableDrag(self, value):
847
+ """
848
+ Set the enableDrag value.
849
+
850
+ .. deprecated:: Feb 27, 2016
851
+
852
+ Use the :attr:`~wx.lib.plot.plotcanvas.PlotCanvas.enableDrag`
853
+ property instead.
854
+ """
855
+ pendingDeprecation("self.enableDrag property")
856
+ self.enableDrag = value
857
+
858
+ def GetEnableDrag(self):
859
+ """
860
+ Get the enableDrag value.
861
+
862
+ .. deprecated:: Feb 27, 2016
863
+
864
+ Use the :attr:`~wx.lib.plot.plotcanvas.PlotCanvas.enableDrag`
865
+ property instead.
866
+ """
867
+ pendingDeprecation("self.enableDrag property")
868
+ return self.enableDrag
869
+
870
+ @property
871
+ def enableDrag(self):
872
+ """
873
+ The current enableDrag value.
874
+
875
+ :getter: Returns the value of enableDrag.
876
+ :setter: Sets the value of enableDrag.
877
+ :type: bool
878
+ :raises: `TypeError` if setting a non-boolean value.
879
+
880
+ .. note::
881
+ This is mutually exclusive with
882
+ :attr:`~wx.lib.plot.plotcanvas.PlotCanvas.enableZoom`. Setting
883
+ one will disable the other.
884
+
885
+ .. seealso::
886
+ :attr:`~wx.lib.plot.plotcanvas.PlotCanvas.enableZoom`
887
+ """
888
+ return self._dragEnabled
889
+
890
+ @enableDrag.setter
891
+ def enableDrag(self, value):
892
+ if not isinstance(value, bool):
893
+ raise TypeError("Value must be a bool.")
894
+ if value:
895
+ if self.enableZoom:
896
+ self.enableZoom = False
897
+ self.SetCursor(self.HandCursor)
898
+ else:
899
+ self.SetCursor(self.defaultCursor)
900
+ self._dragEnabled = value
901
+
902
+ def SetEnableZoom(self, value):
903
+ """
904
+ Set the enableZoom value.
905
+
906
+ .. deprecated:: Feb 27, 2016
907
+
908
+ Use the :attr:`~wx.lib.plot.plotcanvas.PlotCanvas.enableZoom`
909
+ property instead.
910
+ """
911
+ pendingDeprecation("self.enableZoom property")
912
+ self.enableZoom = value
913
+
914
+ def GetEnableZoom(self):
915
+ """
916
+ Get the enableZoom value.
917
+
918
+ .. deprecated:: Feb 27, 2016
919
+
920
+ Use the :attr:`~wx.lib.plot.plotcanvas.PlotCanvas.enableZoom`
921
+ property instead.
922
+ """
923
+ pendingDeprecation("self.enableZoom property")
924
+ return self.enableZoom
925
+
926
+ @property
927
+ def enableZoom(self):
928
+ """
929
+ The current enableZoom value.
930
+
931
+ :getter: Returns the value of enableZoom.
932
+ :setter: Sets the value of enableZoom.
933
+ :type: bool
934
+ :raises: `TypeError` if setting a non-boolean value.
935
+
936
+ .. note::
937
+ This is mutually exclusive with
938
+ :attr:`~wx.lib.plot.plotcanvas.PlotCanvas.enableDrag`. Setting
939
+ one will disable the other.
940
+
941
+ .. seealso::
942
+ :attr:`~wx.lib.plot.plotcanvas.PlotCanvas.enableDrag`
943
+ """
944
+ return self._zoomEnabled
945
+
946
+ @enableZoom.setter
947
+ def enableZoom(self, value):
948
+ if not isinstance(value, bool):
949
+ raise TypeError("Value must be a bool.")
950
+ if value:
951
+ if self.enableDrag:
952
+ self.enableDrag = False
953
+ self.SetCursor(self.MagCursor)
954
+ else:
955
+ self.SetCursor(self.defaultCursor)
956
+ self._zoomEnabled = value
957
+
958
+ def SetEnableGrid(self, value):
959
+ """
960
+ Set the enableGrid value.
961
+
962
+ .. deprecated:: Feb 27, 2016
963
+
964
+ Use the :attr:`~wx.lib.plot.plotcanvas.PlotCanvas.enableGrid`
965
+ property instead.
966
+ """
967
+ pendingDeprecation("self.enableGrid property")
968
+ self.enableGrid = value
969
+
970
+ def GetEnableGrid(self):
971
+ """
972
+ Get the enableGrid value.
973
+
974
+ .. deprecated:: Feb 27, 2016
975
+
976
+ Use the :attr:`~wx.lib.plot.plotcanvas.PlotCanvas.enableGrid`
977
+ property instead.
978
+ """
979
+ pendingDeprecation("self.enableGrid property")
980
+ return self.enableGrid
981
+
982
+ @property
983
+ def enableGrid(self):
984
+ """
985
+ The current enableGrid value.
986
+
987
+ :getter: Returns the value of enableGrid.
988
+ :setter: Sets the value of enableGrid.
989
+ :type: bool or 2-tuple of bools
990
+ :raises: `TypeError` if setting an invalid value.
991
+
992
+ If set to a single boolean value, then both X and y grids will be
993
+ enabled (``enableGrid = True``) or disabled (``enableGrid = False``).
994
+
995
+ If a 2-tuple of bools, the 1st value is the X (vertical) grid and
996
+ the 2nd value is the Y (horizontal) grid.
997
+ """
998
+ return self._gridEnabled
999
+
1000
+ @enableGrid.setter
1001
+ def enableGrid(self, value):
1002
+ if isinstance(value, bool):
1003
+ value = (value, value)
1004
+ elif isinstance(value, tuple) and len(value) == 2:
1005
+ pass
1006
+ else:
1007
+ err_txt = "Value must be a bool or 2-tuple of bool."
1008
+ raise TypeError(err_txt)
1009
+
1010
+ self._gridEnabled = value
1011
+ self.Redraw()
1012
+
1013
+ def SetEnableCenterLines(self, value):
1014
+ """
1015
+ Set the enableCenterLines value.
1016
+
1017
+ .. deprecated:: Feb 27, 2016
1018
+
1019
+ Use the :attr:`~wx.lib.plot.plotcanvas.PlotCanvas.enableCenterLines`
1020
+ property instead.
1021
+ """
1022
+ pendingDeprecation("self.enableCenterLines property")
1023
+ self.enableCenterLines = value
1024
+
1025
+ def GetEnableCenterLines(self):
1026
+ """
1027
+ Get the enableCenterLines value.
1028
+
1029
+ .. deprecated:: Feb 27, 2016
1030
+
1031
+ Use the :attr:`~wx.lib.plot.plotcanvas.PlotCanvas.enableCenterLines`
1032
+ property instead.
1033
+ """
1034
+ pendingDeprecation("self.enableCenterLines property")
1035
+ return self.enableCenterLines
1036
+
1037
+ @property
1038
+ def enableCenterLines(self):
1039
+ """
1040
+ The current enableCenterLines value.
1041
+
1042
+ :getter: Returns the value of enableCenterLines.
1043
+ :setter: Sets the value of enableCenterLines.
1044
+ :type: bool or str
1045
+ :raises: `TypeError` if setting an invalid value.
1046
+
1047
+ If set to a single boolean value, then both horizontal and vertical
1048
+ lines will be enabled or disabled.
1049
+
1050
+ If a string, must be one of ``('Horizontal', 'Vertical')``.
1051
+ """
1052
+ return self._centerLinesEnabled
1053
+
1054
+ @enableCenterLines.setter
1055
+ def enableCenterLines(self, value):
1056
+ if value not in [True, False, 'Horizontal', 'Vertical']:
1057
+ raise TypeError(
1058
+ "Value should be True, False, 'Horizontal' or 'Vertical'")
1059
+ self._centerLinesEnabled = value
1060
+ self.Redraw()
1061
+
1062
+ def SetEnableDiagonals(self, value):
1063
+ """
1064
+ Set the enableDiagonals value.
1065
+
1066
+ .. deprecated:: Feb 27, 2016
1067
+
1068
+ Use the :attr:`~wx.lib.plot.plotcanvas.PlotCanvas.enableDiagonals`
1069
+ property instead.
1070
+ """
1071
+ pendingDeprecation("self.enableDiagonals property")
1072
+ self.enableDiagonals = value
1073
+
1074
+ def GetEnableDiagonals(self):
1075
+ """
1076
+ Get the enableDiagonals value.
1077
+
1078
+ .. deprecated:: Feb 27, 2016
1079
+
1080
+ Use the :attr:`~wx.lib.plot.plotcanvas.PlotCanvas.enableDiagonals`
1081
+ property instead.
1082
+ """
1083
+ pendingDeprecation("self.enableDiagonals property")
1084
+ return self.enableDiagonals
1085
+
1086
+ @property
1087
+ def enableDiagonals(self):
1088
+ """
1089
+ The current enableDiagonals value.
1090
+
1091
+ :getter: Returns the value of enableDiagonals.
1092
+ :setter: Sets the value of enableDiagonals.
1093
+ :type: bool or str
1094
+ :raises: `TypeError` if setting an invalid value.
1095
+
1096
+ If set to a single boolean value, then both diagonal lines will
1097
+ be enabled or disabled.
1098
+
1099
+ If a string, must be one of ``('Bottomleft-Topright',
1100
+ 'Bottomright-Topleft')``.
1101
+ """
1102
+ return self._diagonalsEnabled
1103
+
1104
+ @enableDiagonals.setter
1105
+ def enableDiagonals(self, value):
1106
+ # TODO: Rename Bottomleft-TopRight, Bottomright-Topleft
1107
+ if value not in [True, False,
1108
+ 'Bottomleft-Topright', 'Bottomright-Topleft']:
1109
+ raise TypeError(
1110
+ "Value should be True, False, 'Bottomleft-Topright' or "
1111
+ "'Bottomright-Topleft'"
1112
+ )
1113
+ self._diagonalsEnabled = value
1114
+ self.Redraw()
1115
+
1116
+ def SetEnableLegend(self, value):
1117
+ """
1118
+ Set the enableLegend value.
1119
+
1120
+ .. deprecated:: Feb 27, 2016
1121
+
1122
+ Use the :attr:`~wx.lib.plot.plotcanvas.PlotCanvas.enableLegend`
1123
+ property instead.
1124
+ """
1125
+ pendingDeprecation("self.enableLegend property")
1126
+ self.enableLegend = value
1127
+
1128
+ def GetEnableLegend(self):
1129
+ """
1130
+ Get the enableLegend value.
1131
+
1132
+ .. deprecated:: Feb 27, 2016
1133
+
1134
+ Use the :attr:`~wx.lib.plot.plotcanvas.PlotCanvas.enableLegend`
1135
+ property instead.
1136
+ """
1137
+ pendingDeprecation("self.enableLegend property")
1138
+ return self.enableLegend
1139
+
1140
+ @property
1141
+ def enableLegend(self):
1142
+ """
1143
+ The current enableLegend value.
1144
+
1145
+ :getter: Returns the value of enableLegend.
1146
+ :setter: Sets the value of enableLegend.
1147
+ :type: bool
1148
+ :raises: `TypeError` if setting a non-boolean value.
1149
+ """
1150
+ return self._legendEnabled
1151
+
1152
+ @enableLegend.setter
1153
+ def enableLegend(self, value):
1154
+ """Set True to enable legend."""
1155
+ # XXX: why not `if not isinstance(value, bool):`?
1156
+ if value not in [True, False]:
1157
+ raise TypeError("Value should be True or False")
1158
+ self._legendEnabled = value
1159
+ self.Redraw()
1160
+
1161
+ def SetEnableTitle(self, value):
1162
+ """
1163
+ Set the enableTitle value.
1164
+
1165
+ .. deprecated:: Feb 27, 2016
1166
+
1167
+ Use the :attr:`~wx.lib.plot.plotcanvas.PlotCanvas.enableTitle`
1168
+ property instead.
1169
+ """
1170
+ pendingDeprecation("self.enableTitle property")
1171
+ self.enableTitle = value
1172
+
1173
+ def GetEnableTitle(self):
1174
+ """
1175
+ Get the enableTitle value.
1176
+
1177
+ .. deprecated:: Feb 27, 2016
1178
+
1179
+ Use the :attr:`~wx.lib.plot.plotcanvas.PlotCanvas.enableTitle`
1180
+ property instead.
1181
+ """
1182
+ pendingDeprecation("self.enableTitle property")
1183
+ return self.enableTitle
1184
+
1185
+ @property
1186
+ def enableTitle(self):
1187
+ """
1188
+ The current enableTitle value.
1189
+
1190
+ :getter: Returns the value of enableTitle.
1191
+ :setter: Sets the value of enableTitle.
1192
+ :type: bool
1193
+ :raises: `TypeError` if setting a non-boolean value.
1194
+ """
1195
+ return self._titleEnabled
1196
+
1197
+ @enableTitle.setter
1198
+ def enableTitle(self, value):
1199
+ if not isinstance(value, bool):
1200
+ raise TypeError("Value must be a bool.")
1201
+ self._titleEnabled = value
1202
+ self.Redraw()
1203
+
1204
+ def SetEnablePointLabel(self, value):
1205
+ """
1206
+ Set the enablePointLabel value.
1207
+
1208
+ .. deprecated:: Feb 27, 2016
1209
+
1210
+ Use the :attr:`~wx.lib.plot.plotcanvas.PlotCanvas.enablePointLabel`
1211
+ property instead.
1212
+ """
1213
+ pendingDeprecation("self.enablePointLabel property")
1214
+ self.enablePointLabel = value
1215
+
1216
+ def GetEnablePointLabel(self):
1217
+ """
1218
+ Set the enablePointLabel value.
1219
+
1220
+ .. deprecated:: Feb 27, 2016
1221
+
1222
+ Use the :attr:`~wx.lib.plot.plotcanvas.PlotCanvas.enablePointLabel`
1223
+ property instead.
1224
+ """
1225
+ pendingDeprecation("self.enablePointLabel property")
1226
+ return self.enablePointLabel
1227
+
1228
+ @property
1229
+ def enablePointLabel(self):
1230
+ """
1231
+ The current enablePointLabel value.
1232
+
1233
+ :getter: Returns the value of enablePointLabel.
1234
+ :setter: Sets the value of enablePointLabel.
1235
+ :type: bool
1236
+ :raises: `TypeError` if setting a non-boolean value.
1237
+ """
1238
+ return self._pointLabelEnabled
1239
+
1240
+ @enablePointLabel.setter
1241
+ def enablePointLabel(self, value):
1242
+ if not isinstance(value, bool):
1243
+ raise TypeError("Value must be a bool.")
1244
+ self._pointLabelEnabled = value
1245
+ self.Redraw() # will erase existing pointLabel if present
1246
+ self.last_PointLabel = None
1247
+
1248
+ @property
1249
+ def enableAxes(self):
1250
+ """
1251
+ The current enableAxes value.
1252
+
1253
+ :getter: Returns the value of enableAxes.
1254
+ :setter: Sets the value of enableAxes.
1255
+ :type: bool, 2-tuple of bool, or 4-tuple of bool
1256
+ :raises: `TypeError` if setting an invalid value.
1257
+ :raises: `ValueError` if the tuple has incorrect length.
1258
+
1259
+ If bool, enable or disable all axis
1260
+
1261
+ If 2-tuple, enable or disable the bottom or left axes: ``(bottom,
1262
+ left)``
1263
+
1264
+ If 4-tuple, enable or disable each axis individually: ``(bottom,
1265
+ left, top, right)``
1266
+ """
1267
+ return self._axesEnabled
1268
+
1269
+ @enableAxes.setter
1270
+ def enableAxes(self, value):
1271
+ self._axesEnabled = set_displayside(value)
1272
+ self.Redraw()
1273
+
1274
+ @property
1275
+ def enableAxesValues(self):
1276
+ """
1277
+ The current enableAxesValues value.
1278
+
1279
+ :getter: Returns the value of enableAxesValues.
1280
+ :setter: Sets the value of enableAxesValues.
1281
+ :type: bool, 2-tuple of bool, or 4-tuple of bool
1282
+ :raises: `TypeError` if setting an invalid value.
1283
+ :raises: `ValueError` if the tuple has incorrect length.
1284
+
1285
+ If bool, enable or disable all axis values
1286
+
1287
+ If 2-tuple, enable or disable the bottom or left axes values:
1288
+ ``(bottom, left)``
1289
+
1290
+ If 4-tuple, enable or disable each axis value individually:
1291
+ ``(bottom, left, top, right)``
1292
+ """
1293
+ return self._axesValuesEnabled
1294
+
1295
+ @enableAxesValues.setter
1296
+ def enableAxesValues(self, value):
1297
+ self._axesValuesEnabled = set_displayside(value)
1298
+ self.Redraw()
1299
+
1300
+ @property
1301
+ def enableTicks(self):
1302
+ """
1303
+ The current enableTicks value.
1304
+
1305
+ :getter: Returns the value of enableTicks.
1306
+ :setter: Sets the value of enableTicks.
1307
+ :type: bool, 2-tuple of bool, or 4-tuple of bool
1308
+ :raises: `TypeError` if setting an invalid value.
1309
+ :raises: `ValueError` if the tuple has incorrect length.
1310
+
1311
+ If bool, enable or disable all ticks
1312
+
1313
+ If 2-tuple, enable or disable the bottom or left ticks:
1314
+ ``(bottom, left)``
1315
+
1316
+ If 4-tuple, enable or disable each tick side individually:
1317
+ ``(bottom, left, top, right)``
1318
+ """
1319
+ return self._ticksEnabled
1320
+
1321
+ @enableTicks.setter
1322
+ def enableTicks(self, value):
1323
+ self._ticksEnabled = set_displayside(value)
1324
+ self.Redraw()
1325
+
1326
+ @property
1327
+ def enablePlotTitle(self):
1328
+ """
1329
+ The current enablePlotTitle value.
1330
+
1331
+ :getter: Returns the value of enablePlotTitle.
1332
+ :setter: Sets the value of enablePlotTitle.
1333
+ :type: bool
1334
+ :raises: `TypeError` if setting an invalid value.
1335
+ """
1336
+ return self._titleEnabled
1337
+
1338
+ @enablePlotTitle.setter
1339
+ def enablePlotTitle(self, value):
1340
+ if not isinstance(value, bool):
1341
+ raise TypeError("`value` must be boolean True or False")
1342
+ self._titleEnabled = value
1343
+ self.Redraw()
1344
+
1345
+ @property
1346
+ def enableXAxisLabel(self):
1347
+ """
1348
+ The current enableXAxisLabel value.
1349
+
1350
+ :getter: Returns the value of enableXAxisLabel.
1351
+ :setter: Sets the value of enableXAxisLabel.
1352
+ :type: bool
1353
+ :raises: `TypeError` if setting an invalid value.
1354
+ """
1355
+ return self._xAxisLabelEnabled
1356
+
1357
+ @enableXAxisLabel.setter
1358
+ def enableXAxisLabel(self, value):
1359
+ if not isinstance(value, bool):
1360
+ raise TypeError("`value` must be boolean True or False")
1361
+ self._xAxisLabelEnabled = value
1362
+ self.Redraw()
1363
+
1364
+ @property
1365
+ def enableYAxisLabel(self):
1366
+ """
1367
+ The current enableYAxisLabel value.
1368
+
1369
+ :getter: Returns the value of enableYAxisLabel.
1370
+ :setter: Sets the value of enableYAxisLabel.
1371
+ :type: bool
1372
+ :raises: `TypeError` if setting an invalid value.
1373
+ """
1374
+ return self._yAxisLabelEnabled
1375
+
1376
+ @enableYAxisLabel.setter
1377
+ def enableYAxisLabel(self, value):
1378
+ if not isinstance(value, bool):
1379
+ raise TypeError("`value` must be boolean True or False")
1380
+ self._yAxisLabelEnabled = value
1381
+ self.Redraw()
1382
+
1383
+ # TODO: this conflicts with enableXAxisLabel and enableYAxisLabel
1384
+ @property
1385
+ def enableAxesLabels(self):
1386
+ """
1387
+ The current enableAxesLabels value.
1388
+
1389
+ :getter: Returns the value of enableAxesLabels.
1390
+ :setter: Sets the value of enableAxesLabels.
1391
+ :type: bool
1392
+ :raises: `TypeError` if setting an invalid value.
1393
+ """
1394
+ return self._axesLabelsEnabled
1395
+
1396
+ @enableAxesLabels.setter
1397
+ def enableAxesLabels(self, value):
1398
+ if not isinstance(value, bool):
1399
+ raise TypeError("`value` must be boolean True or False")
1400
+ self._axesLabelsEnabled = value
1401
+ self.Redraw()
1402
+
1403
+ def SetPointLabelFunc(self, func):
1404
+ """
1405
+ Set the enablePointLabel value.
1406
+
1407
+ .. deprecated:: Feb 27, 2016
1408
+
1409
+ Use the :attr:`~wx.lib.plot.plotcanvas.PlotCanvas.enablePointLabel`
1410
+ property instead.
1411
+ """
1412
+ pendingDeprecation("self.pointLabelFunc property")
1413
+ self.pointLabelFunc = func
1414
+
1415
+ def GetPointLabelFunc(self):
1416
+ """
1417
+ Get the enablePointLabel value.
1418
+
1419
+ .. deprecated:: Feb 27, 2016
1420
+
1421
+ Use the :attr:`~wx.lib.plot.plotcanvas.PlotCanvas.enablePointLabel`
1422
+ property instead.
1423
+ """
1424
+ pendingDeprecation("self.pointLabelFunc property")
1425
+ return self.pointLabelFunc
1426
+
1427
+ @property
1428
+ def pointLabelFunc(self):
1429
+ """
1430
+ The current pointLabelFunc value.
1431
+
1432
+ :getter: Returns the value of pointLabelFunc.
1433
+ :setter: Sets the value of pointLabelFunc.
1434
+ :type: function
1435
+
1436
+ TODO: More information is needed.
1437
+ Sets the function with custom code for pointLabel drawing
1438
+ """
1439
+ return self._pointLabelFunc
1440
+
1441
+ @pointLabelFunc.setter
1442
+ def pointLabelFunc(self, func):
1443
+ self._pointLabelFunc = func
1444
+
1445
+ def Reset(self):
1446
+ """Unzoom the plot."""
1447
+ self.last_PointLabel = None # reset pointLabel
1448
+ if self.last_draw is not None:
1449
+ self._Draw(self.last_draw[0])
1450
+
1451
+ def ScrollRight(self, units):
1452
+ """Move view right number of axis units."""
1453
+ self.last_PointLabel = None # reset pointLabel
1454
+ if self.last_draw is not None:
1455
+ graphics, xAxis, yAxis = self.last_draw
1456
+ xAxis = (xAxis[0] + units, xAxis[1] + units)
1457
+ self._Draw(graphics, xAxis, yAxis)
1458
+
1459
+ def ScrollLeft(self, units):
1460
+ """Move view left number of axis units."""
1461
+ self.ScrollRight(-units)
1462
+
1463
+ def ScrollUp(self, units):
1464
+ """Move view up number of axis units."""
1465
+ self.last_PointLabel = None # reset pointLabel
1466
+ if self.last_draw is not None:
1467
+ graphics, xAxis, yAxis = self.last_draw
1468
+ yAxis = (yAxis[0] + units, yAxis[1] + units)
1469
+ self._Draw(graphics, xAxis, yAxis)
1470
+
1471
+ def ScrollDown(self, units):
1472
+ """Move view down number of axis units."""
1473
+ self.ScrollUp(-units)
1474
+
1475
+ def GetXY(self, event):
1476
+ """Wrapper around _getXY, which handles log scales"""
1477
+ x, y = self._getXY(event)
1478
+ if self.logScale[0]:
1479
+ x = np.power(10, x)
1480
+ if self.logScale[1]:
1481
+ y = np.power(10, y)
1482
+ return x, y
1483
+
1484
+ def _getXY(self, event):
1485
+ """Takes a mouse event and returns the XY user axis values."""
1486
+ x, y = self.PositionScreenToUser(event.GetPosition())
1487
+ return x, y
1488
+
1489
+ def PositionUserToScreen(self, pntXY):
1490
+ """Converts User position to Screen Coordinates"""
1491
+ userPos = np.array(pntXY)
1492
+ x, y = userPos * self._pointScale + self._pointShift
1493
+ return x, y
1494
+
1495
+ def PositionScreenToUser(self, pntXY):
1496
+ """Converts Screen position to User Coordinates"""
1497
+ screenPos = np.array(pntXY)
1498
+ x, y = (screenPos - self._pointShift) / self._pointScale
1499
+ return x, y
1500
+
1501
+ def SetXSpec(self, spectype='auto'):
1502
+ """
1503
+ Set the xSpec value.
1504
+
1505
+ .. deprecated:: Feb 27, 2016
1506
+
1507
+ Use the :attr:`~wx.lib.plot.plotcanvas.PlotCanvas.xSpec`
1508
+ property instead.
1509
+ """
1510
+ pendingDeprecation("self.xSpec property")
1511
+ self.xSpec = spectype
1512
+
1513
+ def SetYSpec(self, spectype='auto'):
1514
+ """
1515
+ Set the ySpec value.
1516
+
1517
+ .. deprecated:: Feb 27, 2016
1518
+
1519
+ Use the :attr:`~wx.lib.plot.plotcanvas.PlotCanvas.ySpec`
1520
+ property instead.
1521
+ """
1522
+ pendingDeprecation("self.ySpec property")
1523
+ self.ySpec = spectype
1524
+
1525
+ def GetXSpec(self):
1526
+ """
1527
+ Get the xSpec value.
1528
+
1529
+ .. deprecated:: Feb 27, 2016
1530
+
1531
+ Use the :attr:`~wx.lib.plot.plotcanvas.PlotCanvas.xSpec`
1532
+ property instead.
1533
+ """
1534
+ pendingDeprecation("self.xSpec property")
1535
+ return self.xSpec
1536
+
1537
+ def GetYSpec(self):
1538
+ """
1539
+ Get the ySpec value.
1540
+
1541
+ .. deprecated:: Feb 27, 2016
1542
+
1543
+ Use the :attr:`~wx.lib.plot.plotcanvas.PlotCanvas.ySpec`
1544
+ property instead.
1545
+ """
1546
+ pendingDeprecation("self.ySpec property")
1547
+ return self.ySpec
1548
+
1549
+ @property
1550
+ def xSpec(self):
1551
+ """
1552
+ Defines the X axis type.
1553
+
1554
+ Default is 'auto'.
1555
+
1556
+ :getter: Returns the value of xSpec.
1557
+ :setter: Sets the value of xSpec.
1558
+ :type: str, int, or length-2 sequence of floats
1559
+ :raises: `TypeError` if setting an invalid value.
1560
+
1561
+ Valid strings:
1562
+ + 'none' - shows no axis or tick mark values
1563
+ + 'min' - shows min bounding box values
1564
+ + 'auto' - rounds axis range to sensible values
1565
+
1566
+ Other valid values:
1567
+ + <number> - like 'min', but with <number> tick marks
1568
+ + list or tuple: a list of (min, max) values. Must be length 2.
1569
+
1570
+ .. seealso::
1571
+ :attr:`~wx.lib.plot.plotcanvas.PlotCanvas.ySpec`
1572
+ """
1573
+ return self._xSpec
1574
+
1575
+ @xSpec.setter
1576
+ def xSpec(self, value):
1577
+ ok_values = ('none', 'min', 'auto')
1578
+ if value not in ok_values and not isinstance(value, (int, float)):
1579
+ if not isinstance(value, (list, tuple)) and len(value != 2):
1580
+ err_str = ("xSpec must be 'none', 'min', 'auto', "
1581
+ "a number, or sequence of numbers (length 2)")
1582
+ raise TypeError(err_str)
1583
+ self._xSpec = value
1584
+
1585
+ @property
1586
+ def ySpec(self):
1587
+ """
1588
+ Defines the Y axis type.
1589
+
1590
+ Default is 'auto'.
1591
+
1592
+ :getter: Returns the value of xSpec.
1593
+ :setter: Sets the value of xSpec.
1594
+ :type: str, int, or length-2 sequence of floats
1595
+ :raises: `TypeError` if setting an invalid value.
1596
+
1597
+ Valid strings:
1598
+ + 'none' - shows no axis or tick mark values
1599
+ + 'min' - shows min bounding box values
1600
+ + 'auto' - rounds axis range to sensible values
1601
+
1602
+ Other valid values:
1603
+ + <number> - like 'min', but with <number> tick marks
1604
+ + list or tuple: a list of (min, max) values. Must be length 2.
1605
+
1606
+ .. seealso::
1607
+ :attr:`~wx.lib.plot.plotcanvas.PlotCanvas.xSpec`
1608
+ """
1609
+ return self._ySpec
1610
+
1611
+ @ySpec.setter
1612
+ def ySpec(self, value):
1613
+ ok_values = ('none', 'min', 'auto')
1614
+ if value not in ok_values and not isinstance(value, (int, float)):
1615
+ if not isinstance(value, (list, tuple)) and len(value != 2):
1616
+ err_str = ("ySpec must be 'none', 'min', 'auto', "
1617
+ "a number, or sequence of numbers (length 2)")
1618
+ raise TypeError(err_str)
1619
+ self._ySpec = value
1620
+
1621
+ def GetXMaxRange(self):
1622
+ """
1623
+ Get the xMaxRange value.
1624
+
1625
+ .. deprecated:: Feb 27, 2016
1626
+
1627
+ Use the :attr:`~wx.lib.plot.plotcanvas.PlotCanvas.xMaxRange`
1628
+ property instead.
1629
+ """
1630
+ pendingDeprecation("self.xMaxRange property")
1631
+ return self.xMaxRange
1632
+
1633
+ @property
1634
+ def xMaxRange(self):
1635
+ """
1636
+ The plots' maximum X range as a tuple of ``(min, max)``.
1637
+
1638
+ :getter: Returns the value of xMaxRange.
1639
+
1640
+ .. seealso::
1641
+ :attr:`~wx.lib.plot.plotcanvas.PlotCanvas.yMaxRange`
1642
+ """
1643
+ xAxis = self._getXMaxRange()
1644
+ if self.logScale[0]:
1645
+ xAxis = np.power(10, xAxis)
1646
+ return xAxis
1647
+
1648
+ def _getXMaxRange(self):
1649
+ """Returns (minX, maxX) x-axis range for displayed graph"""
1650
+ graphics = self.last_draw[0]
1651
+ p1, p2 = graphics.boundingBox() # min, max points of graphics
1652
+ xAxis = self._axisInterval(self._xSpec, p1[0], p2[0]) # in user units
1653
+ return xAxis
1654
+
1655
+ def GetYMaxRange(self):
1656
+ """
1657
+ Get the yMaxRange value.
1658
+
1659
+ .. deprecated:: Feb 27, 2016
1660
+
1661
+ Use the :attr:`~wx.lib.plot.plotcanvas.PlotCanvas.yMaxRange`
1662
+ property instead.
1663
+ """
1664
+ pendingDeprecation("self.yMaxRange property")
1665
+ return self.yMaxRange
1666
+
1667
+ @property
1668
+ def yMaxRange(self):
1669
+ """
1670
+ The plots' maximum Y range as a tuple of ``(min, max)``.
1671
+
1672
+ :getter: Returns the value of yMaxRange.
1673
+
1674
+ .. seealso::
1675
+ :attr:`~wx.lib.plot.plotcanvas.PlotCanvas.xMaxRange`
1676
+ """
1677
+ yAxis = self._getYMaxRange()
1678
+ if self.logScale[1]:
1679
+ yAxis = np.power(10, yAxis)
1680
+ return yAxis
1681
+
1682
+ def _getYMaxRange(self):
1683
+ """Returns (minY, maxY) y-axis range for displayed graph"""
1684
+ graphics = self.last_draw[0]
1685
+ p1, p2 = graphics.boundingBox() # min, max points of graphics
1686
+ yAxis = self._axisInterval(self._ySpec, p1[1], p2[1])
1687
+ return yAxis
1688
+
1689
+ def GetXCurrentRange(self):
1690
+ """
1691
+ Get the xCurrentRange value.
1692
+
1693
+ .. deprecated:: Feb 27, 2016
1694
+
1695
+ Use the :attr:`~wx.lib.plot.plotcanvas.PlotCanvas.xCurrentRange`
1696
+ property instead.
1697
+ """
1698
+ pendingDeprecation("self.xCurrentRange property")
1699
+ return self.xCurrentRange
1700
+
1701
+ @property
1702
+ def xCurrentRange(self):
1703
+ """
1704
+ The plots' X range of the currently displayed portion as
1705
+ a tuple of ``(min, max)``
1706
+
1707
+ :getter: Returns the value of xCurrentRange.
1708
+
1709
+ .. seealso::
1710
+ :attr:`~wx.lib.plot.plotcanvas.PlotCanvas.yCurrentRange`
1711
+ """
1712
+ xAxis = self._getXCurrentRange()
1713
+ if self.logScale[0]:
1714
+ xAxis = np.power(10, xAxis)
1715
+ return xAxis
1716
+
1717
+ def _getXCurrentRange(self):
1718
+ """Returns (minX, maxX) x-axis for currently displayed
1719
+ portion of graph"""
1720
+ return self.last_draw[1]
1721
+
1722
+ def GetYCurrentRange(self):
1723
+ """
1724
+ Get the yCurrentRange value.
1725
+
1726
+ .. deprecated:: Feb 27, 2016
1727
+
1728
+ Use the :attr:`~wx.lib.plot.plotcanvas.PlotCanvas.yCurrentRange`
1729
+ property instead.
1730
+ """
1731
+ pendingDeprecation("self.yCurrentRange property")
1732
+ return self.yCurrentRange
1733
+
1734
+ @property
1735
+ def yCurrentRange(self):
1736
+ """
1737
+ The plots' Y range of the currently displayed portion as
1738
+ a tuple of ``(min, max)``
1739
+
1740
+ :getter: Returns the value of yCurrentRange.
1741
+
1742
+ .. seealso::
1743
+ :attr:`~wx.lib.plot.plotcanvas.PlotCanvas.xCurrentRange`
1744
+ """
1745
+ yAxis = self._getYCurrentRange()
1746
+ if self.logScale[1]:
1747
+ yAxis = np.power(10, yAxis)
1748
+ return yAxis
1749
+
1750
+ def _getYCurrentRange(self):
1751
+ """Returns (minY, maxY) y-axis for currently displayed
1752
+ portion of graph"""
1753
+ return self.last_draw[2]
1754
+
1755
+ def Draw(self, graphics, xAxis=None, yAxis=None, dc=None):
1756
+ """Wrapper around _Draw, which handles log axes"""
1757
+
1758
+ graphics.logScale = self.logScale
1759
+
1760
+ # check Axis is either tuple or none
1761
+ err_txt = "xAxis should be None or (minX, maxX). Got type `{}`."
1762
+ if type(xAxis) not in [type(None), tuple]:
1763
+ raise TypeError(err_txt .format(type(xAxis)))
1764
+
1765
+ err_txt = "yAxis should be None or (minY, maxY). Got type `{}`."
1766
+ if type(yAxis) not in [type(None), tuple]:
1767
+ raise TypeError(err_txt.format(type(yAxis)))
1768
+
1769
+ # check case for axis = (a,b) where a==b caused by improper zooms
1770
+ if xAxis is not None:
1771
+ if xAxis[0] == xAxis[1]:
1772
+ return
1773
+ if self.logScale[0]:
1774
+ xAxis = np.log10(xAxis)
1775
+ if yAxis is not None:
1776
+ if yAxis[0] == yAxis[1]:
1777
+ return
1778
+ if self.logScale[1]:
1779
+ yAxis = np.log10(yAxis)
1780
+ self._Draw(graphics, xAxis, yAxis, dc)
1781
+
1782
+ def _Draw(self, graphics, xAxis=None, yAxis=None, dc=None):
1783
+ """\
1784
+ Draw objects in graphics with specified x and y axis.
1785
+ graphics- instance of PlotGraphics with list of PolyXXX objects
1786
+ xAxis - tuple with (min, max) axis range to view
1787
+ yAxis - same as xAxis
1788
+ dc - drawing context - doesn't have to be specified.
1789
+ If it's not, the offscreen buffer is used
1790
+ """
1791
+
1792
+ if dc is None:
1793
+ # sets new dc and clears it
1794
+ dc = wx.BufferedDC(wx.ClientDC(self.canvas), self._Buffer)
1795
+ bbr = wx.Brush(self.GetBackgroundColour(), wx.BRUSHSTYLE_SOLID)
1796
+ dc.SetBackground(bbr)
1797
+ dc.SetBackgroundMode(wx.SOLID)
1798
+ dc.Clear()
1799
+ if self._antiAliasingEnabled:
1800
+ if not isinstance(dc, wx.GCDC):
1801
+ try:
1802
+ dc = wx.GCDC(dc)
1803
+ except Exception: # XXX: Yucky.
1804
+ pass
1805
+ else:
1806
+ if self._hiResEnabled:
1807
+ # high precision: each logical unit is 1/20 of a point
1808
+ dc.SetMapMode(wx.MM_TWIPS)
1809
+ self._pointSize = tuple(
1810
+ 1.0 / lscale for lscale in dc.GetLogicalScale())
1811
+ self._setSize()
1812
+ elif self._pointSize != (1.0, 1.0):
1813
+ self._pointSize = (1.0, 1.0)
1814
+ self._setSize()
1815
+
1816
+ if (sys.platform in ("darwin", "win32")
1817
+ or not isinstance(dc, wx.GCDC)
1818
+ or wx.VERSION >= (2, 9)):
1819
+ self._fontScale = sum(self._pointSize) / 2.0
1820
+ else:
1821
+ # on Linux, we need to correct the font size by a certain
1822
+ # factor if wx.GCDC is used, to make text the same size as
1823
+ # if wx.GCDC weren't used
1824
+ screenppi = map(float, wx.ScreenDC().GetPPI())
1825
+ ppi = dc.GetPPI()
1826
+ self._fontScale = (
1827
+ (screenppi[0] / ppi[0] * self._pointSize[0]
1828
+ + screenppi[1] / ppi[1] * self._pointSize[1])
1829
+ / 2.0
1830
+ )
1831
+
1832
+ graphics._pointSize = self._pointSize
1833
+
1834
+ dc.SetTextForeground(self.GetForegroundColour())
1835
+ dc.SetTextBackground(self.GetBackgroundColour())
1836
+
1837
+ # dc.Clear()
1838
+
1839
+ # set font size for every thing but title and legend
1840
+ dc.SetFont(self._getFont(self._fontSizeAxis))
1841
+
1842
+ # sizes axis to axis type, create lower left and upper right
1843
+ # corners of plot
1844
+ if xAxis is None or yAxis is None:
1845
+ # One or both axis not specified in Draw
1846
+ p1, p2 = graphics.boundingBox() # min, max points of graphics
1847
+ if xAxis is None:
1848
+ xAxis = self._axisInterval(
1849
+ self._xSpec, p1[0], p2[0]) # in user units
1850
+ if yAxis is None:
1851
+ yAxis = self._axisInterval(self._ySpec, p1[1], p2[1])
1852
+ # Adjust bounding box for axis spec
1853
+ # lower left corner user scale (xmin,ymin)
1854
+ p1[0], p1[1] = xAxis[0], yAxis[0]
1855
+ # upper right corner user scale (xmax,ymax)
1856
+ p2[0], p2[1] = xAxis[1], yAxis[1]
1857
+ else:
1858
+ # Both axis specified in Draw
1859
+ # lower left corner user scale (xmin,ymin)
1860
+ p1 = np.array([xAxis[0], yAxis[0]])
1861
+ # upper right corner user scale (xmax,ymax)
1862
+ p2 = np.array([xAxis[1], yAxis[1]])
1863
+
1864
+ # saves most recent values
1865
+ self.last_draw = (graphics, np.array(xAxis), np.array(yAxis))
1866
+
1867
+ # Get ticks and textExtents for axis if required
1868
+ xticks = yticks = None
1869
+ xTextExtent = yTextExtent = (0, 0) # No text for ticks
1870
+ if self._xSpec != 'none':
1871
+ xticks = self._xticks(xAxis[0], xAxis[1])
1872
+ # w h of x axis text last number on axis
1873
+ xTextExtent = dc.GetTextExtent(xticks[-1][1])
1874
+
1875
+ if self._ySpec != 'none':
1876
+ yticks = self._yticks(yAxis[0], yAxis[1])
1877
+ if self.logScale[1]:
1878
+ # make sure we have enough room to display SI notation.
1879
+ yTextExtent = dc.GetTextExtent('-2e-2')
1880
+ else:
1881
+ yTextExtentBottom = dc.GetTextExtent(yticks[0][1])
1882
+ yTextExtentTop = dc.GetTextExtent(yticks[-1][1])
1883
+ yTextExtent = (max(yTextExtentBottom[0], yTextExtentTop[0]),
1884
+ max(yTextExtentBottom[1], yTextExtentTop[1]))
1885
+
1886
+ # TextExtents for Title and Axis Labels
1887
+ titleWH, xLabelWH, yLabelWH = self._titleLablesWH(dc, graphics)
1888
+
1889
+ # TextExtents for Legend
1890
+ legendBoxWH, legendSymExt, legendTextExt = self._legendWH(
1891
+ dc,
1892
+ graphics
1893
+ )
1894
+
1895
+ # room around graph area
1896
+ # use larger of number width or legend width
1897
+ rhsW = max(xTextExtent[0], legendBoxWH[0]) + 5 * self._pointSize[0]
1898
+ lhsW = yTextExtent[0] + yLabelWH[1] + 3 * self._pointSize[0]
1899
+ bottomH = (max(xTextExtent[1], yTextExtent[1] / 2.)
1900
+ + xLabelWH[1] + 2 * self._pointSize[1])
1901
+ topH = yTextExtent[1] / 2. + titleWH[1]
1902
+ # make plot area smaller by text size
1903
+ textSize_scale = np.array([rhsW + lhsW, bottomH + topH])
1904
+ # shift plot area by this amount
1905
+ textSize_shift = np.array([lhsW, bottomH])
1906
+
1907
+ # Draw the labels (title, axes labels)
1908
+ self._drawPlotAreaLabels(dc, graphics, lhsW, rhsW, titleWH,
1909
+ bottomH, topH, xLabelWH, yLabelWH)
1910
+
1911
+ # drawing legend makers and text
1912
+ if self._legendEnabled:
1913
+ self._drawLegend(dc,
1914
+ graphics,
1915
+ rhsW,
1916
+ topH,
1917
+ legendBoxWH,
1918
+ legendSymExt,
1919
+ legendTextExt)
1920
+
1921
+ # allow for scaling and shifting plotted points
1922
+ scale = ((self.plotbox_size - textSize_scale) / (p2 - p1)
1923
+ * np.array((1, -1)))
1924
+ shift = (-p1 * scale + self.plotbox_origin
1925
+ + textSize_shift * np.array((1, -1)))
1926
+ # make available for mouse events
1927
+ self._pointScale = scale / self._pointSize
1928
+ self._pointShift = shift / self._pointSize
1929
+ self._drawPlotAreaItems(dc, p1, p2, scale, shift, xticks, yticks)
1930
+
1931
+ graphics.scaleAndShift(scale, shift)
1932
+ # thicken up lines and markers if printing
1933
+ graphics.printerScale = self.printerScale
1934
+
1935
+ # set clipping area so drawing does not occur outside axis box
1936
+ ptx, pty, rectWidth, rectHeight = self._point2ClientCoord(p1, p2)
1937
+ # allow graph to overlap axis lines by adding units to w and h
1938
+ dc.SetClippingRegion(int(ptx * self._pointSize[0]),
1939
+ int(pty * self._pointSize[1]),
1940
+ int(rectWidth * self._pointSize[0] + 2),
1941
+ int(rectHeight * self._pointSize[1] + 1))
1942
+ # Draw the lines and markers
1943
+ # start = _time.perf_counter()
1944
+ graphics.draw(dc)
1945
+ # time_str = "entire graphics drawing took: {} seconds"
1946
+ # print(time_str.format(_time.perf_counter() - start))
1947
+ # remove the clipping region
1948
+ dc.DestroyClippingRegion()
1949
+
1950
+ self._adjustScrollbars()
1951
+
1952
+ def Redraw(self, dc=None):
1953
+ """Redraw the existing plot."""
1954
+ if self.last_draw is not None:
1955
+ graphics, xAxis, yAxis = self.last_draw
1956
+ self._Draw(graphics, xAxis, yAxis, dc)
1957
+
1958
+ def Clear(self):
1959
+ """Erase the window."""
1960
+ self.last_PointLabel = None # reset pointLabel
1961
+ dc = wx.BufferedDC(wx.ClientDC(self.canvas), self._Buffer)
1962
+ bbr = wx.Brush(self.GetBackgroundColour(), wx.SOLID)
1963
+ dc.SetBackground(bbr)
1964
+ dc.SetBackgroundMode(wx.SOLID)
1965
+ dc.Clear()
1966
+ if self._antiAliasingEnabled:
1967
+ try:
1968
+ dc = wx.GCDC(dc)
1969
+ except Exception:
1970
+ pass
1971
+ dc.SetTextForeground(self.GetForegroundColour())
1972
+ dc.SetTextBackground(self.GetBackgroundColour())
1973
+ self.last_draw = None
1974
+
1975
+ def Zoom(self, Center, Ratio):
1976
+ """
1977
+ Zoom on the plot
1978
+ Centers on the X,Y coords given in Center
1979
+ Zooms by the Ratio = (Xratio, Yratio) given
1980
+ """
1981
+ self.last_PointLabel = None # reset maker
1982
+ x, y = Center
1983
+ if self.last_draw is not None:
1984
+ (graphics, xAxis, yAxis) = self.last_draw
1985
+ w = (xAxis[1] - xAxis[0]) * Ratio[0]
1986
+ h = (yAxis[1] - yAxis[0]) * Ratio[1]
1987
+ xAxis = (x - w / 2, x + w / 2)
1988
+ yAxis = (y - h / 2, y + h / 2)
1989
+ self._Draw(graphics, xAxis, yAxis)
1990
+
1991
+ def GetClosestPoints(self, pntXY, pointScaled=True):
1992
+ """
1993
+ Returns list with
1994
+ [curveNumber, legend, index of closest point,
1995
+ pointXY, scaledXY, distance]
1996
+ list for each curve.
1997
+ Returns [] if no curves are being plotted.
1998
+
1999
+ x, y in user coords
2000
+ if pointScaled == True based on screen coords
2001
+ if pointScaled == False based on user coords
2002
+ """
2003
+ if self.last_draw is None:
2004
+ # no graph available
2005
+ return []
2006
+ graphics, xAxis, yAxis = self.last_draw
2007
+ l = []
2008
+ for curveNum, obj in enumerate(graphics):
2009
+ # check there are points in the curve
2010
+ if len(obj.points) == 0:
2011
+ continue # go to next obj
2012
+ #[curveNum, legend, closest pt index, pointXY, scaledXY, dist]
2013
+ cn = ([curveNum] +
2014
+ [obj.getLegend()] + obj.getClosestPoint(pntXY, pointScaled))
2015
+ l.append(cn)
2016
+ return l
2017
+
2018
+ def GetClosestPoint(self, pntXY, pointScaled=True):
2019
+ """
2020
+ Returns list with
2021
+ [curveNumber, legend, index of closest point,
2022
+ pointXY, scaledXY, distance]
2023
+ list for only the closest curve.
2024
+ Returns [] if no curves are being plotted.
2025
+
2026
+ x, y in user coords
2027
+ if pointScaled == True based on screen coords
2028
+ if pointScaled == False based on user coords
2029
+ """
2030
+ # closest points on screen based on screen scaling (pointScaled=True)
2031
+ closestPts = self.GetClosestPoints(pntXY, pointScaled)
2032
+ if closestPts == []:
2033
+ return [] # no graph present
2034
+ # find one with least distance
2035
+ dists = [c[-1] for c in closestPts]
2036
+ mdist = min(dists) # Min dist
2037
+ i = dists.index(mdist) # index for min dist
2038
+ return closestPts[i] # this is the closest point on closest curve
2039
+
2040
+ def UpdatePointLabel(self, mDataDict):
2041
+ """
2042
+ Updates the pointLabel point on screen with data contained in
2043
+ mDataDict.
2044
+
2045
+ mDataDict will be passed to your function set by
2046
+ SetPointLabelFunc. It can contain anything you
2047
+ want to display on the screen at the scaledXY point
2048
+ you specify.
2049
+
2050
+ This function can be called from parent window with onClick,
2051
+ onMotion events etc.
2052
+ """
2053
+ if self.last_PointLabel is not None:
2054
+ # compare pointXY
2055
+ if np.any(
2056
+ mDataDict["pointXY"] != self.last_PointLabel["pointXY"]):
2057
+ # closest changed
2058
+ self._drawPointLabel(self.last_PointLabel) # erase old
2059
+ self._drawPointLabel(mDataDict) # plot new
2060
+ else:
2061
+ # just plot new with no erase
2062
+ self._drawPointLabel(mDataDict) # plot new
2063
+ # save for next erase
2064
+ self.last_PointLabel = mDataDict
2065
+
2066
+ # event handlers **********************************
2067
+ # TODO: some of these event handlers can be modified
2068
+ # Meaning: only bind the event if the item is enabled. Disable
2069
+ # the event when the item is disabled.
2070
+ #
2071
+ # Example::
2072
+ #
2073
+ # if self._zoomEnabled:
2074
+ # self.Bind(stuff)
2075
+ # else:
2076
+ # self.UnBind(stuff) # or equivalent
2077
+ #
2078
+ # def OnZoom(self, event):
2079
+ # # process zoom event.
2080
+ #
2081
+ # What this change would do is remove most of the if statements
2082
+ # within these event handlers.
2083
+ def OnMotion(self, event):
2084
+ if self._zoomEnabled and event.LeftIsDown():
2085
+ if self._hasDragged:
2086
+ self._drawRubberBand(
2087
+ self._zoomCorner1, self._zoomCorner2) # remove old
2088
+ else:
2089
+ self._hasDragged = True
2090
+ self._zoomCorner2[0], self._zoomCorner2[1] = self._getXY(event)
2091
+ self._drawRubberBand(
2092
+ self._zoomCorner1, self._zoomCorner2) # add new
2093
+ elif self._dragEnabled and event.LeftIsDown():
2094
+ coordinates = event.GetPosition()
2095
+ newpos, oldpos = map(
2096
+ np.array,
2097
+ map(self.PositionScreenToUser,
2098
+ [coordinates, self._screenCoordinates]
2099
+ )
2100
+ )
2101
+ dist = newpos - oldpos
2102
+ self._screenCoordinates = coordinates
2103
+
2104
+ if self.last_draw is not None:
2105
+ graphics, xAxis, yAxis = self.last_draw
2106
+ yAxis -= dist[1]
2107
+ xAxis -= dist[0]
2108
+ self._Draw(graphics, xAxis, yAxis)
2109
+
2110
+ def OnMouseLeftDown(self, event):
2111
+ self._zoomCorner1[0], self._zoomCorner1[1] = self._getXY(event)
2112
+ self._screenCoordinates = np.array(event.GetPosition())
2113
+ if self._dragEnabled:
2114
+ self.SetCursor(self.GrabHandCursor)
2115
+ self.canvas.CaptureMouse()
2116
+
2117
+ def OnMouseLeftUp(self, event):
2118
+ if self._zoomEnabled:
2119
+ if self._hasDragged is True:
2120
+ self._drawRubberBand(
2121
+ self._zoomCorner1, self._zoomCorner2) # remove old
2122
+ self._zoomCorner2[0], self._zoomCorner2[1] = self._getXY(event)
2123
+ self._hasDragged = False # reset flag
2124
+ minX, minY = np.minimum(self._zoomCorner1, self._zoomCorner2)
2125
+ maxX, maxY = np.maximum(self._zoomCorner1, self._zoomCorner2)
2126
+ self.last_PointLabel = None # reset pointLabel
2127
+ if self.last_draw is not None:
2128
+ self._Draw(self.last_draw[0],
2129
+ xAxis=(minX, maxX),
2130
+ yAxis=(minY, maxY),
2131
+ dc=None)
2132
+ # else: # A box has not been drawn, zoom in on a point
2133
+ # this interfered with the double click, so I've disables it.
2134
+ # X,Y = self._getXY(event)
2135
+ # self.Zoom( (X,Y), (self._zoomInFactor,self._zoomInFactor) )
2136
+ if self._dragEnabled:
2137
+ self.SetCursor(self.HandCursor)
2138
+ if self.canvas.HasCapture():
2139
+ self.canvas.ReleaseMouse()
2140
+
2141
+ def OnMouseDoubleClick(self, event):
2142
+ if self._zoomEnabled:
2143
+ # Give a little time for the click to be totally finished
2144
+ # before (possibly) removing the scrollbars and trigering
2145
+ # size events, etc.
2146
+ wx.CallLater(200, self.Reset)
2147
+
2148
+ def OnMouseRightDown(self, event):
2149
+ if self._zoomEnabled:
2150
+ X, Y = self._getXY(event)
2151
+ self.Zoom((X, Y), (self._zoomOutFactor, self._zoomOutFactor))
2152
+
2153
+ def OnPaint(self, event):
2154
+ # All that is needed here is to draw the buffer to screen
2155
+ if self.last_PointLabel is not None:
2156
+ self._drawPointLabel(self.last_PointLabel) # erase old
2157
+ self.last_PointLabel = None
2158
+ dc = wx.BufferedPaintDC(self.canvas, self._Buffer)
2159
+ if self._antiAliasingEnabled:
2160
+ try:
2161
+ dc = wx.GCDC(dc)
2162
+ except Exception:
2163
+ pass
2164
+
2165
+ def OnSize(self, event):
2166
+ # The Buffer init is done here, to make sure the buffer is always
2167
+ # the same size as the Window
2168
+ Size = self.canvas.GetClientSize()
2169
+ Size.width = max(1, Size.width)
2170
+ Size.height = max(1, Size.height)
2171
+
2172
+ # Make new offscreen bitmap: this bitmap will always have the
2173
+ # current drawing in it, so it can be used to save the image to
2174
+ # a file, or whatever.
2175
+ self._Buffer = wx.Bitmap(Size.width, Size.height)
2176
+ self._setSize()
2177
+
2178
+ self.last_PointLabel = None # reset pointLabel
2179
+
2180
+ if self.last_draw is None:
2181
+ self.Clear()
2182
+ else:
2183
+ graphics, xSpec, ySpec = self.last_draw
2184
+ self._Draw(graphics, xSpec, ySpec)
2185
+
2186
+ def OnLeave(self, event):
2187
+ """Used to erase pointLabel when mouse outside window"""
2188
+ if self.last_PointLabel is not None:
2189
+ self._drawPointLabel(self.last_PointLabel) # erase old
2190
+ self.last_PointLabel = None
2191
+
2192
+ def OnScroll(self, evt):
2193
+ if not self._adjustingSB:
2194
+ self._sb_ignore = True
2195
+ sbpos = evt.GetPosition()
2196
+
2197
+ if evt.GetOrientation() == wx.VERTICAL:
2198
+ fullrange = self.sb_vert.GetRange()
2199
+ pagesize = self.sb_vert.GetPageSize()
2200
+ sbpos = fullrange - pagesize - sbpos
2201
+ dist = (sbpos * self._sb_yunit -
2202
+ (self._getYCurrentRange()[0] - self._sb_yfullrange[0]))
2203
+ self.ScrollUp(dist)
2204
+
2205
+ if evt.GetOrientation() == wx.HORIZONTAL:
2206
+ dist = (sbpos * self._sb_xunit -
2207
+ (self._getXCurrentRange()[0] - self._sb_xfullrange[0]))
2208
+ self.ScrollRight(dist)
2209
+
2210
+ # Private Methods **************************************************
2211
+ def _setSize(self, width=None, height=None):
2212
+ """DC width and height."""
2213
+ if width is None:
2214
+ (self.width, self.height) = self.canvas.GetClientSize()
2215
+ else:
2216
+ self.width, self.height = width, height
2217
+ self.width *= self._pointSize[0] # high precision
2218
+ self.height *= self._pointSize[1] # high precision
2219
+ self.plotbox_size = 0.97 * np.array([self.width, self.height])
2220
+ xo = 0.5 * (self.width - self.plotbox_size[0])
2221
+ yo = self.height - 0.5 * (self.height - self.plotbox_size[1])
2222
+ self.plotbox_origin = np.array([xo, yo])
2223
+
2224
+ def _setPrinterScale(self, scale):
2225
+ """Used to thicken lines and increase marker size for print out."""
2226
+ # line thickness on printer is very thin at 600 dot/in. Markers small
2227
+ self.printerScale = scale
2228
+
2229
+ def _printDraw(self, printDC):
2230
+ """Used for printing."""
2231
+ if self.last_draw is not None:
2232
+ graphics, xSpec, ySpec = self.last_draw
2233
+ self._Draw(graphics, xSpec, ySpec, printDC)
2234
+
2235
+ def _drawPointLabel(self, mDataDict):
2236
+ """Draws and erases pointLabels"""
2237
+ width = self._Buffer.GetWidth()
2238
+ height = self._Buffer.GetHeight()
2239
+ if sys.platform not in ("darwin", "linux"):
2240
+ tmp_Buffer = wx.Bitmap(width, height)
2241
+ dcs = wx.MemoryDC()
2242
+ dcs.SelectObject(tmp_Buffer)
2243
+ dcs.Clear()
2244
+ else:
2245
+ tmp_Buffer = self._Buffer.GetSubBitmap((0, 0, width, height))
2246
+ dcs = wx.MemoryDC(self._Buffer)
2247
+ self._pointLabelFunc(dcs, mDataDict) # custom user pointLabel func
2248
+
2249
+ dc = wx.ClientDC(self.canvas)
2250
+ dc = wx.BufferedDC(dc, self._Buffer)
2251
+ # this will erase if called twice
2252
+ dc.Blit(0, 0, width, height, dcs, 0, 0, self._logicalFunction)
2253
+ if sys.platform in ("darwin", "linux"):
2254
+ self._Buffer = tmp_Buffer
2255
+
2256
+ def _drawLegend(self, dc, graphics, rhsW, topH, legendBoxWH,
2257
+ legendSymExt, legendTextExt):
2258
+ """Draws legend symbols and text"""
2259
+ # top right hand corner of graph box is ref corner
2260
+ trhc = (self.plotbox_origin +
2261
+ (self.plotbox_size - [rhsW, topH]) * [1, -1])
2262
+ # border space between legend sym and graph box
2263
+ legendLHS = .091 * legendBoxWH[0]
2264
+ # 1.1 used as space between lines
2265
+ lineHeight = max(legendSymExt[1], legendTextExt[1]) * 1.1
2266
+ dc.SetFont(self._getFont(self._fontSizeLegend))
2267
+
2268
+ from .polyobjects import PolyLine
2269
+ from .polyobjects import PolyMarker
2270
+ from .polyobjects import PolyBoxPlot
2271
+
2272
+ for i in range(len(graphics)):
2273
+ o = graphics[i]
2274
+ s = i * lineHeight
2275
+ if isinstance(o, PolyMarker) or isinstance(o, PolyBoxPlot):
2276
+ # draw marker with legend
2277
+ pnt = (trhc[0] + legendLHS + legendSymExt[0] / 2.,
2278
+ trhc[1] + s + lineHeight / 2.)
2279
+ o.draw(dc, self.printerScale, coord=np.array([pnt]))
2280
+ elif isinstance(o, PolyLine):
2281
+ # draw line with legend
2282
+ pnt1 = (trhc[0] + legendLHS, trhc[1] + s + lineHeight / 2.)
2283
+ pnt2 = (trhc[0] + legendLHS + legendSymExt[0],
2284
+ trhc[1] + s + lineHeight / 2.)
2285
+ o.draw(dc, self.printerScale, coord=np.array([pnt1, pnt2]))
2286
+ else:
2287
+ raise TypeError(
2288
+ "object is neither PolyMarker or PolyLine instance")
2289
+ # draw legend txt
2290
+ pnt = ((trhc[0] + legendLHS + legendSymExt[0]
2291
+ + 5 * self._pointSize[0]),
2292
+ trhc[1] + s + lineHeight / 2. - legendTextExt[1] / 2)
2293
+ dc.DrawText(o.getLegend(), int(pnt[0]), int(pnt[1]))
2294
+ dc.SetFont(self._getFont(self._fontSizeAxis)) # reset
2295
+
2296
+ def _titleLablesWH(self, dc, graphics):
2297
+ """Draws Title and labels and returns width and height for each"""
2298
+ # TextExtents for Title and Axis Labels
2299
+ dc.SetFont(self._getFont(self._fontSizeTitle))
2300
+ if self.enablePlotTitle:
2301
+ title = graphics.title
2302
+ titleWH = dc.GetTextExtent(title)
2303
+ else:
2304
+ titleWH = (0, 0)
2305
+ dc.SetFont(self._getFont(self._fontSizeAxis))
2306
+ xLabel, yLabel = graphics.xLabel, graphics.yLabel
2307
+ xLabelWH = dc.GetTextExtent(xLabel)
2308
+ yLabelWH = dc.GetTextExtent(yLabel)
2309
+ return titleWH, xLabelWH, yLabelWH
2310
+
2311
+ def _legendWH(self, dc, graphics):
2312
+ """Returns the size in screen units for legend box"""
2313
+ if self._legendEnabled is not True:
2314
+ legendBoxWH = symExt = txtExt = (0, 0)
2315
+ else:
2316
+ # find max symbol size
2317
+ symExt = graphics.getSymExtent(self.printerScale)
2318
+ # find max legend text extent
2319
+ dc.SetFont(self._getFont(self._fontSizeLegend))
2320
+ txtList = graphics.getLegendNames()
2321
+ txtExt = dc.GetTextExtent(txtList[0])
2322
+ for txt in graphics.getLegendNames()[1:]:
2323
+ txtExt = np.maximum(txtExt, dc.GetTextExtent(txt))
2324
+ maxW = symExt[0] + txtExt[0]
2325
+ maxH = max(symExt[1], txtExt[1])
2326
+ # padding .1 for lhs of legend box and space between lines
2327
+ maxW = maxW * 1.1
2328
+ maxH = maxH * 1.1 * len(txtList)
2329
+ dc.SetFont(self._getFont(self._fontSizeAxis))
2330
+ legendBoxWH = (maxW, maxH)
2331
+ return (legendBoxWH, symExt, txtExt)
2332
+
2333
+ def _drawRubberBand(self, corner1, corner2):
2334
+ """Draws/erases rect box from corner1 to corner2"""
2335
+ ptx, pty, rectWidth, rectHeight = self._point2ClientCoord(
2336
+ corner1, corner2)
2337
+ # draw rectangle
2338
+ dc = wx.ClientDC(self.canvas)
2339
+ dc.SetPen(wx.Pen(wx.BLACK))
2340
+ dc.SetBrush(wx.Brush(wx.WHITE, wx.BRUSHSTYLE_TRANSPARENT))
2341
+ dc.SetLogicalFunction(wx.INVERT)
2342
+ dc.DrawRectangle(int(ptx), int(pty), int(rectWidth), int(rectHeight))
2343
+ dc.SetLogicalFunction(wx.COPY)
2344
+
2345
+ def _getFont(self, size):
2346
+ """Take font size, adjusts if printing and returns wx.Font"""
2347
+ s = size * self.printerScale * self._fontScale
2348
+ of = self.GetFont()
2349
+ # Linux speed up to get font from cache rather than X font server
2350
+ key = (int(s), of.GetFamily(), of.GetStyle(), of.GetWeight())
2351
+ font = self._fontCache.get(key, None)
2352
+ if font:
2353
+ return font # yeah! cache hit
2354
+ else:
2355
+ font = wx.Font(
2356
+ int(s), of.GetFamily(), of.GetStyle(), of.GetWeight())
2357
+ self._fontCache[key] = font
2358
+ return font
2359
+
2360
+ def _point2ClientCoord(self, corner1, corner2):
2361
+ """Converts user point coords to client screen int
2362
+ coords x,y,width,height"""
2363
+ c1 = np.array(corner1)
2364
+ c2 = np.array(corner2)
2365
+ # convert to screen coords
2366
+ pt1 = c1 * self._pointScale + self._pointShift
2367
+ pt2 = c2 * self._pointScale + self._pointShift
2368
+ # make height and width positive
2369
+ pul = np.minimum(pt1, pt2) # Upper left corner
2370
+ plr = np.maximum(pt1, pt2) # Lower right corner
2371
+ rectWidth, rectHeight = plr - pul
2372
+ ptx, pty = pul
2373
+ return ptx, pty, rectWidth, rectHeight
2374
+
2375
+ def _axisInterval(self, spec, lower, upper):
2376
+ """Returns sensible axis range for given spec"""
2377
+ if spec == 'none' or spec == 'min' or isinstance(spec, (float, int)):
2378
+ if lower == upper:
2379
+ return lower - 0.5, upper + 0.5
2380
+ else:
2381
+ return lower, upper
2382
+ elif spec == 'auto':
2383
+ range = upper - lower
2384
+ if range == 0.:
2385
+ return lower - 0.5, upper + 0.5
2386
+ log = np.log10(range)
2387
+ power = np.floor(log)
2388
+ fraction = log - power
2389
+ if fraction <= 0.05:
2390
+ power = power - 1
2391
+ grid = 10. ** power
2392
+ lower = lower - lower % grid
2393
+ mod = upper % grid
2394
+ if mod != 0:
2395
+ upper = upper - mod + grid
2396
+ return lower, upper
2397
+ # elif type(spec) == type(()):
2398
+ elif isinstance(spec, tuple):
2399
+ lower, upper = spec
2400
+ if lower <= upper:
2401
+ return lower, upper
2402
+ else:
2403
+ return upper, lower
2404
+ else:
2405
+ raise ValueError(str(spec) + ': illegal axis specification')
2406
+
2407
+ @TempStyle('pen')
2408
+ def _drawGrid(self, dc, p1, p2, scale, shift, xticks, yticks):
2409
+ """
2410
+ Draws the gridlines
2411
+
2412
+ :param :class:`wx.DC` `dc`: The :class:`wx.DC` to draw on.
2413
+ :type `dc`: :class:`wx.DC`
2414
+ :param p1: The lower-left hand corner of the plot in plot coords. So,
2415
+ if the plot ranges from x=-10 to 10 and y=-5 to 5, then
2416
+ p1 = (-10, -5)
2417
+ :type p1: :class:`np.array`, length 2
2418
+ :param p2: The upper-right hand corner of the plot in plot coords. So,
2419
+ if the plot ranges from x=-10 to 10 and y=-5 to 5, then
2420
+ p2 = (10, 5)
2421
+ :type p2: :class:`np.array`, length 2
2422
+ :param scale: The [X, Y] scaling factor to convert plot coords to
2423
+ DC coords
2424
+ :type scale: :class:`np.array`, length 2
2425
+ :param shift: The [X, Y] shift values to convert plot coords to
2426
+ DC coords. Must be in plot units, not DC units.
2427
+ :type shift: :class:`np.array`, length 2
2428
+ :param xticks: The X tick definition
2429
+ :type xticks: list of length-2 lists
2430
+ :param yticks: The Y tick definition
2431
+ :type yticks: list of length-2 lists
2432
+ """
2433
+ # increases thickness for printing only
2434
+ pen = self.gridPen
2435
+ penWidth = self.printerScale * pen.GetWidth()
2436
+ pen.SetWidth(int(penWidth))
2437
+ dc.SetPen(pen)
2438
+
2439
+ x, y, width, height = self._point2ClientCoord(p1, p2)
2440
+
2441
+ if self._xSpec != 'none':
2442
+ if self.enableGrid[0]:
2443
+ for x, _ in xticks:
2444
+ pt = scale_and_shift_point(x, p1[1], scale, shift)
2445
+ dc.DrawLine(int(pt[0]), int(pt[1]), int(pt[0]), int(pt[1] - height))
2446
+
2447
+ if self._ySpec != 'none':
2448
+ if self.enableGrid[1]:
2449
+ for y, label in yticks:
2450
+ pt = scale_and_shift_point(p1[0], y, scale, shift)
2451
+ dc.DrawLine(int(pt[0]), int(pt[1]), int(pt[0] + width), int(pt[1]))
2452
+
2453
+ @TempStyle('pen')
2454
+ def _drawTicks(self, dc, p1, p2, scale, shift, xticks, yticks):
2455
+ """Draw the tick marks
2456
+
2457
+ :param :class:`wx.DC` `dc`: The :class:`wx.DC` to draw on.
2458
+ :type `dc`: :class:`wx.DC`
2459
+ :param p1: The lower-left hand corner of the plot in plot coords. So,
2460
+ if the plot ranges from x=-10 to 10 and y=-5 to 5, then
2461
+ p1 = (-10, -5)
2462
+ :type p1: :class:`np.array`, length 2
2463
+ :param p2: The upper-right hand corner of the plot in plot coords. So,
2464
+ if the plot ranges from x=-10 to 10 and y=-5 to 5, then
2465
+ p2 = (10, 5)
2466
+ :type p2: :class:`np.array`, length 2
2467
+ :param scale: The [X, Y] scaling factor to convert plot coords to
2468
+ DC coords
2469
+ :type scale: :class:`np.array`, length 2
2470
+ :param shift: The [X, Y] shift values to convert plot coords to
2471
+ DC coords. Must be in plot units, not DC units.
2472
+ :type shift: :class:`np.array`, length 2
2473
+ :param xticks: The X tick definition
2474
+ :type xticks: list of length-2 lists
2475
+ :param yticks: The Y tick definition
2476
+ :type yticks: list of length-2 lists
2477
+ """
2478
+ # TODO: add option for ticks to extend outside of graph
2479
+ # - done via negative ticklength values?
2480
+ # + works but the axes values cut off the ticks.
2481
+ # increases thickness for printing only
2482
+ pen = self.tickPen
2483
+ penWidth = self.printerScale * pen.GetWidth()
2484
+ pen.SetWidth(int(penWidth))
2485
+ dc.SetPen(pen)
2486
+
2487
+ # lengthen lines for printing
2488
+ xTickLength = self.tickLengthPrinterScale[0]
2489
+ yTickLength = self.tickLengthPrinterScale[1]
2490
+
2491
+ ticks = self.enableTicks
2492
+ if self.xSpec != 'none': # I don't like this :-/
2493
+ if ticks.bottom:
2494
+ lines = []
2495
+ for x, label in xticks:
2496
+ pt = scale_and_shift_point(x, p1[1], scale, shift)
2497
+ lines.append((int(pt[0]), int(pt[1]), int(pt[0]), int(pt[1] - xTickLength)))
2498
+ dc.DrawLineList(lines)
2499
+ if ticks.top:
2500
+ lines = []
2501
+ for x, label in xticks:
2502
+ pt = scale_and_shift_point(x, p2[1], scale, shift)
2503
+ lines.append((int(pt[0]), int(pt[1]), int(pt[0]), int(pt[1] + xTickLength)))
2504
+ dc.DrawLineList(lines)
2505
+
2506
+ if self.ySpec != 'none':
2507
+ if ticks.left:
2508
+ lines = []
2509
+ for y, label in yticks:
2510
+ pt = scale_and_shift_point(p1[0], y, scale, shift)
2511
+ lines.append((int(pt[0]), int(pt[1]), int(pt[0] + yTickLength), int(pt[1])))
2512
+ dc.DrawLineList(lines)
2513
+ if ticks.right:
2514
+ lines = []
2515
+ for y, label in yticks:
2516
+ pt = scale_and_shift_point(p2[0], y, scale, shift)
2517
+ lines.append((int(pt[0]), int(pt[1]), int(pt[0] - yTickLength), int(pt[1])))
2518
+ dc.DrawLineList(lines)
2519
+
2520
+ @TempStyle('pen')
2521
+ def _drawCenterLines(self, dc, p1, p2, scale, shift):
2522
+ """Draws the center lines
2523
+
2524
+ :param :class:`wx.DC` `dc`: The :class:`wx.DC` to draw on.
2525
+ :type `dc`: :class:`wx.DC`
2526
+ :param p1: The lower-left hand corner of the plot in plot coords. So,
2527
+ if the plot ranges from x=-10 to 10 and y=-5 to 5, then
2528
+ p1 = (-10, -5)
2529
+ :type p1: :class:`np.array`, length 2
2530
+ :param p2: The upper-right hand corner of the plot in plot coords. So,
2531
+ if the plot ranges from x=-10 to 10 and y=-5 to 5, then
2532
+ p2 = (10, 5)
2533
+ :type p2: :class:`np.array`, length 2
2534
+ :param scale: The [X, Y] scaling factor to convert plot coords to
2535
+ DC coords
2536
+ :type scale: :class:`np.array`, length 2
2537
+ :param shift: The [X, Y] shift values to convert plot coords to
2538
+ DC coords. Must be in plot units, not DC units.
2539
+ :type shift: :class:`np.array`, length 2
2540
+ """
2541
+ # increases thickness for printing only
2542
+ pen = self.centerLinePen
2543
+ penWidth = self.printerScale * pen.GetWidth()
2544
+ pen.SetWidth(int(penWidth))
2545
+ dc.SetPen(pen)
2546
+
2547
+ if self._centerLinesEnabled in ('Horizontal', True):
2548
+ y1 = scale[1] * p1[1] + shift[1]
2549
+ y2 = scale[1] * p2[1] + shift[1]
2550
+ y = (y1 - y2) / 2.0 + y2
2551
+ dc.DrawLine(int(scale[0] * p1[0] + shift[0]),
2552
+ int(y),
2553
+ int(scale[0] * p2[0] + shift[0]),
2554
+ int(y))
2555
+ if self._centerLinesEnabled in ('Vertical', True):
2556
+ x1 = scale[0] * p1[0] + shift[0]
2557
+ x2 = scale[0] * p2[0] + shift[0]
2558
+ x = (x1 - x2) / 2.0 + x2
2559
+ dc.DrawLine(int(x),
2560
+ int(scale[1] * p1[1] + shift[1]),
2561
+ int(x),
2562
+ int(scale[1] * p2[1] + shift[1]))
2563
+
2564
+ @TempStyle('pen')
2565
+ def _drawDiagonals(self, dc, p1, p2, scale, shift):
2566
+ """
2567
+ Draws the diagonal lines.
2568
+
2569
+ :param :class:`wx.DC` `dc`: The :class:`wx.DC` to draw on.
2570
+ :type `dc`: :class:`wx.DC`
2571
+ :param p1: The lower-left hand corner of the plot in plot coords. So,
2572
+ if the plot ranges from x=-10 to 10 and y=-5 to 5, then
2573
+ p1 = (-10, -5)
2574
+ :type p1: :class:`np.array`, length 2
2575
+ :param p2: The upper-right hand corner of the plot in plot coords. So,
2576
+ if the plot ranges from x=-10 to 10 and y=-5 to 5, then
2577
+ p2 = (10, 5)
2578
+ :type p2: :class:`np.array`, length 2
2579
+ :param scale: The [X, Y] scaling factor to convert plot coords to
2580
+ DC coords
2581
+ :type scale: :class:`np.array`, length 2
2582
+ :param shift: The [X, Y] shift values to convert plot coords to
2583
+ DC coords. Must be in plot units, not DC units.
2584
+ :type shift: :class:`np.array`, length 2
2585
+ """
2586
+ pen = self.diagonalPen
2587
+ penWidth = self.printerScale * pen.GetWidth()
2588
+ pen.SetWidth(int(penWidth))
2589
+ dc.SetPen(pen)
2590
+
2591
+ if self._diagonalsEnabled in ('Bottomleft-Topright', True):
2592
+ dc.DrawLine(int(scale[0] * p1[0] + shift[0]),
2593
+ int(scale[1] * p1[1] + shift[1]),
2594
+ int(scale[0] * p2[0] + shift[0]),
2595
+ int(scale[1] * p2[1] + shift[1]))
2596
+ if self._diagonalsEnabled in ('Bottomright-Topleft', True):
2597
+ dc.DrawLine(int(scale[0] * p1[0] + shift[0]),
2598
+ int(scale[1] * p2[1] + shift[1]),
2599
+ int(scale[0] * p2[0] + shift[0]),
2600
+ int(scale[1] * p1[1] + shift[1]))
2601
+
2602
+ @TempStyle('pen')
2603
+ def _drawAxes(self, dc, p1, p2, scale, shift):
2604
+ """
2605
+ Draw the frame lines.
2606
+
2607
+ :param :class:`wx.DC` `dc`: The :class:`wx.DC` to draw on.
2608
+ :type `dc`: :class:`wx.DC`
2609
+ :param p1: The lower-left hand corner of the plot in plot coords. So,
2610
+ if the plot ranges from x=-10 to 10 and y=-5 to 5, then
2611
+ p1 = (-10, -5)
2612
+ :type p1: :class:`np.array`, length 2
2613
+ :param p2: The upper-right hand corner of the plot in plot coords. So,
2614
+ if the plot ranges from x=-10 to 10 and y=-5 to 5, then
2615
+ p2 = (10, 5)
2616
+ :type p2: :class:`np.array`, length 2
2617
+ :param scale: The [X, Y] scaling factor to convert plot coords to
2618
+ DC coords
2619
+ :type scale: :class:`np.array`, length 2
2620
+ :param shift: The [X, Y] shift values to convert plot coords to
2621
+ DC coords. Must be in plot units, not DC units.
2622
+ :type shift: :class:`np.array`, length 2
2623
+ """
2624
+ # increases thickness for printing only
2625
+ pen = self.axesPen
2626
+ penWidth = self.printerScale * pen.GetWidth()
2627
+ pen.SetWidth(int(penWidth))
2628
+ dc.SetPen(pen)
2629
+
2630
+ axes = self.enableAxes
2631
+ if self.xSpec != 'none':
2632
+ if axes.bottom:
2633
+ lower, upper = p1[0], p2[0]
2634
+ a1 = scale_and_shift_point(lower, p1[1], scale, shift)
2635
+ a2 = scale_and_shift_point(upper, p1[1], scale, shift)
2636
+ dc.DrawLine(int(a1[0]), int(a1[1]), int(a2[0]), int(a2[1]))
2637
+ if axes.top:
2638
+ lower, upper = p1[0], p2[0]
2639
+ a1 = scale_and_shift_point(lower, p2[1], scale, shift)
2640
+ a2 = scale_and_shift_point(upper, p2[1], scale, shift)
2641
+ dc.DrawLine(int(a1[0]), int(a1[1]), int(a2[0]), int(a2[1]))
2642
+
2643
+ if self.ySpec != 'none':
2644
+ if axes.left:
2645
+ lower, upper = p1[1], p2[1]
2646
+ a1 = scale_and_shift_point(p1[0], lower, scale, shift)
2647
+ a2 = scale_and_shift_point(p1[0], upper, scale, shift)
2648
+ dc.DrawLine(int(a1[0]), int(a1[1]), int(a2[0]), int(a2[1]))
2649
+ if axes.right:
2650
+ lower, upper = p1[1], p2[1]
2651
+ a1 = scale_and_shift_point(p2[0], lower, scale, shift)
2652
+ a2 = scale_and_shift_point(p2[0], upper, scale, shift)
2653
+ dc.DrawLine(int(a1[0]), int(a1[1]), int(a2[0]), int(a2[1]))
2654
+
2655
+ @TempStyle('pen')
2656
+ def _drawAxesValues(self, dc, p1, p2, scale, shift, xticks, yticks):
2657
+ """
2658
+ Draws the axes values: numbers representing each major grid or tick.
2659
+
2660
+ :param :class:`wx.DC` `dc`: The :class:`wx.DC` to draw on.
2661
+ :type `dc`: :class:`wx.DC`
2662
+ :param p1: The lower-left hand corner of the plot in plot coords. So,
2663
+ if the plot ranges from x=-10 to 10 and y=-5 to 5, then
2664
+ p1 = (-10, -5)
2665
+ :type p1: :class:`np.array`, length 2
2666
+ :param p2: The upper-right hand corner of the plot in plot coords. So,
2667
+ if the plot ranges from x=-10 to 10 and y=-5 to 5, then
2668
+ p2 = (10, 5)
2669
+ :type p2: :class:`np.array`, length 2
2670
+ :param scale: The [X, Y] scaling factor to convert plot coords to
2671
+ DC coords
2672
+ :type scale: :class:`np.array`, length 2
2673
+ :param shift: The [X, Y] shift values to convert plot coords to
2674
+ DC coords. Must be in plot units, not DC units.
2675
+ :type shift: :class:`np.array`, length 2
2676
+ :param xticks: The X tick definition
2677
+ :type xticks: list of length-2 lists
2678
+ :param yticks: The Y tick definition
2679
+ :type yticks: list of length-2 lists
2680
+ """
2681
+ # get the tick lengths so that labels don't overlap
2682
+ xTickLength = self.tickLengthPrinterScale[0]
2683
+ yTickLength = self.tickLengthPrinterScale[1]
2684
+ # only care about negative (out of plot area) tick lengths.
2685
+ xTickLength = xTickLength if xTickLength < 0 else 0
2686
+ yTickLength = yTickLength if yTickLength < 0 else 0
2687
+
2688
+ # TODO: More code duplication? Same as _drawGrid and _drawTicks?
2689
+ # TODO: update the bounding boxes when adding right and top values
2690
+ axes = self.enableAxesValues
2691
+ if self.xSpec != 'none':
2692
+ if axes.bottom:
2693
+ labels = [tick[1] for tick in xticks]
2694
+ coords = []
2695
+ for x, label in xticks:
2696
+ w = dc.GetTextExtent(label)[0]
2697
+ pt = scale_and_shift_point(x, p1[1], scale, shift)
2698
+ coords.append(
2699
+ (int(pt[0] - w/2),
2700
+ int(pt[1] + 2 * self._pointSize[1] - xTickLength))
2701
+ )
2702
+ dc.DrawTextList(labels, coords)
2703
+
2704
+ if axes.top:
2705
+ labels = [tick[1] for tick in xticks]
2706
+ coords = []
2707
+ for x, label in xticks:
2708
+ w, h = dc.GetTextExtent(label)
2709
+ pt = scale_and_shift_point(x, p2[1], scale, shift)
2710
+ coords.append(
2711
+ (int(pt[0] - w/2),
2712
+ int(pt[1] - 2 * self._pointSize[1] - h - xTickLength))
2713
+ )
2714
+ dc.DrawTextList(labels, coords)
2715
+
2716
+ if self.ySpec != 'none':
2717
+ if axes.left:
2718
+ h = dc.GetCharHeight()
2719
+ labels = [tick[1] for tick in yticks]
2720
+ coords = []
2721
+ for y, label in yticks:
2722
+ w = dc.GetTextExtent(label)[0]
2723
+ pt = scale_and_shift_point(p1[0], y, scale, shift)
2724
+ coords.append(
2725
+ (int(pt[0] - w - 3 * self._pointSize[0] + yTickLength),
2726
+ int(pt[1] - 0.5 * h))
2727
+ )
2728
+ dc.DrawTextList(labels, coords)
2729
+
2730
+ if axes.right:
2731
+ h = dc.GetCharHeight()
2732
+ labels = [tick[1] for tick in yticks]
2733
+ coords = []
2734
+ for y, label in yticks:
2735
+ w = dc.GetTextExtent(label)[0]
2736
+ pt = scale_and_shift_point(p2[0], y, scale, shift)
2737
+ coords.append(
2738
+ (int(pt[0] + 3 * self._pointSize[0] + yTickLength),
2739
+ int(pt[1] - 0.5 * h))
2740
+ )
2741
+ dc.DrawTextList(labels, coords)
2742
+
2743
+ @TempStyle('pen')
2744
+ def _drawPlotAreaItems(self, dc, p1, p2, scale, shift, xticks, yticks):
2745
+ """
2746
+ Draws each frame element
2747
+
2748
+ :param :class:`wx.DC` `dc`: The :class:`wx.DC` to draw on.
2749
+ :type `dc`: :class:`wx.DC`
2750
+ :param p1: The lower-left hand corner of the plot in plot coords. So,
2751
+ if the plot ranges from x=-10 to 10 and y=-5 to 5, then
2752
+ p1 = (-10, -5)
2753
+ :type p1: :class:`np.array`, length 2
2754
+ :param p2: The upper-right hand corner of the plot in plot coords. So,
2755
+ if the plot ranges from x=-10 to 10 and y=-5 to 5, then
2756
+ p2 = (10, 5)
2757
+ :type p2: :class:`np.array`, length 2
2758
+ :param scale: The [X, Y] scaling factor to convert plot coords to
2759
+ DC coords
2760
+ :type scale: :class:`np.array`, length 2
2761
+ :param shift: The [X, Y] shift values to convert plot coords to
2762
+ DC coords. Must be in plot units, not DC units.
2763
+ :type shift: :class:`np.array`, length 2
2764
+ :param xticks: The X tick definition
2765
+ :type xticks: list of length-2 lists
2766
+ :param yticks: The Y tick definition
2767
+ :type yticks: list of length-2 lists
2768
+ """
2769
+ if self._gridEnabled:
2770
+ self._drawGrid(dc, p1, p2, scale, shift, xticks, yticks)
2771
+
2772
+ if self._ticksEnabled:
2773
+ self._drawTicks(dc, p1, p2, scale, shift, xticks, yticks)
2774
+
2775
+ if self._centerLinesEnabled:
2776
+ self._drawCenterLines(dc, p1, p2, scale, shift)
2777
+
2778
+ if self._diagonalsEnabled:
2779
+ self._drawDiagonals(dc, p1, p2, scale, shift)
2780
+
2781
+ if self._axesEnabled:
2782
+ self._drawAxes(dc, p1, p2, scale, shift)
2783
+
2784
+ if self._axesValuesEnabled:
2785
+ self._drawAxesValues(dc, p1, p2, scale, shift, xticks, yticks)
2786
+
2787
+ @TempStyle('pen')
2788
+ def _drawPlotTitle(self, dc, graphics, lhsW, rhsW, titleWH):
2789
+ """
2790
+ Draws the plot title
2791
+ """
2792
+ dc.SetFont(self._getFont(self._fontSizeTitle))
2793
+ titlePos = (
2794
+ self.plotbox_origin[0] + lhsW
2795
+ + (self.plotbox_size[0] - lhsW - rhsW) / 2. - titleWH[0] / 2.,
2796
+ self.plotbox_origin[1] - self.plotbox_size[1]
2797
+ )
2798
+ dc.DrawText(graphics.title, int(titlePos[0]), int(titlePos[1]))
2799
+
2800
+ def _drawAxesLabels(self, dc, graphics, lhsW, rhsW, bottomH, topH,
2801
+ xLabelWH, yLabelWH):
2802
+ """
2803
+ Draws the axes labels
2804
+ """
2805
+ # get the tick lengths so that labels don't overlap
2806
+ xTickLength = self.tickLengthPrinterScale[0]
2807
+ yTickLength = self.tickLengthPrinterScale[1]
2808
+ # only care about negative (out of plot area) tick lengths.
2809
+ xTickLength = xTickLength if xTickLength < 0 else 0
2810
+ yTickLength = yTickLength if yTickLength < 0 else 0
2811
+
2812
+ # TODO: axes values get big when this is turned off
2813
+ dc.SetFont(self._getFont(self._fontSizeAxis))
2814
+ xLabelPos = (
2815
+ self.plotbox_origin[0] + lhsW
2816
+ + (self.plotbox_size[0] - lhsW - rhsW) / 2. - xLabelWH[0] / 2.,
2817
+ self.plotbox_origin[1] - xLabelWH[1] - yTickLength
2818
+ )
2819
+ dc.DrawText(graphics.xLabel, int(xLabelPos[0]), int(xLabelPos[1]))
2820
+ yLabelPos = (
2821
+ self.plotbox_origin[0] - 3 * self._pointSize[0] + xTickLength,
2822
+ self.plotbox_origin[1] - bottomH
2823
+ - (self.plotbox_size[1] - bottomH - topH) / 2. + yLabelWH[0] / 2.
2824
+ )
2825
+ if graphics.yLabel: # bug fix for Linux
2826
+ dc.DrawRotatedText(
2827
+ graphics.yLabel, int(yLabelPos[0]), int(yLabelPos[1]), 90)
2828
+
2829
+ @TempStyle('pen')
2830
+ def _drawPlotAreaLabels(self, dc, graphics, lhsW, rhsW, titleWH,
2831
+ bottomH, topH, xLabelWH, yLabelWH):
2832
+ """
2833
+ Draw the plot area labels.
2834
+ """
2835
+ if self._titleEnabled:
2836
+ self._drawPlotTitle(dc, graphics, lhsW, rhsW, titleWH)
2837
+
2838
+ if self._axesLabelsEnabled:
2839
+ self._drawAxesLabels(dc, graphics, lhsW, rhsW,
2840
+ bottomH, topH, xLabelWH, yLabelWH)
2841
+
2842
+ def _xticks(self, *args):
2843
+ if self._logscale[0]:
2844
+ return self._logticks(*args)
2845
+ else:
2846
+ attr = {'numticks': self._xSpec}
2847
+ return self._ticks(*args, **attr)
2848
+
2849
+ def _yticks(self, *args):
2850
+ if self._logscale[1]:
2851
+ return self._logticks(*args)
2852
+ else:
2853
+ attr = {'numticks': self._ySpec}
2854
+ return self._ticks(*args, **attr)
2855
+
2856
+ def _logticks(self, lower, upper):
2857
+ #lower,upper = map(np.log10,[lower,upper])
2858
+ # print('logticks',lower,upper)
2859
+ ticks = []
2860
+ mag = np.power(10, np.floor(lower))
2861
+ if upper - lower > 6:
2862
+ t = np.power(10, np.ceil(lower))
2863
+ base = np.power(10, np.floor((upper - lower) / 6))
2864
+
2865
+ def inc(t):
2866
+ return t * base - t
2867
+ else:
2868
+ t = np.ceil(np.power(10, lower) / mag) * mag
2869
+
2870
+ def inc(t):
2871
+ return 10 ** int(np.floor(np.log10(t) + 1e-16))
2872
+ majortick = int(np.log10(mag))
2873
+ while t <= pow(10, upper):
2874
+ if majortick != int(np.floor(np.log10(t) + 1e-16)):
2875
+ majortick = int(np.floor(np.log10(t) + 1e-16))
2876
+ ticklabel = '1e%d' % majortick
2877
+ else:
2878
+ if upper - lower < 2:
2879
+ minortick = int(t / pow(10, majortick) + .5)
2880
+ ticklabel = '%de%d' % (minortick, majortick)
2881
+ else:
2882
+ ticklabel = ''
2883
+ ticks.append((np.log10(t), ticklabel))
2884
+ t += inc(t)
2885
+ if len(ticks) == 0:
2886
+ ticks = [(0, '')]
2887
+ return ticks
2888
+
2889
+ def _ticks(self, lower, upper, numticks=None):
2890
+ if isinstance(numticks, (float, int)):
2891
+ ideal = (upper - lower) / float(numticks)
2892
+ else:
2893
+ ideal = (upper - lower) / 7.
2894
+ log = np.log10(ideal)
2895
+ power = np.floor(log)
2896
+ if isinstance(numticks, (float, int)):
2897
+ grid = ideal
2898
+ else:
2899
+ fraction = log - power
2900
+ factor = 1.
2901
+ error = fraction
2902
+ for f, lf in self._multiples:
2903
+ e = np.fabs(fraction - lf)
2904
+ if e < error:
2905
+ error = e
2906
+ factor = f
2907
+ grid = factor * 10. ** power
2908
+ if self._useScientificNotation and (power > 4 or power < -4):
2909
+ format = '%+7.1e'
2910
+ elif power >= 0:
2911
+ digits = max(1, int(power))
2912
+ format = '%' + repr(digits) + '.0f'
2913
+ else:
2914
+ digits = -int(power)
2915
+ format = '%' + repr(digits + 2) + '.' + repr(digits) + 'f'
2916
+ ticks = []
2917
+ t = -grid * np.floor(-lower / grid)
2918
+ while t <= upper:
2919
+ if t == -0:
2920
+ t = 0
2921
+ ticks.append((t, format % (t,)))
2922
+ t = t + grid
2923
+ return ticks
2924
+
2925
+ _multiples = [(2., np.log10(2.)), (5., np.log10(5.))]
2926
+
2927
+
2928
+ def _adjustScrollbars(self):
2929
+ if self._sb_ignore:
2930
+ self._sb_ignore = False
2931
+ return
2932
+
2933
+ if not self.showScrollbars:
2934
+ return
2935
+
2936
+ self._adjustingSB = True
2937
+ needScrollbars = False
2938
+
2939
+ # horizontal scrollbar
2940
+ r_current = self._getXCurrentRange()
2941
+ r_max = list(self._getXMaxRange())
2942
+ sbfullrange = float(self.sb_hor.GetRange())
2943
+
2944
+ r_max[0] = min(r_max[0], r_current[0])
2945
+ r_max[1] = max(r_max[1], r_current[1])
2946
+
2947
+ self._sb_xfullrange = r_max
2948
+
2949
+ unit = (r_max[1] - r_max[0]) / float(self.sb_hor.GetRange())
2950
+ pos = int((r_current[0] - r_max[0]) / unit)
2951
+
2952
+ if pos >= 0:
2953
+ pagesize = int((r_current[1] - r_current[0]) / unit)
2954
+
2955
+ self.sb_hor.SetScrollbar(pos, pagesize, int(sbfullrange), pagesize)
2956
+ self._sb_xunit = unit
2957
+ needScrollbars = needScrollbars or (pagesize != sbfullrange)
2958
+ else:
2959
+ self.sb_hor.SetScrollbar(0, 1000, 1000, 1000)
2960
+
2961
+ # vertical scrollbar
2962
+ r_current = self._getYCurrentRange()
2963
+ r_max = list(self._getYMaxRange())
2964
+ sbfullrange = float(self.sb_vert.GetRange())
2965
+
2966
+ r_max[0] = min(r_max[0], r_current[0])
2967
+ r_max[1] = max(r_max[1], r_current[1])
2968
+
2969
+ self._sb_yfullrange = r_max
2970
+
2971
+ unit = (r_max[1] - r_max[0]) / sbfullrange
2972
+ pos = int((r_current[0] - r_max[0]) / unit)
2973
+
2974
+ if pos >= 0:
2975
+ pagesize = int((r_current[1] - r_current[0]) / unit)
2976
+ pos = (sbfullrange - 1 - pos - pagesize)
2977
+ self.sb_vert.SetScrollbar(int(pos), pagesize, int(sbfullrange), pagesize)
2978
+ self._sb_yunit = unit
2979
+ needScrollbars = needScrollbars or (pagesize != sbfullrange)
2980
+ else:
2981
+ self.sb_vert.SetScrollbar(0, 1000, 1000, 1000)
2982
+
2983
+ self.sb_hor.Show(needScrollbars)
2984
+ self.sb_vert.Show(needScrollbars)
2985
+ self._adjustingSB = False