mapdata 3.8.0__tar.gz → 3.9.0__tar.gz

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (207) hide show
  1. {mapdata-3.8.0/mapdata.egg-info → mapdata-3.9.0}/PKG-INFO +12 -5
  2. {mapdata-3.8.0 → mapdata-3.9.0}/README.md +11 -4
  3. {mapdata-3.8.0 → mapdata-3.9.0}/mapdata/mapdata.py +392 -25
  4. {mapdata-3.8.0 → mapdata-3.9.0/mapdata.egg-info}/PKG-INFO +12 -5
  5. {mapdata-3.8.0 → mapdata-3.9.0}/setup.py +1 -1
  6. {mapdata-3.8.0 → mapdata-3.9.0}/LICENSE.txt +0 -0
  7. {mapdata-3.8.0 → mapdata-3.9.0}/MANIFEST.in +0 -0
  8. {mapdata-3.8.0 → mapdata-3.9.0}/mapdata/configfile/mapdata.conf +0 -0
  9. {mapdata-3.8.0 → mapdata-3.9.0}/mapdata/symbols/16x16/0.xbm +0 -0
  10. {mapdata-3.8.0 → mapdata-3.9.0}/mapdata/symbols/16x16/1.xbm +0 -0
  11. {mapdata-3.8.0 → mapdata-3.9.0}/mapdata/symbols/16x16/2.xbm +0 -0
  12. {mapdata-3.8.0 → mapdata-3.9.0}/mapdata/symbols/16x16/3.xbm +0 -0
  13. {mapdata-3.8.0 → mapdata-3.9.0}/mapdata/symbols/16x16/4.xbm +0 -0
  14. {mapdata-3.8.0 → mapdata-3.9.0}/mapdata/symbols/16x16/5.xbm +0 -0
  15. {mapdata-3.8.0 → mapdata-3.9.0}/mapdata/symbols/16x16/6.xbm +0 -0
  16. {mapdata-3.8.0 → mapdata-3.9.0}/mapdata/symbols/16x16/7.xbm +0 -0
  17. {mapdata-3.8.0 → mapdata-3.9.0}/mapdata/symbols/16x16/8.xbm +0 -0
  18. {mapdata-3.8.0 → mapdata-3.9.0}/mapdata/symbols/16x16/9.xbm +0 -0
  19. {mapdata-3.8.0 → mapdata-3.9.0}/mapdata/symbols/16x16/A.xbm +0 -0
  20. {mapdata-3.8.0 → mapdata-3.9.0}/mapdata/symbols/16x16/B.xbm +0 -0
  21. {mapdata-3.8.0 → mapdata-3.9.0}/mapdata/symbols/16x16/C.xbm +0 -0
  22. {mapdata-3.8.0 → mapdata-3.9.0}/mapdata/symbols/16x16/D.xbm +0 -0
  23. {mapdata-3.8.0 → mapdata-3.9.0}/mapdata/symbols/16x16/E.xbm +0 -0
  24. {mapdata-3.8.0 → mapdata-3.9.0}/mapdata/symbols/16x16/F.xbm +0 -0
  25. {mapdata-3.8.0 → mapdata-3.9.0}/mapdata/symbols/16x16/G.xbm +0 -0
  26. {mapdata-3.8.0 → mapdata-3.9.0}/mapdata/symbols/16x16/H.xbm +0 -0
  27. {mapdata-3.8.0 → mapdata-3.9.0}/mapdata/symbols/16x16/I.xbm +0 -0
  28. {mapdata-3.8.0 → mapdata-3.9.0}/mapdata/symbols/16x16/J.xbm +0 -0
  29. {mapdata-3.8.0 → mapdata-3.9.0}/mapdata/symbols/16x16/K.xbm +0 -0
  30. {mapdata-3.8.0 → mapdata-3.9.0}/mapdata/symbols/16x16/L.xbm +0 -0
  31. {mapdata-3.8.0 → mapdata-3.9.0}/mapdata/symbols/16x16/M.xbm +0 -0
  32. {mapdata-3.8.0 → mapdata-3.9.0}/mapdata/symbols/16x16/N.xbm +0 -0
  33. {mapdata-3.8.0 → mapdata-3.9.0}/mapdata/symbols/16x16/O.xbm +0 -0
  34. {mapdata-3.8.0 → mapdata-3.9.0}/mapdata/symbols/16x16/P.xbm +0 -0
  35. {mapdata-3.8.0 → mapdata-3.9.0}/mapdata/symbols/16x16/Q.xbm +0 -0
  36. {mapdata-3.8.0 → mapdata-3.9.0}/mapdata/symbols/16x16/R.xbm +0 -0
  37. {mapdata-3.8.0 → mapdata-3.9.0}/mapdata/symbols/16x16/S.xbm +0 -0
  38. {mapdata-3.8.0 → mapdata-3.9.0}/mapdata/symbols/16x16/T.xbm +0 -0
  39. {mapdata-3.8.0 → mapdata-3.9.0}/mapdata/symbols/16x16/U.xbm +0 -0
  40. {mapdata-3.8.0 → mapdata-3.9.0}/mapdata/symbols/16x16/V.xbm +0 -0
  41. {mapdata-3.8.0 → mapdata-3.9.0}/mapdata/symbols/16x16/W.xbm +0 -0
  42. {mapdata-3.8.0 → mapdata-3.9.0}/mapdata/symbols/16x16/X.xbm +0 -0
  43. {mapdata-3.8.0 → mapdata-3.9.0}/mapdata/symbols/16x16/Y.xbm +0 -0
  44. {mapdata-3.8.0 → mapdata-3.9.0}/mapdata/symbols/16x16/Z.xbm +0 -0
  45. {mapdata-3.8.0 → mapdata-3.9.0}/mapdata/symbols/16x16/airplane.xbm +0 -0
  46. {mapdata-3.8.0 → mapdata-3.9.0}/mapdata/symbols/16x16/anchor.xbm +0 -0
  47. {mapdata-3.8.0 → mapdata-3.9.0}/mapdata/symbols/16x16/ball.xbm +0 -0
  48. {mapdata-3.8.0 → mapdata-3.9.0}/mapdata/symbols/16x16/ball_small.xbm +0 -0
  49. {mapdata-3.8.0 → mapdata-3.9.0}/mapdata/symbols/16x16/bar.xbm +0 -0
  50. {mapdata-3.8.0 → mapdata-3.9.0}/mapdata/symbols/16x16/bars.xbm +0 -0
  51. {mapdata-3.8.0 → mapdata-3.9.0}/mapdata/symbols/16x16/binoculars.xbm +0 -0
  52. {mapdata-3.8.0 → mapdata-3.9.0}/mapdata/symbols/16x16/bird.xbm +0 -0
  53. {mapdata-3.8.0 → mapdata-3.9.0}/mapdata/symbols/16x16/block.xbm +0 -0
  54. {mapdata-3.8.0 → mapdata-3.9.0}/mapdata/symbols/16x16/block_small.xbm +0 -0
  55. {mapdata-3.8.0 → mapdata-3.9.0}/mapdata/symbols/16x16/bookmark.xbm +0 -0
  56. {mapdata-3.8.0 → mapdata-3.9.0}/mapdata/symbols/16x16/box_stack.xbm +0 -0
  57. {mapdata-3.8.0 → mapdata-3.9.0}/mapdata/symbols/16x16/camera.xbm +0 -0
  58. {mapdata-3.8.0 → mapdata-3.9.0}/mapdata/symbols/16x16/cancel.xbm +0 -0
  59. {mapdata-3.8.0 → mapdata-3.9.0}/mapdata/symbols/16x16/car.xbm +0 -0
  60. {mapdata-3.8.0 → mapdata-3.9.0}/mapdata/symbols/16x16/car2.xbm +0 -0
  61. {mapdata-3.8.0 → mapdata-3.9.0}/mapdata/symbols/16x16/center8.xbm +0 -0
  62. {mapdata-3.8.0 → mapdata-3.9.0}/mapdata/symbols/16x16/check.xbm +0 -0
  63. {mapdata-3.8.0 → mapdata-3.9.0}/mapdata/symbols/16x16/check_circle.xbm +0 -0
  64. {mapdata-3.8.0 → mapdata-3.9.0}/mapdata/symbols/16x16/checkbox.xbm +0 -0
  65. {mapdata-3.8.0 → mapdata-3.9.0}/mapdata/symbols/16x16/checkerboard.xbm +0 -0
  66. {mapdata-3.8.0 → mapdata-3.9.0}/mapdata/symbols/16x16/chevrons.xbm +0 -0
  67. {mapdata-3.8.0 → mapdata-3.9.0}/mapdata/symbols/16x16/circle.xbm +0 -0
  68. {mapdata-3.8.0 → mapdata-3.9.0}/mapdata/symbols/16x16/circle_bar.xbm +0 -0
  69. {mapdata-3.8.0 → mapdata-3.9.0}/mapdata/symbols/16x16/circle_plus.xbm +0 -0
  70. {mapdata-3.8.0 → mapdata-3.9.0}/mapdata/symbols/16x16/circle_stipple.xbm +0 -0
  71. {mapdata-3.8.0 → mapdata-3.9.0}/mapdata/symbols/16x16/circle_triangle.xbm +0 -0
  72. {mapdata-3.8.0 → mapdata-3.9.0}/mapdata/symbols/16x16/circle_wedge.xbm +0 -0
  73. {mapdata-3.8.0 → mapdata-3.9.0}/mapdata/symbols/16x16/circle_x.xbm +0 -0
  74. {mapdata-3.8.0 → mapdata-3.9.0}/mapdata/symbols/16x16/clock.xbm +0 -0
  75. {mapdata-3.8.0 → mapdata-3.9.0}/mapdata/symbols/16x16/columns.xbm +0 -0
  76. {mapdata-3.8.0 → mapdata-3.9.0}/mapdata/symbols/16x16/contract.xbm +0 -0
  77. {mapdata-3.8.0 → mapdata-3.9.0}/mapdata/symbols/16x16/cross.xbm +0 -0
  78. {mapdata-3.8.0 → mapdata-3.9.0}/mapdata/symbols/16x16/darkeye.xbm +0 -0
  79. {mapdata-3.8.0 → mapdata-3.9.0}/mapdata/symbols/16x16/decrease.xbm +0 -0
  80. {mapdata-3.8.0 → mapdata-3.9.0}/mapdata/symbols/16x16/deposition.xbm +0 -0
  81. {mapdata-3.8.0 → mapdata-3.9.0}/mapdata/symbols/16x16/diag_ll.xbm +0 -0
  82. {mapdata-3.8.0 → mapdata-3.9.0}/mapdata/symbols/16x16/diag_lr.xbm +0 -0
  83. {mapdata-3.8.0 → mapdata-3.9.0}/mapdata/symbols/16x16/diag_ul.xbm +0 -0
  84. {mapdata-3.8.0 → mapdata-3.9.0}/mapdata/symbols/16x16/diag_ur.xbm +0 -0
  85. {mapdata-3.8.0 → mapdata-3.9.0}/mapdata/symbols/16x16/dialog.xbm +0 -0
  86. {mapdata-3.8.0 → mapdata-3.9.0}/mapdata/symbols/16x16/diamond.xbm +0 -0
  87. {mapdata-3.8.0 → mapdata-3.9.0}/mapdata/symbols/16x16/donkey.xbm +0 -0
  88. {mapdata-3.8.0 → mapdata-3.9.0}/mapdata/symbols/16x16/dot.xbm +0 -0
  89. {mapdata-3.8.0 → mapdata-3.9.0}/mapdata/symbols/16x16/down.xbm +0 -0
  90. {mapdata-3.8.0 → mapdata-3.9.0}/mapdata/symbols/16x16/drop.xbm +0 -0
  91. {mapdata-3.8.0 → mapdata-3.9.0}/mapdata/symbols/16x16/elephant.xbm +0 -0
  92. {mapdata-3.8.0 → mapdata-3.9.0}/mapdata/symbols/16x16/expand.xbm +0 -0
  93. {mapdata-3.8.0 → mapdata-3.9.0}/mapdata/symbols/16x16/eye.xbm +0 -0
  94. {mapdata-3.8.0 → mapdata-3.9.0}/mapdata/symbols/16x16/fire.xbm +0 -0
  95. {mapdata-3.8.0 → mapdata-3.9.0}/mapdata/symbols/16x16/fish.xbm +0 -0
  96. {mapdata-3.8.0 → mapdata-3.9.0}/mapdata/symbols/16x16/flag.xbm +0 -0
  97. {mapdata-3.8.0 → mapdata-3.9.0}/mapdata/symbols/16x16/flag2.xbm +0 -0
  98. {mapdata-3.8.0 → mapdata-3.9.0}/mapdata/symbols/16x16/four_arrows.xbm +0 -0
  99. {mapdata-3.8.0 → mapdata-3.9.0}/mapdata/symbols/16x16/graph.xbm +0 -0
  100. {mapdata-3.8.0 → mapdata-3.9.0}/mapdata/symbols/16x16/hand.xbm +0 -0
  101. {mapdata-3.8.0 → mapdata-3.9.0}/mapdata/symbols/16x16/hash.xbm +0 -0
  102. {mapdata-3.8.0 → mapdata-3.9.0}/mapdata/symbols/16x16/heart.xbm +0 -0
  103. {mapdata-3.8.0 → mapdata-3.9.0}/mapdata/symbols/16x16/hidden.xbm +0 -0
  104. {mapdata-3.8.0 → mapdata-3.9.0}/mapdata/symbols/16x16/hourglass.xbm +0 -0
  105. {mapdata-3.8.0 → mapdata-3.9.0}/mapdata/symbols/16x16/house.xbm +0 -0
  106. {mapdata-3.8.0 → mapdata-3.9.0}/mapdata/symbols/16x16/increase.xbm +0 -0
  107. {mapdata-3.8.0 → mapdata-3.9.0}/mapdata/symbols/16x16/info.xbm +0 -0
  108. {mapdata-3.8.0 → mapdata-3.9.0}/mapdata/symbols/16x16/leaf.xbm +0 -0
  109. {mapdata-3.8.0 → mapdata-3.9.0}/mapdata/symbols/16x16/left.xbm +0 -0
  110. {mapdata-3.8.0 → mapdata-3.9.0}/mapdata/symbols/16x16/lightbulb.xbm +0 -0
  111. {mapdata-3.8.0 → mapdata-3.9.0}/mapdata/symbols/16x16/lightning.xbm +0 -0
  112. {mapdata-3.8.0 → mapdata-3.9.0}/mapdata/symbols/16x16/lightning2.xbm +0 -0
  113. {mapdata-3.8.0 → mapdata-3.9.0}/mapdata/symbols/16x16/location_ptr.xbm +0 -0
  114. {mapdata-3.8.0 → mapdata-3.9.0}/mapdata/symbols/16x16/mine.xbm +0 -0
  115. {mapdata-3.8.0 → mapdata-3.9.0}/mapdata/symbols/16x16/nested_boxes.xbm +0 -0
  116. {mapdata-3.8.0 → mapdata-3.9.0}/mapdata/symbols/16x16/pennant.xbm +0 -0
  117. {mapdata-3.8.0 → mapdata-3.9.0}/mapdata/symbols/16x16/pennant2.xbm +0 -0
  118. {mapdata-3.8.0 → mapdata-3.9.0}/mapdata/symbols/16x16/people.xbm +0 -0
  119. {mapdata-3.8.0 → mapdata-3.9.0}/mapdata/symbols/16x16/person.xbm +0 -0
  120. {mapdata-3.8.0 → mapdata-3.9.0}/mapdata/symbols/16x16/person2.xbm +0 -0
  121. {mapdata-3.8.0 → mapdata-3.9.0}/mapdata/symbols/16x16/person3.xbm +0 -0
  122. {mapdata-3.8.0 → mapdata-3.9.0}/mapdata/symbols/16x16/phone.xbm +0 -0
  123. {mapdata-3.8.0 → mapdata-3.9.0}/mapdata/symbols/16x16/photo.xbm +0 -0
  124. {mapdata-3.8.0 → mapdata-3.9.0}/mapdata/symbols/16x16/picnic.xbm +0 -0
  125. {mapdata-3.8.0 → mapdata-3.9.0}/mapdata/symbols/16x16/plus.xbm +0 -0
  126. {mapdata-3.8.0 → mapdata-3.9.0}/mapdata/symbols/16x16/point_down.xbm +0 -0
  127. {mapdata-3.8.0 → mapdata-3.9.0}/mapdata/symbols/16x16/point_left.xbm +0 -0
  128. {mapdata-3.8.0 → mapdata-3.9.0}/mapdata/symbols/16x16/point_right.xbm +0 -0
  129. {mapdata-3.8.0 → mapdata-3.9.0}/mapdata/symbols/16x16/point_up.xbm +0 -0
  130. {mapdata-3.8.0 → mapdata-3.9.0}/mapdata/symbols/16x16/pointer_ne.xbm +0 -0
  131. {mapdata-3.8.0 → mapdata-3.9.0}/mapdata/symbols/16x16/pointer_nw.xbm +0 -0
  132. {mapdata-3.8.0 → mapdata-3.9.0}/mapdata/symbols/16x16/pointer_se.xbm +0 -0
  133. {mapdata-3.8.0 → mapdata-3.9.0}/mapdata/symbols/16x16/pointer_sw.xbm +0 -0
  134. {mapdata-3.8.0 → mapdata-3.9.0}/mapdata/symbols/16x16/puzzle.xbm +0 -0
  135. {mapdata-3.8.0 → mapdata-3.9.0}/mapdata/symbols/16x16/q1.xbm +0 -0
  136. {mapdata-3.8.0 → mapdata-3.9.0}/mapdata/symbols/16x16/q1_notch.xbm +0 -0
  137. {mapdata-3.8.0 → mapdata-3.9.0}/mapdata/symbols/16x16/q2.xbm +0 -0
  138. {mapdata-3.8.0 → mapdata-3.9.0}/mapdata/symbols/16x16/q2_notch.xbm +0 -0
  139. {mapdata-3.8.0 → mapdata-3.9.0}/mapdata/symbols/16x16/q3.xbm +0 -0
  140. {mapdata-3.8.0 → mapdata-3.9.0}/mapdata/symbols/16x16/q3_notch.xbm +0 -0
  141. {mapdata-3.8.0 → mapdata-3.9.0}/mapdata/symbols/16x16/q4.xbm +0 -0
  142. {mapdata-3.8.0 → mapdata-3.9.0}/mapdata/symbols/16x16/q4_notch.xbm +0 -0
  143. {mapdata-3.8.0 → mapdata-3.9.0}/mapdata/symbols/16x16/qmark_circle.xbm +0 -0
  144. {mapdata-3.8.0 → mapdata-3.9.0}/mapdata/symbols/16x16/qmark_circle2.xbm +0 -0
  145. {mapdata-3.8.0 → mapdata-3.9.0}/mapdata/symbols/16x16/raincloud.xbm +0 -0
  146. {mapdata-3.8.0 → mapdata-3.9.0}/mapdata/symbols/16x16/right.xbm +0 -0
  147. {mapdata-3.8.0 → mapdata-3.9.0}/mapdata/symbols/16x16/rocket.xbm +0 -0
  148. {mapdata-3.8.0 → mapdata-3.9.0}/mapdata/symbols/16x16/rocket2.xbm +0 -0
  149. {mapdata-3.8.0 → mapdata-3.9.0}/mapdata/symbols/16x16/rose.xbm +0 -0
  150. {mapdata-3.8.0 → mapdata-3.9.0}/mapdata/symbols/16x16/rows.xbm +0 -0
  151. {mapdata-3.8.0 → mapdata-3.9.0}/mapdata/symbols/16x16/scales.xbm +0 -0
  152. {mapdata-3.8.0 → mapdata-3.9.0}/mapdata/symbols/16x16/search.xbm +0 -0
  153. {mapdata-3.8.0 → mapdata-3.9.0}/mapdata/symbols/16x16/search2.xbm +0 -0
  154. {mapdata-3.8.0 → mapdata-3.9.0}/mapdata/symbols/16x16/skull.xbm +0 -0
  155. {mapdata-3.8.0 → mapdata-3.9.0}/mapdata/symbols/16x16/square.xbm +0 -0
  156. {mapdata-3.8.0 → mapdata-3.9.0}/mapdata/symbols/16x16/star.xbm +0 -0
  157. {mapdata-3.8.0 → mapdata-3.9.0}/mapdata/symbols/16x16/stipple.xbm +0 -0
  158. {mapdata-3.8.0 → mapdata-3.9.0}/mapdata/symbols/16x16/stop.xbm +0 -0
  159. {mapdata-3.8.0 → mapdata-3.9.0}/mapdata/symbols/16x16/surprise_circle.xbm +0 -0
  160. {mapdata-3.8.0 → mapdata-3.9.0}/mapdata/symbols/16x16/swamp.xbm +0 -0
  161. {mapdata-3.8.0 → mapdata-3.9.0}/mapdata/symbols/16x16/target.xbm +0 -0
  162. {mapdata-3.8.0 → mapdata-3.9.0}/mapdata/symbols/16x16/target2.xbm +0 -0
  163. {mapdata-3.8.0 → mapdata-3.9.0}/mapdata/symbols/16x16/ten.xbm +0 -0
  164. {mapdata-3.8.0 → mapdata-3.9.0}/mapdata/symbols/16x16/trash.xbm +0 -0
  165. {mapdata-3.8.0 → mapdata-3.9.0}/mapdata/symbols/16x16/tree.xbm +0 -0
  166. {mapdata-3.8.0 → mapdata-3.9.0}/mapdata/symbols/16x16/tree2.xbm +0 -0
  167. {mapdata-3.8.0 → mapdata-3.9.0}/mapdata/symbols/16x16/tree3.xbm +0 -0
  168. {mapdata-3.8.0 → mapdata-3.9.0}/mapdata/symbols/16x16/triangle.xbm +0 -0
  169. {mapdata-3.8.0 → mapdata-3.9.0}/mapdata/symbols/16x16/triangle_open.xbm +0 -0
  170. {mapdata-3.8.0 → mapdata-3.9.0}/mapdata/symbols/16x16/triangle_sm.xbm +0 -0
  171. {mapdata-3.8.0 → mapdata-3.9.0}/mapdata/symbols/16x16/up.xbm +0 -0
  172. {mapdata-3.8.0 → mapdata-3.9.0}/mapdata/symbols/16x16/vapor.xbm +0 -0
  173. {mapdata-3.8.0 → mapdata-3.9.0}/mapdata/symbols/16x16/warning.xbm +0 -0
  174. {mapdata-3.8.0 → mapdata-3.9.0}/mapdata/symbols/16x16/wave.xbm +0 -0
  175. {mapdata-3.8.0 → mapdata-3.9.0}/mapdata/symbols/16x16/wave2.xbm +0 -0
  176. {mapdata-3.8.0 → mapdata-3.9.0}/mapdata/symbols/16x16/wave3.xbm +0 -0
  177. {mapdata-3.8.0 → mapdata-3.9.0}/mapdata/symbols/16x16/weather.xbm +0 -0
  178. {mapdata-3.8.0 → mapdata-3.9.0}/mapdata/symbols/16x16/wedge.xbm +0 -0
  179. {mapdata-3.8.0 → mapdata-3.9.0}/mapdata/symbols/16x16/wedge_sm.xbm +0 -0
  180. {mapdata-3.8.0 → mapdata-3.9.0}/mapdata/symbols/16x16/wedges_3.xbm +0 -0
  181. {mapdata-3.8.0 → mapdata-3.9.0}/mapdata/symbols/16x16/well.xbm +0 -0
  182. {mapdata-3.8.0 → mapdata-3.9.0}/mapdata/symbols/16x16/whale.xbm +0 -0
  183. {mapdata-3.8.0 → mapdata-3.9.0}/mapdata/symbols/16x16/whale2.xbm +0 -0
  184. {mapdata-3.8.0 → mapdata-3.9.0}/mapdata/symbols/16x16/wheelchair.xbm +0 -0
  185. {mapdata-3.8.0 → mapdata-3.9.0}/mapdata/symbols/16x16/zigzags.xbm +0 -0
  186. {mapdata-3.8.0 → mapdata-3.9.0}/mapdata/symbols/16x16/zigzags2.xbm +0 -0
  187. {mapdata-3.8.0 → mapdata-3.9.0}/mapdata/symbols/20x20/ball20.xbm +0 -0
  188. {mapdata-3.8.0 → mapdata-3.9.0}/mapdata/symbols/20x20/block20.xbm +0 -0
  189. {mapdata-3.8.0 → mapdata-3.9.0}/mapdata/symbols/20x20/circle20.xbm +0 -0
  190. {mapdata-3.8.0 → mapdata-3.9.0}/mapdata/symbols/20x20/q1_20.xbm +0 -0
  191. {mapdata-3.8.0 → mapdata-3.9.0}/mapdata/symbols/20x20/q2_20.xbm +0 -0
  192. {mapdata-3.8.0 → mapdata-3.9.0}/mapdata/symbols/20x20/q3_20.xbm +0 -0
  193. {mapdata-3.8.0 → mapdata-3.9.0}/mapdata/symbols/20x20/q4_20.xbm +0 -0
  194. {mapdata-3.8.0 → mapdata-3.9.0}/mapdata/symbols/20x20/square20.xbm +0 -0
  195. {mapdata-3.8.0 → mapdata-3.9.0}/mapdata/symbols/24x24/ball24.xbm +0 -0
  196. {mapdata-3.8.0 → mapdata-3.9.0}/mapdata/symbols/24x24/block24.xbm +0 -0
  197. {mapdata-3.8.0 → mapdata-3.9.0}/mapdata/symbols/24x24/circle24.xbm +0 -0
  198. {mapdata-3.8.0 → mapdata-3.9.0}/mapdata/symbols/24x24/square24.xbm +0 -0
  199. {mapdata-3.8.0 → mapdata-3.9.0}/mapdata/symbols/28x28/ball28.xbm +0 -0
  200. {mapdata-3.8.0 → mapdata-3.9.0}/mapdata/symbols/28x28/block28.xbm +0 -0
  201. {mapdata-3.8.0 → mapdata-3.9.0}/mapdata/symbols/28x28/circle28.xbm +0 -0
  202. {mapdata-3.8.0 → mapdata-3.9.0}/mapdata/symbols/28x28/square28.xbm +0 -0
  203. {mapdata-3.8.0 → mapdata-3.9.0}/mapdata.egg-info/SOURCES.txt +0 -0
  204. {mapdata-3.8.0 → mapdata-3.9.0}/mapdata.egg-info/dependency_links.txt +0 -0
  205. {mapdata-3.8.0 → mapdata-3.9.0}/mapdata.egg-info/requires.txt +0 -0
  206. {mapdata-3.8.0 → mapdata-3.9.0}/mapdata.egg-info/top_level.txt +0 -0
  207. {mapdata-3.8.0 → mapdata-3.9.0}/setup.cfg +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: mapdata
3
- Version: 3.8.0
3
+ Version: 3.9.0
4
4
  Summary: An interactive map and table explorer for geographic coordinates in a spreadsheet, CSV file, or database
5
5
  Home-page: https://osdn.net/project/mapdata/
6
6
  Author: Dreas Nielsen
@@ -78,21 +78,28 @@ Selected rows in the data table can be exported to a CSV or spreadsheet file.
78
78
  *Mapdata* provides five different ways to show information about multiple data rows that all have the same geographic coordinates, and thus plot at the same location on the map.
79
79
 
80
80
  Data can also be displayed in several different types of plots: box plots, scatter
81
- plots, line charts, ECDF plots, Q-Q plots, Fisher-Jenks group plots, strip charts,
82
- and counts of categorical and quantitative variables. Plots
81
+ plots, line charts, kernel density plots, ECDF plots, Q-Q plots, strip charts,
82
+ counts of categorical and quantitative variables, and others. Plots
83
83
  can use either all data or only data values that are selected in the map and
84
84
  table. Plots have a live connection to the data table and map, so when data selections are changed the plots are automatically updated.
85
85
 
86
86
  ![example plot](https://mapdata.readthedocs.io/en/latest/_images/UI_cat_stripchart.png)
87
87
 
88
- *Mapdata* can also display summaries of univariate and bivariate statistics for selected variables. These summaries can use either all data in the data table or only the data that are highlighted on the map. These summaries are updated immediately if different data are selected.
88
+ *Mapdata* can also carry out some univariate, bivariate, and multivariate statistical
89
+ summarizations and analyses. Statistical analyses can use either all data in the data table
90
+ or only the data that are highlighted on the map. These summaries are updated immediately
91
+ if different data are selected.
89
92
 
90
93
  ![Bivariate statistics](https://mapdata.readthedocs.io/en/latest/_images/Bivariate_dialog.png)
91
94
 
92
- In addition to univariate and bivariate statistics, and plots, *mapdata* can display the relationships between variables in the form of:
95
+ Statistical summaries and analyses include:
96
+
97
+ * Bivariate ordinary least squares regression and trend evaluation.
93
98
 
94
99
  * A correlation matrix.
95
100
 
101
+ * Parametric and nonparametric analysis of variance (ANOVA).
102
+
96
103
  * A contingency table, using either categorical or numeric variables, with flexible
97
104
  specification of groups. Tests of independence, risk ratio, odds ratio and related
98
105
  statistics, and conditional probabilities are all shown.
@@ -36,21 +36,28 @@ Selected rows in the data table can be exported to a CSV or spreadsheet file.
36
36
  *Mapdata* provides five different ways to show information about multiple data rows that all have the same geographic coordinates, and thus plot at the same location on the map.
37
37
 
38
38
  Data can also be displayed in several different types of plots: box plots, scatter
39
- plots, line charts, ECDF plots, Q-Q plots, Fisher-Jenks group plots, strip charts,
40
- and counts of categorical and quantitative variables. Plots
39
+ plots, line charts, kernel density plots, ECDF plots, Q-Q plots, strip charts,
40
+ counts of categorical and quantitative variables, and others. Plots
41
41
  can use either all data or only data values that are selected in the map and
42
42
  table. Plots have a live connection to the data table and map, so when data selections are changed the plots are automatically updated.
43
43
 
44
44
  ![example plot](https://mapdata.readthedocs.io/en/latest/_images/UI_cat_stripchart.png)
45
45
 
46
- *Mapdata* can also display summaries of univariate and bivariate statistics for selected variables. These summaries can use either all data in the data table or only the data that are highlighted on the map. These summaries are updated immediately if different data are selected.
46
+ *Mapdata* can also carry out some univariate, bivariate, and multivariate statistical
47
+ summarizations and analyses. Statistical analyses can use either all data in the data table
48
+ or only the data that are highlighted on the map. These summaries are updated immediately
49
+ if different data are selected.
47
50
 
48
51
  ![Bivariate statistics](https://mapdata.readthedocs.io/en/latest/_images/Bivariate_dialog.png)
49
52
 
50
- In addition to univariate and bivariate statistics, and plots, *mapdata* can display the relationships between variables in the form of:
53
+ Statistical summaries and analyses include:
54
+
55
+ * Bivariate ordinary least squares regression and trend evaluation.
51
56
 
52
57
  * A correlation matrix.
53
58
 
59
+ * Parametric and nonparametric analysis of variance (ANOVA).
60
+
54
61
  * A contingency table, using either categorical or numeric variables, with flexible
55
62
  specification of groups. Tests of independence, risk ratio, odds ratio and related
56
63
  statistics, and conditional probabilities are all shown.
@@ -24,8 +24,8 @@
24
24
  #
25
25
  # ==================================================================
26
26
 
27
- version = "3.8.0"
28
- vdate = "2024-06-02"
27
+ version = "3.9.0"
28
+ vdate = "2024-06-13"
29
29
 
30
30
  copyright = "2023-2024"
31
31
 
@@ -86,7 +86,7 @@ import scipy.stats as spstats
86
86
  import scipy.sparse as sparse
87
87
  import statsmodels.api as sm
88
88
  from statsmodels.sandbox.stats.runs import runstest_1samp
89
- from statsmodels.stats.diagnostic import normal_ad, kstest_normal
89
+ from statsmodels.stats.diagnostic import normal_ad, lilliefors, kstest_normal
90
90
  try:
91
91
  import pymannkendall as mk
92
92
  mk_available = True
@@ -1380,6 +1380,32 @@ def check_rowtable(rowtable, headers, parent, tablename=None):
1380
1380
  msg += f"Row {rowno+1} has {len(rowtable[rowno])} columns but should have {n_headers}.\nBad row: {rowtable[rowno]}"
1381
1381
  fatal_error(msg, kwargs={'parent': parent})
1382
1382
 
1383
+ def clean_missing(dataset, column_indexes):
1384
+ # Removes rows for a table as a list of columns if there is a missing value in any
1385
+ # of the columns specified by the indexes
1386
+ clean_data = [[] for _ in dataset]
1387
+ for i in range(len(dataset[0])):
1388
+ ok = True
1389
+ for col in column_indexes:
1390
+ if dataset[col][i] is None or dataset[col][i] == '':
1391
+ ok = False
1392
+ if ok:
1393
+ for col in column_indexes:
1394
+ clean_data[col].append(dataset[col][i])
1395
+ return clean_data
1396
+
1397
+
1398
+ def spread_by_groups(grouplist, valuelist):
1399
+ # Split 'valuelist' into several lists, one for each group in grouplist.
1400
+ # The lists must have the same length.
1401
+ # Returns a tuple of group names (as strings) and a list of lists. Missing values are eliminated.
1402
+ grpstrs = [str(g) for g in grouplist]
1403
+ grp_vals = sorted(list(set(grpstrs)))
1404
+ ds = list(zip(grpstrs, valuelist))
1405
+ dspread = []
1406
+ for g in grp_vals:
1407
+ dspread.append([d[1] for d in ds if d[0] == g and d[1] is not None])
1408
+ return grp_vals, dspread
1383
1409
 
1384
1410
  def subset_by_groups(dataset, grouplist):
1385
1411
  # Returns a dictionary with keys of unique elements of 'grouplist' and values
@@ -1975,6 +2001,8 @@ class MapUI(object):
1975
2001
  self.univar_list = []
1976
2002
  # List of BivarStatsDialog objects, so they can be updated.
1977
2003
  self.bivar_list = []
2004
+ # List of ANOVADialog objects, so they can be updated.
2005
+ self.anova_list = []
1978
2006
  # List of FitDistDialog objects, so they can be updated.
1979
2007
  self.fitdist_list = []
1980
2008
  # List of TSNEDialog objects, so they can be updated.
@@ -2110,7 +2138,7 @@ class MapUI(object):
2110
2138
  self.cancel()
2111
2139
  else:
2112
2140
  if args.lat is None or args.lon is None:
2113
- warning("Latitude and longitude columns must be specified on the command line with other data source arguments.", kwargs={'parent': self.win})
2141
+ warning("Latitude and longitude columns must be specified with other data source arguments.", kwargs={'parent': self.win})
2114
2142
  sdsd = SelDataSrcDialog(parent=self.win, mapui=self)
2115
2143
  src_name, label_col, lat_col, lon_col, crs, symbol_col, color_col, message, headers, rows = sdsd.select()
2116
2144
  if src_name is None:
@@ -2829,6 +2857,9 @@ class MapUI(object):
2829
2857
  for dlg in self.bivar_list:
2830
2858
  if unconditional or dlg.sel_only_var.get() == "1":
2831
2859
  dlg.q_recalc()
2860
+ for dlg in self.anova_list:
2861
+ if unconditional or dlg.sel_only_var.get() == "1":
2862
+ dlg.q_recalc()
2832
2863
  for dlg in self.fitdist_list:
2833
2864
  if unconditional or dlg.sel_only_var.get() == "1":
2834
2865
  dlg.q_recalc()
@@ -2967,9 +2998,14 @@ class MapUI(object):
2967
2998
  self.bivar_list.remove(bivar_dlg)
2968
2999
  except:
2969
3000
  pass
3001
+ def remove_anova(self, anova_dlg):
3002
+ try:
3003
+ self.anova_list.remove(anova_dlg)
3004
+ except:
3005
+ pass
2970
3006
  def remove_fitdist(self, fitdist_dlg):
2971
3007
  try:
2972
- self.fitdist_list.remove(bivar_dlg)
3008
+ self.fitdist_list.remove(fitdist_dlg)
2973
3009
  except:
2974
3010
  pass
2975
3011
  def remove_corrmat(self, corrmat_dlg):
@@ -3534,6 +3570,12 @@ class MapUI(object):
3534
3570
  self.bivar_list.append(dlg)
3535
3571
  dlg.show()
3536
3572
 
3573
+ def anova_stats():
3574
+ self.wait_for_data_types()
3575
+ dlg = ANOVADialog(self, self.data_types)
3576
+ self.anova_list.append(dlg)
3577
+ dlg.show()
3578
+
3537
3579
  def fitdist_stats():
3538
3580
  self.wait_for_data_types()
3539
3581
  dlg = FitDistDialog(self, self.data_types)
@@ -3660,6 +3702,7 @@ class MapUI(object):
3660
3702
  stats_menu.add_command(label="Fit univariate distribution", command = fitdist_stats, underline=0)
3661
3703
  stats_menu.add_command(label="Bivariate statistics", command = bivar_stats, underline=0)
3662
3704
  stats_menu.add_command(label="Correlation matrix", command = corr_matrix, underline=0)
3705
+ stats_menu.add_command(label="One-way ANOVA", command = anova_stats, underline=8)
3663
3706
  stats_menu.add_command(label="Contingency table", command = cont_table, underline=2)
3664
3707
  stats_menu.add_command(label="ROC curve", command = roc_curve, underline=0)
3665
3708
  stats_menu.add_command(label="t-SNE analysis", command = tsne_anal, underline=0)
@@ -5886,18 +5929,8 @@ class PlotDialog(object):
5886
5929
  self.plot_data = [x_vals, x_counts]
5887
5930
  self.plot_data_labels = [self.data_labels[0], "Count"]
5888
5931
  elif plot_type in ("Box plot", "Histogram", "Kernel density (KD) plot", "Stripchart", "Violin plot"):
5889
- # The groupby variable may or may not be set
5890
5932
  if self.groupby_var.get() != '':
5891
- # Ensure that all values of the labeling variable are strings
5892
- self.dataset[1] = [str(lbl) for lbl in self.dataset[1]]
5893
- grp_vals = list(set(self.dataset[1]))
5894
- grp_vals.sort()
5895
- ds = list(zip(self.dataset[1], self.dataset[0]))
5896
- plot_data = []
5897
- for g in grp_vals:
5898
- plot_data.append([d[1] for d in ds if d[0] == g])
5899
- self.plot_data = plot_data
5900
- self.plot_data_labels = grp_vals
5933
+ self.plot_data_labels, self.plot_data = spread_by_groups(self.dataset[1], self.dataset[0])
5901
5934
  else:
5902
5935
  self.plot_data = [self.dataset[0]]
5903
5936
  self.plot_data_labels = [self.data_labels[0]]
@@ -7295,10 +7328,10 @@ class UnivarStatsDialog(object):
7295
7328
  self.categ_columns.sort()
7296
7329
  self.dnames = ["Variable", " N ", "Min.", "Max.", "Mean", "Median", "Mode", \
7297
7330
  "Geo. mean", "Std.Dev.", "C.V.", "Sum", "5th %ile", "95th %ile", "Anderson-Darling p", \
7298
- "Lillefors p", "Rosner's outliers", "Tukey outliers"]
7331
+ "Lilliefors p", "Omnibus normality p", "Rosner's outliers", "Tukey outliers"]
7299
7332
  self.logdnames = ["Variable", " N ", "Min.", "Max.", "Mean", "Median", "Mode", \
7300
- "Std.Dev.", "C.V.", "Sum", "5th %ile", "95th %ile", "Anderson-Darling p", "Lillefors p", \
7301
- "Rosner's outliers", "Tukey outliers"]
7333
+ "Std.Dev.", "C.V.", "Sum", "5th %ile", "95th %ile", "Anderson-Darling p", "Lilliefors p", \
7334
+ "Omnibus normality p", "Rosner's outliers", "Tukey outliers"]
7302
7335
  self.statdata = []
7303
7336
  self.dlg.bind("<Control-s>")
7304
7337
  self.dlg.bind("<Control-z>")
@@ -7475,21 +7508,32 @@ class UnivarStatsDialog(object):
7475
7508
  da = np.array(d)
7476
7509
  normstats = []
7477
7510
  if stdev_d != 0.0:
7511
+ # Anderson-Darling
7478
7512
  try:
7479
7513
  adval, adpval = normal_ad(da)
7480
7514
  normstats.append("%.2E" % adpval)
7481
7515
  except:
7482
7516
  normstats.append("NC")
7517
+ # Lilliefors
7483
7518
  try:
7484
- lfval, lfpval = kstest_normal(da)
7519
+ lfval, lfpval = lilliefors(da)
7485
7520
  normstats.append("%.2E" % lfpval)
7486
7521
  except:
7487
7522
  normstats.append("NC")
7523
+ # Omnibus
7524
+ if len(da) > 19:
7525
+ try:
7526
+ stat, p = spstats.normaltest(da)
7527
+ normstats.append("%.2E" % p)
7528
+ except:
7529
+ normstats.append("NC")
7530
+ else:
7531
+ normstats.append("NC")
7488
7532
  else:
7489
- normstats = ["NC", "NC"]
7533
+ normstats = ["NC", "NC", "NC"]
7490
7534
  dd.extend(normstats)
7491
7535
  else:
7492
- dd.extend([None, None])
7536
+ dd.extend(["NC", "NC", "NC"])
7493
7537
  #=== Outlier evaluation
7494
7538
  if len(d) > 14:
7495
7539
  if stdev_d > 0.0:
@@ -7558,6 +7602,7 @@ class UnivarStatsDialog(object):
7558
7602
  self.logstatdata.append([grp, self.data_labels[var]] + logdd)
7559
7603
  dnames = ["Group"] + self.dnames
7560
7604
  logdnames = ["Group"] + self.logdnames
7605
+ breakpoint()
7561
7606
  tframe, tdata = treeview_table(self.data_page, self.statdata, dnames)
7562
7607
  tframe.grid(row=0, column=0, sticky=tk.NSEW)
7563
7608
  ltframe, ltdata = treeview_table(self.log_page, self.logstatdata, logdnames)
@@ -7721,6 +7766,17 @@ class BivarStatsDialog(object):
7721
7766
  self.residfig_canvas.get_tk_widget().pack(side=tk.TOP, fill=tk.BOTH, expand=1)
7722
7767
  #self.resid_nav.update()
7723
7768
  plot_pages.add(resid_frame, text="Residuals")
7769
+ # Şen 2012 trend plot
7770
+ sen_frame = tk.Frame(plot_pages)
7771
+ sen_frame.rowconfigure(0, weight=1)
7772
+ sen_frame.columnconfigure(0, weight=1)
7773
+ sen_frame.pack(side=tk.TOP, fill=tk.BOTH, expand=1)
7774
+ self.senfig = Figure(dpi=100)
7775
+ self.senfig.set_figheight(2)
7776
+ self.senfig.set_figwidth(2)
7777
+ self.senfig_canvas = FigureCanvasTkAgg(self.senfig, sen_frame)
7778
+ self.senfig_canvas.get_tk_widget().pack(side=tk.TOP, fill=tk.BOTH, expand=1)
7779
+ plot_pages.add(sen_frame, text="Şen trend")
7724
7780
 
7725
7781
  # Initialize output frames
7726
7782
  self.clear_output()
@@ -7842,6 +7898,9 @@ class BivarStatsDialog(object):
7842
7898
  self.residfig.clear()
7843
7899
  self.resid_axes = self.residfig.add_subplot(111)
7844
7900
  self.residfig_canvas.draw()
7901
+ self.senfig.clear()
7902
+ self.sen_axes = self.senfig.add_subplot(111)
7903
+ self.senfig_canvas.draw()
7845
7904
 
7846
7905
  def show_data(self, *args):
7847
7906
  if self.dataset is not None:
@@ -7995,6 +8054,24 @@ class BivarStatsDialog(object):
7995
8054
  self.plot_axes.scatter(self.dataset[0], self.dataset[1], alpha=self.alpha)
7996
8055
  self.plotfig_canvas.draw()
7997
8056
  self.residfig_canvas.draw()
8057
+ # Plot of Şen trend
8058
+ ylen = len(self.dataset[1])
8059
+ if ylen > 3:
8060
+ if ylen % 2:
8061
+ ysplit = int((ylen - 1)/2)
8062
+ firsthalf = self.dataset[1][1:][:ysplit]
8063
+ secondhalf = self.dataset[1][1:][ysplit:]
8064
+ else:
8065
+ ysplit = int(ylen/2)
8066
+ firsthalf = self.dataset[1][:ysplit]
8067
+ secondhalf = self.dataset[1][ysplit:]
8068
+ self.sen_axes.scatter(firsthalf, secondhalf)
8069
+ mid = statistics.median(self.dataset[1])
8070
+ self.sen_axes.axline((mid,mid), slope=1, color="grey", alpha=0.65)
8071
+ self.sen_axes.set_xlabel("First half of "+self.data_labels[1])
8072
+ self.sen_axes.set_ylabel("Second half of "+self.data_labels[1])
8073
+ self.senfig_canvas.draw()
8074
+ #
7998
8075
  self.plot_nav.update()
7999
8076
  self.dlg.bind("<Alt-a>", self.set_alpha)
8000
8077
  self.dlg.bind("<Alt-t>", self.set_title)
@@ -8289,6 +8366,296 @@ class CorrMatrixDialog(object):
8289
8366
  pass
8290
8367
 
8291
8368
 
8369
+ class ANOVADialog(object):
8370
+ def __init__(self, parent, column_specs):
8371
+ self.parent = parent
8372
+ self.column_specs = column_specs
8373
+ self.alpha = 0.45
8374
+ self.theilsen = False
8375
+ self.plot_title = None
8376
+ self.dlg = tk.Toplevel()
8377
+ self.dlg.title("Analysis of Variance (ANOVA)")
8378
+ self.dlg.columnconfigure(0, weight=1)
8379
+ # Data
8380
+ self.dataset = None
8381
+ self.data_labels = None
8382
+ self.group_data = None
8383
+ self.group_labels = None
8384
+ self.numeric_columns = sorted([c[0] for c in self.column_specs if c[1] in ("int", "float")])
8385
+ self.categ_columns = sorted([c[0] for c in self.column_specs if c[1] == "string"])
8386
+ self.output_colhdrs = ["Test", "Statistic", "Value", "p value"]
8387
+ self.dist_colhdrs = ["Group", "N", "Mean", "Median", "Variance", "Skewness", "Kurtosis", "Anderson-Darling p", "Lilliefors p", "Omnibus normality p"]
8388
+ self.statdata = []
8389
+ # Message
8390
+ prompt_frame = tk.Frame(self.dlg, borderwidth=5)
8391
+ prompt_frame.grid(row=0, column=0, sticky=tk.N+tk.EW, pady=(3,3))
8392
+ prompt_frame.columnconfigure(0, weight=1)
8393
+ msg_lbl = ttk.Label(prompt_frame, width=70, text="Select numeric and grouping variables")
8394
+ msg_lbl.grid(row=0, column=0, sticky=tk.W, padx=(6,6), pady=(3,3))
8395
+ def wrap_msg(event):
8396
+ msg_lbl.configure(wraplength=event.width - 5)
8397
+ msg_lbl.bind("<Configure>", wrap_msg)
8398
+
8399
+ # Controls
8400
+ ctrl_frame = tk.Frame(self.dlg, borderwidth=5)
8401
+ ctrl_frame.grid(row=1, column=0, sticky=tk.N+tk.EW)
8402
+
8403
+ self.x_var = tk.StringVar(ctrl_frame, "")
8404
+ x_lbl = ttk.Label(ctrl_frame, text="X column:")
8405
+ x_lbl.grid(row=0, column=0, sticky=tk.E, padx=(6,3), pady=(3,3))
8406
+ self.x_sel = ttk.Combobox(ctrl_frame, state=tk.NORMAL, textvariable=self.x_var, values=self.numeric_columns, width=24)
8407
+ self.x_sel.grid(row=0, column=1, sticky=tk.W, padx=(3,6), pady=(3,3))
8408
+ self.x_sel.bind("<<ComboboxSelected>>", self.q_recalc)
8409
+
8410
+ self.xlog_var = tk.StringVar(ctrl_frame, "0")
8411
+ self.xlog_ck = ttk.Checkbutton(ctrl_frame, text="Log X", state=tk.NORMAL, command=self.q_recalc, variable=self.xlog_var,
8412
+ onvalue="1", offvalue="0")
8413
+ self.xlog_ck.grid(row=0, column=2, sticky=tk.W, padx=(6,6), pady=(3,3))
8414
+
8415
+ self.groupby_var = tk.StringVar(ctrl_frame, "")
8416
+ groupby_lbl = ttk.Label(ctrl_frame, text="Group by:")
8417
+ groupby_lbl.grid(row=1, column=0, sticky=tk.E, padx=(6,3), pady=(3,3))
8418
+ self.groupby_sel = ttk.Combobox(ctrl_frame, state=tk.NORMAL, textvariable=self.groupby_var, values=self.categ_columns, width=24)
8419
+ self.groupby_sel.grid(row=1, column=1, sticky=tk.W, padx=(3,6), pady=(3,3))
8420
+ self.groupby_sel.bind("<<ComboboxSelected>>", self.q_recalc)
8421
+
8422
+ self.sel_only_var = tk.StringVar(ctrl_frame, "0")
8423
+ self.sel_only_ck = ttk.Checkbutton(ctrl_frame, text="Selected data only", command=self.q_recalc, variable=self.sel_only_var,
8424
+ onvalue="1", offvalue="0")
8425
+ self.sel_only_ck.grid(row=2, column=0, columnspan=2, sticky=tk.W, padx=(6,3), pady=(3,3))
8426
+
8427
+ # Frames for output tables
8428
+ self.content_frame = tk.Frame(self.dlg)
8429
+ self.content_frame.grid(row=2, column=0, sticky=tk.NSEW)
8430
+ self.dlg.rowconfigure(2, weight=1)
8431
+ self.dlg.columnconfigure(0, weight=1)
8432
+ self.content_frame.rowconfigure(0, weight=1)
8433
+ self.content_frame.columnconfigure(0, weight=1)
8434
+ # with tabbed Notebook for two different tables
8435
+ table_pages = ttk.Notebook(self.content_frame)
8436
+ table_pages.grid(row=0, column=0, sticky=tk.NSEW)
8437
+ table_pages.rowconfigure(0, weight=1)
8438
+ table_pages.columnconfigure(0, weight=1)
8439
+ # Frame for ANOVA statistics
8440
+ self.stat_frame = tk.Frame(table_pages)
8441
+ self.stat_frame.rowconfigure(0, weight=1)
8442
+ self.stat_frame.columnconfigure(0, weight=1)
8443
+ table_pages.add(self.stat_frame, text="ANOVA")
8444
+ # Frame for subgroup distribution statistics
8445
+ self.dist_frame = tk.Frame(table_pages)
8446
+ self.dist_frame.rowconfigure(0, weight=1)
8447
+ self.dist_frame.columnconfigure(0, weight=1)
8448
+ table_pages.add(self.dist_frame, text="Distributions")
8449
+
8450
+ # Initialize output frames
8451
+ self.clear_output()
8452
+
8453
+ # Buttons
8454
+ btn_frame = tk.Frame(self.dlg, borderwidth=3, relief=tk.RIDGE)
8455
+ btn_frame.columnconfigure(0, weight=1)
8456
+ btn_frame.grid(row=3, column=0, sticky=tk.EW, pady=(3,3))
8457
+ btn_frame.columnconfigure(0, weight=0)
8458
+ btn_frame.columnconfigure(1, weight=0)
8459
+ btn_frame.columnconfigure(2, weight=1)
8460
+ self.canceled = False
8461
+ self.help_btn = ttk.Button(btn_frame, text="Help", command=self.do_help, underline=0)
8462
+ self.help_btn.grid(row=0, column=0, sticky=tk.W, padx=(6,3))
8463
+ self.dlg.bind("<Alt-h>", self.do_help)
8464
+ self.data_btn = ttk.Button(btn_frame, text="Source Data", state=tk.DISABLED, command=self.show_data, underline=0)
8465
+ self.data_btn.grid(row=0, column=1, sticky=tk.W, padx=(3,3))
8466
+ self.group_btn = ttk.Button(btn_frame, text="Group Data", state=tk.DISABLED, command=self.show_group_data, underline=0)
8467
+ self.group_btn.grid(row=0, column=2, sticky=tk.W, padx=(3,3))
8468
+ close_btn = ttk.Button(btn_frame, text="Close", command=self.do_close, underline=0)
8469
+ close_btn.grid(row=0, column=3, sticky=tk.E, padx=(6,6))
8470
+ self.dlg.bind("<Alt-c>", self.do_close)
8471
+ self.dlg.bind("<Escape>", self.do_close)
8472
+ center_window(self.dlg)
8473
+ raise_window(self.dlg)
8474
+
8475
+ def do_help(self, *args):
8476
+ webbrowser.open("https://mapdata.readthedocs.io/en/latest/dialogs.html#anova-dialog", new=2, autoraise=True)
8477
+
8478
+ def get_data(self):
8479
+ self.data_btn["state"] = tk.DISABLED
8480
+ self.dataset = None
8481
+ self.data_labels = None
8482
+ self.group_data = None
8483
+ self.group_labels = None
8484
+ self.dlg.bind("<Alt-s>")
8485
+ self.dlg.bind("<Alt-g>")
8486
+ column_list = [self.x_var.get(), self.groupby_var.get()]
8487
+ # Get either only the selected data or all data.
8488
+ if self.sel_only_var.get() == "1":
8489
+ dataset = self.parent.get_sel_data(column_list)
8490
+ else:
8491
+ dataset = self.parent.get_all_data(column_list)
8492
+ if dataset is None or len(dataset[0]) == 0:
8493
+ self.data_btn["state"] = tk.DISABLED
8494
+ self.group_btn["state"] = tk.DISABLED
8495
+ else:
8496
+ # Drop missing data
8497
+ dataset = clean_missing(dataset, [0,1])
8498
+ # Convert nominally numeric values to floats
8499
+ float_vals = [conv_float(v) for v in dataset[0]]
8500
+ # Log-transform data if specified.
8501
+ if self.xlog_ck["state"] != tk.DISABLED and self.xlog_var.get() == "1":
8502
+ log_error = False
8503
+ log_data = []
8504
+ for i in range(len(float_vals)):
8505
+ try:
8506
+ log_data.append(math.log10(float_vals[i]))
8507
+ except:
8508
+ log_error = True
8509
+ self.xlog_var.set("0")
8510
+ self.xlog_ck["state"] = tk.DISABLED
8511
+ break
8512
+ if log_error:
8513
+ warning("Data cannot be log-transformed", {'parent':self.dlg})
8514
+ else:
8515
+ float_vals = log_data
8516
+ self.group_labels, self.group_data = spread_by_groups(dataset[1], float_vals)
8517
+ self.group_btn["state"] = tk.NORMAL
8518
+ self.dataset = [float_vals, dataset[1]]
8519
+ if self.xlog_ck["state"] != tk.DISABLED and self.xlog_var.get() == "1":
8520
+ self.data_labels = ["Log10 of %s" % column_list[0]]
8521
+ else:
8522
+ self.data_labels = [column_list[0]]
8523
+ self.data_labels.append(column_list[1])
8524
+ self.data_btn["state"] = tk.NORMAL
8525
+ self.dlg.bind("<Alt-s>", self.show_data)
8526
+ self.dlg.bind("<Alt-g>", self.show_group_data)
8527
+
8528
+ def clear_output(self):
8529
+ for ctl in self.stat_frame.winfo_children():
8530
+ ctl.destroy()
8531
+ for ctl in self.dist_frame.winfo_children():
8532
+ ctl.destroy()
8533
+ self.dlg.bind("<Control-s>")
8534
+ self.dlg.bind("<Control-z>")
8535
+ tframe, tdata = treeview_table(self.stat_frame, [], self.output_colhdrs)
8536
+ tframe.grid(row=0, column=0, sticky=tk.NSEW)
8537
+ tframe, tdata = treeview_table(self.dist_frame, [], self.dist_colhdrs)
8538
+ tframe.grid(row=0, column=0, sticky=tk.NSEW)
8539
+ self.dlg.bind("<Alt-s>")
8540
+ self.dlg.bind("<Alt-g>")
8541
+
8542
+ def show_data(self, *args):
8543
+ if self.dataset is not None:
8544
+ show_columnar_table(self.dlg, "Source Data", "Selected data:", self.dataset, self.data_labels[0:len(self.dataset)], \
8545
+ "Source Data for ANOVA")
8546
+
8547
+ def show_group_data(self, *args):
8548
+ if self.group_data is not None:
8549
+ show_columnar_table(self.dlg, "Grouped Data", "Data for each group:", self.group_data, self.group_labels, "Data for ANOVA")
8550
+
8551
+ def q_recalc(self, get_data=True, *args):
8552
+ if self.x_var.get() != '' and self.groupby_var.get() != '':
8553
+ if get_data or self.dataset is None:
8554
+ self.get_data()
8555
+ if self.group_data is not None and len(self.group_data) > 1 and max([len(d) for d in self.group_data]) > 1:
8556
+ self.recalc()
8557
+ else:
8558
+ self.clear_output()
8559
+
8560
+ def recalc(self):
8561
+ self.clear_output()
8562
+ self.statdata = []
8563
+ self.distdata = []
8564
+ if self.group_data is not None:
8565
+ group_lengths = [len(g) for g in self.group_data]
8566
+ # One-way ANOVA
8567
+ F, p = spstats.f_oneway(*self.group_data)
8568
+ self.statdata.append(["One-way ANOVA", "F", fp_display(F), fp_display(p)])
8569
+ # Kruskal-Wallace test
8570
+ H, p = spstats.kruskal(*self.group_data)
8571
+ self.statdata.append(["Kruskal-Wallis", "H", fp_display(H), fp_display(p)])
8572
+ # Alexander-Govern test
8573
+ if min(group_lengths) > 1:
8574
+ ag = spstats.alexandergovern(*self.group_data)
8575
+ A = ag.statistic
8576
+ p = ag.pvalue
8577
+ self.statdata.append(["Alexander-Govern", "A", fp_display(A), fp_display(p)])
8578
+ # Levene's test
8579
+ W, p = spstats.levene(*self.group_data, center="mean")
8580
+ self.statdata.append(["Levene", "W", fp_display(W), fp_display(p)])
8581
+ # Brown-Forsythe test
8582
+ F, p = spstats.levene(*self.group_data, center="median")
8583
+ self.statdata.append(["Brown-Forsythe", "F", fp_display(F), fp_display(p)])
8584
+ # Bartlett's test
8585
+ try:
8586
+ X2, p = spstats.bartlett(*self.group_data)
8587
+ except:
8588
+ pass
8589
+ else:
8590
+ if not math.isnan(X2) and not math.isnan(p):
8591
+ self.statdata.append(["Bartlett", "X2", fp_display(X2), fp_display(p)])
8592
+ # Distribution statistics for each group
8593
+ for i in range(len(self.group_labels)):
8594
+ # Group, N, Mean, Median, Variance, Skewness, Kurtosis, Normality p]
8595
+ lbl = self.group_labels[i]
8596
+ d = self.group_data[i]
8597
+ dd = [lbl, group_lengths[i], fp_display(statistics.fmean(d))]
8598
+ dd.append(fp_display(statistics.median(d)))
8599
+ var = None
8600
+ if group_lengths[i] > 1:
8601
+ try:
8602
+ var = statistics.variance(d)
8603
+ dd.append(fp_display(var))
8604
+ except:
8605
+ dd.append("NC")
8606
+ else:
8607
+ dd.append("NC")
8608
+ dd.extend([fp_display(spstats.skew(d)), fp_display(spstats.kurtosis(d))])
8609
+ # Normality tests
8610
+ if var is not None:
8611
+ try:
8612
+ adval, adpval = normal_ad(da)
8613
+ dd.append("%.2E" % adpval)
8614
+ except:
8615
+ dd.append("NC")
8616
+ try:
8617
+ lfval, lfpval = lilliefors(da, dist='norm')
8618
+ dd.append("%.2E" % lfpval)
8619
+ except:
8620
+ dd.append("NC")
8621
+ if len(self.group_data[i]) > 19:
8622
+ try:
8623
+ stat, p = spstats.normaltest(d)
8624
+ except:
8625
+ dd.append("NC")
8626
+ else:
8627
+ dd.append("%.2E" % p)
8628
+ else:
8629
+ dd.append("NC")
8630
+ else:
8631
+ dd.extend(["NC", "NC", "NC"])
8632
+
8633
+ self.distdata.append(dd)
8634
+ if len(self.statdata) > 0:
8635
+ tframe, tdata = treeview_table(self.stat_frame, self.statdata, self.output_colhdrs)
8636
+ tframe.grid(row=0, column=0, stick=tk.NSEW)
8637
+ tframe, tdata = treeview_table(self.dist_frame, self.distdata, self.dist_colhdrs)
8638
+ tframe.grid(row=0, column=0, stick=tk.NSEW)
8639
+ self.dlg.bind("<Control-s>", self.save_table)
8640
+ self.dlg.minsize(width=700, height=400)
8641
+ self.dlg.bind("<Control-s>", self.save_table)
8642
+ self.dlg.bind("<Control-z>", self.save_norm_table)
8643
+
8644
+ def save_table(self, *args):
8645
+ export_data_table(self.output_colhdrs, self.statdata, sheetname="ANOVA statistsics")
8646
+ def save_norm_table(self, *args):
8647
+ export_data_table(self.dist_colhdrs, self.distdata, sheetname="Normality statistsics")
8648
+ def show(self):
8649
+ self.dlg.wait_window(self.dlg)
8650
+ def do_close(self, *args):
8651
+ self.parent.remove_anova(self)
8652
+ try:
8653
+ self.dlg.destroy()
8654
+ except:
8655
+ pass
8656
+
8657
+
8658
+
8292
8659
  class TSNEDialog(object):
8293
8660
  def __init__(self, parent, column_specs, prohibited_columns):
8294
8661
  self.parent = parent
@@ -16366,8 +16733,8 @@ def read_all_config(argobj):
16366
16733
 
16367
16734
  # Update 'argobj'
16368
16735
  for att in ("db_type", "server", "port", "database", "user", "table", "script", \
16369
- "lon", "lat", "id", "projection", "message", "file", "sheet", "imagefile", \
16370
- "imagewait"):
16736
+ "lon", "lat", "id", "projection", "message", "file", "sheet", "symbol", \
16737
+ "color", "message", "imagefile", "imagewait"):
16371
16738
  if hasattr(cl_arg_defaults, att) and getattr(argobj, att) is None:
16372
16739
  setattr(argobj, att, getattr(cl_arg_defaults, att))
16373
16740
 
@@ -16696,7 +17063,7 @@ def clparser():
16696
17063
  help="The name of the column in the data file containing location identifiers or labels.")
16697
17064
  parser.add_argument("-k", "--db_type", type=str, choices=['p', 's', 'l', 'm', 'k', 'o', 'f'], dest="db_type", default=None,
16698
17065
  help="Database type: 'p'-PostgreSQL; 's'-SQL Server; 'l'-SQLite, 'm'-MySQL/MariaDB, 'k'-DuckDB, 'o'-Oracle, 'f'-Firebird.")
16699
- parser.add_argument('-m', '--message', dest='message', default='Map display',
17066
+ parser.add_argument('-m', '--message', dest='message',
16700
17067
  help='A message to display above the map.')
16701
17068
  parser.add_argument("-n", "--no_passwd", action="store_true", dest="no_passwd", default=False,
16702
17069
  help="Do not prompt for the password when the user is specified (default is to prompt).")
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: mapdata
3
- Version: 3.8.0
3
+ Version: 3.9.0
4
4
  Summary: An interactive map and table explorer for geographic coordinates in a spreadsheet, CSV file, or database
5
5
  Home-page: https://osdn.net/project/mapdata/
6
6
  Author: Dreas Nielsen
@@ -78,21 +78,28 @@ Selected rows in the data table can be exported to a CSV or spreadsheet file.
78
78
  *Mapdata* provides five different ways to show information about multiple data rows that all have the same geographic coordinates, and thus plot at the same location on the map.
79
79
 
80
80
  Data can also be displayed in several different types of plots: box plots, scatter
81
- plots, line charts, ECDF plots, Q-Q plots, Fisher-Jenks group plots, strip charts,
82
- and counts of categorical and quantitative variables. Plots
81
+ plots, line charts, kernel density plots, ECDF plots, Q-Q plots, strip charts,
82
+ counts of categorical and quantitative variables, and others. Plots
83
83
  can use either all data or only data values that are selected in the map and
84
84
  table. Plots have a live connection to the data table and map, so when data selections are changed the plots are automatically updated.
85
85
 
86
86
  ![example plot](https://mapdata.readthedocs.io/en/latest/_images/UI_cat_stripchart.png)
87
87
 
88
- *Mapdata* can also display summaries of univariate and bivariate statistics for selected variables. These summaries can use either all data in the data table or only the data that are highlighted on the map. These summaries are updated immediately if different data are selected.
88
+ *Mapdata* can also carry out some univariate, bivariate, and multivariate statistical
89
+ summarizations and analyses. Statistical analyses can use either all data in the data table
90
+ or only the data that are highlighted on the map. These summaries are updated immediately
91
+ if different data are selected.
89
92
 
90
93
  ![Bivariate statistics](https://mapdata.readthedocs.io/en/latest/_images/Bivariate_dialog.png)
91
94
 
92
- In addition to univariate and bivariate statistics, and plots, *mapdata* can display the relationships between variables in the form of:
95
+ Statistical summaries and analyses include:
96
+
97
+ * Bivariate ordinary least squares regression and trend evaluation.
93
98
 
94
99
  * A correlation matrix.
95
100
 
101
+ * Parametric and nonparametric analysis of variance (ANOVA).
102
+
96
103
  * A contingency table, using either categorical or numeric variables, with flexible
97
104
  specification of groups. Tests of independence, risk ratio, odds ratio and related
98
105
  statistics, and conditional probabilities are all shown.