mapdata 3.18.0__tar.gz → 3.20.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.18.0/mapdata.egg-info → mapdata-3.20.0}/PKG-INFO +2 -2
  2. {mapdata-3.18.0 → mapdata-3.20.0}/mapdata/mapdata.py +322 -16
  3. {mapdata-3.18.0 → mapdata-3.20.0/mapdata.egg-info}/PKG-INFO +2 -2
  4. {mapdata-3.18.0 → mapdata-3.20.0}/setup.py +2 -2
  5. {mapdata-3.18.0 → mapdata-3.20.0}/LICENSE.txt +0 -0
  6. {mapdata-3.18.0 → mapdata-3.20.0}/MANIFEST.in +0 -0
  7. {mapdata-3.18.0 → mapdata-3.20.0}/README.md +0 -0
  8. {mapdata-3.18.0 → mapdata-3.20.0}/mapdata/configfile/mapdata.conf +0 -0
  9. {mapdata-3.18.0 → mapdata-3.20.0}/mapdata/symbols/16x16/0.xbm +0 -0
  10. {mapdata-3.18.0 → mapdata-3.20.0}/mapdata/symbols/16x16/1.xbm +0 -0
  11. {mapdata-3.18.0 → mapdata-3.20.0}/mapdata/symbols/16x16/2.xbm +0 -0
  12. {mapdata-3.18.0 → mapdata-3.20.0}/mapdata/symbols/16x16/3.xbm +0 -0
  13. {mapdata-3.18.0 → mapdata-3.20.0}/mapdata/symbols/16x16/4.xbm +0 -0
  14. {mapdata-3.18.0 → mapdata-3.20.0}/mapdata/symbols/16x16/5.xbm +0 -0
  15. {mapdata-3.18.0 → mapdata-3.20.0}/mapdata/symbols/16x16/6.xbm +0 -0
  16. {mapdata-3.18.0 → mapdata-3.20.0}/mapdata/symbols/16x16/7.xbm +0 -0
  17. {mapdata-3.18.0 → mapdata-3.20.0}/mapdata/symbols/16x16/8.xbm +0 -0
  18. {mapdata-3.18.0 → mapdata-3.20.0}/mapdata/symbols/16x16/9.xbm +0 -0
  19. {mapdata-3.18.0 → mapdata-3.20.0}/mapdata/symbols/16x16/A.xbm +0 -0
  20. {mapdata-3.18.0 → mapdata-3.20.0}/mapdata/symbols/16x16/B.xbm +0 -0
  21. {mapdata-3.18.0 → mapdata-3.20.0}/mapdata/symbols/16x16/C.xbm +0 -0
  22. {mapdata-3.18.0 → mapdata-3.20.0}/mapdata/symbols/16x16/D.xbm +0 -0
  23. {mapdata-3.18.0 → mapdata-3.20.0}/mapdata/symbols/16x16/E.xbm +0 -0
  24. {mapdata-3.18.0 → mapdata-3.20.0}/mapdata/symbols/16x16/F.xbm +0 -0
  25. {mapdata-3.18.0 → mapdata-3.20.0}/mapdata/symbols/16x16/G.xbm +0 -0
  26. {mapdata-3.18.0 → mapdata-3.20.0}/mapdata/symbols/16x16/H.xbm +0 -0
  27. {mapdata-3.18.0 → mapdata-3.20.0}/mapdata/symbols/16x16/I.xbm +0 -0
  28. {mapdata-3.18.0 → mapdata-3.20.0}/mapdata/symbols/16x16/J.xbm +0 -0
  29. {mapdata-3.18.0 → mapdata-3.20.0}/mapdata/symbols/16x16/K.xbm +0 -0
  30. {mapdata-3.18.0 → mapdata-3.20.0}/mapdata/symbols/16x16/L.xbm +0 -0
  31. {mapdata-3.18.0 → mapdata-3.20.0}/mapdata/symbols/16x16/M.xbm +0 -0
  32. {mapdata-3.18.0 → mapdata-3.20.0}/mapdata/symbols/16x16/N.xbm +0 -0
  33. {mapdata-3.18.0 → mapdata-3.20.0}/mapdata/symbols/16x16/O.xbm +0 -0
  34. {mapdata-3.18.0 → mapdata-3.20.0}/mapdata/symbols/16x16/P.xbm +0 -0
  35. {mapdata-3.18.0 → mapdata-3.20.0}/mapdata/symbols/16x16/Q.xbm +0 -0
  36. {mapdata-3.18.0 → mapdata-3.20.0}/mapdata/symbols/16x16/R.xbm +0 -0
  37. {mapdata-3.18.0 → mapdata-3.20.0}/mapdata/symbols/16x16/S.xbm +0 -0
  38. {mapdata-3.18.0 → mapdata-3.20.0}/mapdata/symbols/16x16/T.xbm +0 -0
  39. {mapdata-3.18.0 → mapdata-3.20.0}/mapdata/symbols/16x16/U.xbm +0 -0
  40. {mapdata-3.18.0 → mapdata-3.20.0}/mapdata/symbols/16x16/V.xbm +0 -0
  41. {mapdata-3.18.0 → mapdata-3.20.0}/mapdata/symbols/16x16/W.xbm +0 -0
  42. {mapdata-3.18.0 → mapdata-3.20.0}/mapdata/symbols/16x16/X.xbm +0 -0
  43. {mapdata-3.18.0 → mapdata-3.20.0}/mapdata/symbols/16x16/Y.xbm +0 -0
  44. {mapdata-3.18.0 → mapdata-3.20.0}/mapdata/symbols/16x16/Z.xbm +0 -0
  45. {mapdata-3.18.0 → mapdata-3.20.0}/mapdata/symbols/16x16/airplane.xbm +0 -0
  46. {mapdata-3.18.0 → mapdata-3.20.0}/mapdata/symbols/16x16/anchor.xbm +0 -0
  47. {mapdata-3.18.0 → mapdata-3.20.0}/mapdata/symbols/16x16/ball.xbm +0 -0
  48. {mapdata-3.18.0 → mapdata-3.20.0}/mapdata/symbols/16x16/ball_small.xbm +0 -0
  49. {mapdata-3.18.0 → mapdata-3.20.0}/mapdata/symbols/16x16/bar.xbm +0 -0
  50. {mapdata-3.18.0 → mapdata-3.20.0}/mapdata/symbols/16x16/bars.xbm +0 -0
  51. {mapdata-3.18.0 → mapdata-3.20.0}/mapdata/symbols/16x16/binoculars.xbm +0 -0
  52. {mapdata-3.18.0 → mapdata-3.20.0}/mapdata/symbols/16x16/bird.xbm +0 -0
  53. {mapdata-3.18.0 → mapdata-3.20.0}/mapdata/symbols/16x16/block.xbm +0 -0
  54. {mapdata-3.18.0 → mapdata-3.20.0}/mapdata/symbols/16x16/block_small.xbm +0 -0
  55. {mapdata-3.18.0 → mapdata-3.20.0}/mapdata/symbols/16x16/bookmark.xbm +0 -0
  56. {mapdata-3.18.0 → mapdata-3.20.0}/mapdata/symbols/16x16/box_stack.xbm +0 -0
  57. {mapdata-3.18.0 → mapdata-3.20.0}/mapdata/symbols/16x16/camera.xbm +0 -0
  58. {mapdata-3.18.0 → mapdata-3.20.0}/mapdata/symbols/16x16/cancel.xbm +0 -0
  59. {mapdata-3.18.0 → mapdata-3.20.0}/mapdata/symbols/16x16/car.xbm +0 -0
  60. {mapdata-3.18.0 → mapdata-3.20.0}/mapdata/symbols/16x16/car2.xbm +0 -0
  61. {mapdata-3.18.0 → mapdata-3.20.0}/mapdata/symbols/16x16/center8.xbm +0 -0
  62. {mapdata-3.18.0 → mapdata-3.20.0}/mapdata/symbols/16x16/check.xbm +0 -0
  63. {mapdata-3.18.0 → mapdata-3.20.0}/mapdata/symbols/16x16/check_circle.xbm +0 -0
  64. {mapdata-3.18.0 → mapdata-3.20.0}/mapdata/symbols/16x16/checkbox.xbm +0 -0
  65. {mapdata-3.18.0 → mapdata-3.20.0}/mapdata/symbols/16x16/checkerboard.xbm +0 -0
  66. {mapdata-3.18.0 → mapdata-3.20.0}/mapdata/symbols/16x16/chevrons.xbm +0 -0
  67. {mapdata-3.18.0 → mapdata-3.20.0}/mapdata/symbols/16x16/circle.xbm +0 -0
  68. {mapdata-3.18.0 → mapdata-3.20.0}/mapdata/symbols/16x16/circle_bar.xbm +0 -0
  69. {mapdata-3.18.0 → mapdata-3.20.0}/mapdata/symbols/16x16/circle_plus.xbm +0 -0
  70. {mapdata-3.18.0 → mapdata-3.20.0}/mapdata/symbols/16x16/circle_stipple.xbm +0 -0
  71. {mapdata-3.18.0 → mapdata-3.20.0}/mapdata/symbols/16x16/circle_triangle.xbm +0 -0
  72. {mapdata-3.18.0 → mapdata-3.20.0}/mapdata/symbols/16x16/circle_wedge.xbm +0 -0
  73. {mapdata-3.18.0 → mapdata-3.20.0}/mapdata/symbols/16x16/circle_x.xbm +0 -0
  74. {mapdata-3.18.0 → mapdata-3.20.0}/mapdata/symbols/16x16/clock.xbm +0 -0
  75. {mapdata-3.18.0 → mapdata-3.20.0}/mapdata/symbols/16x16/columns.xbm +0 -0
  76. {mapdata-3.18.0 → mapdata-3.20.0}/mapdata/symbols/16x16/contract.xbm +0 -0
  77. {mapdata-3.18.0 → mapdata-3.20.0}/mapdata/symbols/16x16/cross.xbm +0 -0
  78. {mapdata-3.18.0 → mapdata-3.20.0}/mapdata/symbols/16x16/darkeye.xbm +0 -0
  79. {mapdata-3.18.0 → mapdata-3.20.0}/mapdata/symbols/16x16/decrease.xbm +0 -0
  80. {mapdata-3.18.0 → mapdata-3.20.0}/mapdata/symbols/16x16/deposition.xbm +0 -0
  81. {mapdata-3.18.0 → mapdata-3.20.0}/mapdata/symbols/16x16/diag_ll.xbm +0 -0
  82. {mapdata-3.18.0 → mapdata-3.20.0}/mapdata/symbols/16x16/diag_lr.xbm +0 -0
  83. {mapdata-3.18.0 → mapdata-3.20.0}/mapdata/symbols/16x16/diag_ul.xbm +0 -0
  84. {mapdata-3.18.0 → mapdata-3.20.0}/mapdata/symbols/16x16/diag_ur.xbm +0 -0
  85. {mapdata-3.18.0 → mapdata-3.20.0}/mapdata/symbols/16x16/dialog.xbm +0 -0
  86. {mapdata-3.18.0 → mapdata-3.20.0}/mapdata/symbols/16x16/diamond.xbm +0 -0
  87. {mapdata-3.18.0 → mapdata-3.20.0}/mapdata/symbols/16x16/donkey.xbm +0 -0
  88. {mapdata-3.18.0 → mapdata-3.20.0}/mapdata/symbols/16x16/dot.xbm +0 -0
  89. {mapdata-3.18.0 → mapdata-3.20.0}/mapdata/symbols/16x16/down.xbm +0 -0
  90. {mapdata-3.18.0 → mapdata-3.20.0}/mapdata/symbols/16x16/drop.xbm +0 -0
  91. {mapdata-3.18.0 → mapdata-3.20.0}/mapdata/symbols/16x16/elephant.xbm +0 -0
  92. {mapdata-3.18.0 → mapdata-3.20.0}/mapdata/symbols/16x16/expand.xbm +0 -0
  93. {mapdata-3.18.0 → mapdata-3.20.0}/mapdata/symbols/16x16/eye.xbm +0 -0
  94. {mapdata-3.18.0 → mapdata-3.20.0}/mapdata/symbols/16x16/fire.xbm +0 -0
  95. {mapdata-3.18.0 → mapdata-3.20.0}/mapdata/symbols/16x16/fish.xbm +0 -0
  96. {mapdata-3.18.0 → mapdata-3.20.0}/mapdata/symbols/16x16/flag.xbm +0 -0
  97. {mapdata-3.18.0 → mapdata-3.20.0}/mapdata/symbols/16x16/flag2.xbm +0 -0
  98. {mapdata-3.18.0 → mapdata-3.20.0}/mapdata/symbols/16x16/four_arrows.xbm +0 -0
  99. {mapdata-3.18.0 → mapdata-3.20.0}/mapdata/symbols/16x16/graph.xbm +0 -0
  100. {mapdata-3.18.0 → mapdata-3.20.0}/mapdata/symbols/16x16/hand.xbm +0 -0
  101. {mapdata-3.18.0 → mapdata-3.20.0}/mapdata/symbols/16x16/hash.xbm +0 -0
  102. {mapdata-3.18.0 → mapdata-3.20.0}/mapdata/symbols/16x16/heart.xbm +0 -0
  103. {mapdata-3.18.0 → mapdata-3.20.0}/mapdata/symbols/16x16/hidden.xbm +0 -0
  104. {mapdata-3.18.0 → mapdata-3.20.0}/mapdata/symbols/16x16/hourglass.xbm +0 -0
  105. {mapdata-3.18.0 → mapdata-3.20.0}/mapdata/symbols/16x16/house.xbm +0 -0
  106. {mapdata-3.18.0 → mapdata-3.20.0}/mapdata/symbols/16x16/increase.xbm +0 -0
  107. {mapdata-3.18.0 → mapdata-3.20.0}/mapdata/symbols/16x16/info.xbm +0 -0
  108. {mapdata-3.18.0 → mapdata-3.20.0}/mapdata/symbols/16x16/leaf.xbm +0 -0
  109. {mapdata-3.18.0 → mapdata-3.20.0}/mapdata/symbols/16x16/left.xbm +0 -0
  110. {mapdata-3.18.0 → mapdata-3.20.0}/mapdata/symbols/16x16/lightbulb.xbm +0 -0
  111. {mapdata-3.18.0 → mapdata-3.20.0}/mapdata/symbols/16x16/lightning.xbm +0 -0
  112. {mapdata-3.18.0 → mapdata-3.20.0}/mapdata/symbols/16x16/lightning2.xbm +0 -0
  113. {mapdata-3.18.0 → mapdata-3.20.0}/mapdata/symbols/16x16/location_ptr.xbm +0 -0
  114. {mapdata-3.18.0 → mapdata-3.20.0}/mapdata/symbols/16x16/mine.xbm +0 -0
  115. {mapdata-3.18.0 → mapdata-3.20.0}/mapdata/symbols/16x16/nested_boxes.xbm +0 -0
  116. {mapdata-3.18.0 → mapdata-3.20.0}/mapdata/symbols/16x16/pennant.xbm +0 -0
  117. {mapdata-3.18.0 → mapdata-3.20.0}/mapdata/symbols/16x16/pennant2.xbm +0 -0
  118. {mapdata-3.18.0 → mapdata-3.20.0}/mapdata/symbols/16x16/people.xbm +0 -0
  119. {mapdata-3.18.0 → mapdata-3.20.0}/mapdata/symbols/16x16/person.xbm +0 -0
  120. {mapdata-3.18.0 → mapdata-3.20.0}/mapdata/symbols/16x16/person2.xbm +0 -0
  121. {mapdata-3.18.0 → mapdata-3.20.0}/mapdata/symbols/16x16/person3.xbm +0 -0
  122. {mapdata-3.18.0 → mapdata-3.20.0}/mapdata/symbols/16x16/phone.xbm +0 -0
  123. {mapdata-3.18.0 → mapdata-3.20.0}/mapdata/symbols/16x16/photo.xbm +0 -0
  124. {mapdata-3.18.0 → mapdata-3.20.0}/mapdata/symbols/16x16/picnic.xbm +0 -0
  125. {mapdata-3.18.0 → mapdata-3.20.0}/mapdata/symbols/16x16/plus.xbm +0 -0
  126. {mapdata-3.18.0 → mapdata-3.20.0}/mapdata/symbols/16x16/point_down.xbm +0 -0
  127. {mapdata-3.18.0 → mapdata-3.20.0}/mapdata/symbols/16x16/point_left.xbm +0 -0
  128. {mapdata-3.18.0 → mapdata-3.20.0}/mapdata/symbols/16x16/point_right.xbm +0 -0
  129. {mapdata-3.18.0 → mapdata-3.20.0}/mapdata/symbols/16x16/point_up.xbm +0 -0
  130. {mapdata-3.18.0 → mapdata-3.20.0}/mapdata/symbols/16x16/pointer_ne.xbm +0 -0
  131. {mapdata-3.18.0 → mapdata-3.20.0}/mapdata/symbols/16x16/pointer_nw.xbm +0 -0
  132. {mapdata-3.18.0 → mapdata-3.20.0}/mapdata/symbols/16x16/pointer_se.xbm +0 -0
  133. {mapdata-3.18.0 → mapdata-3.20.0}/mapdata/symbols/16x16/pointer_sw.xbm +0 -0
  134. {mapdata-3.18.0 → mapdata-3.20.0}/mapdata/symbols/16x16/puzzle.xbm +0 -0
  135. {mapdata-3.18.0 → mapdata-3.20.0}/mapdata/symbols/16x16/q1.xbm +0 -0
  136. {mapdata-3.18.0 → mapdata-3.20.0}/mapdata/symbols/16x16/q1_notch.xbm +0 -0
  137. {mapdata-3.18.0 → mapdata-3.20.0}/mapdata/symbols/16x16/q2.xbm +0 -0
  138. {mapdata-3.18.0 → mapdata-3.20.0}/mapdata/symbols/16x16/q2_notch.xbm +0 -0
  139. {mapdata-3.18.0 → mapdata-3.20.0}/mapdata/symbols/16x16/q3.xbm +0 -0
  140. {mapdata-3.18.0 → mapdata-3.20.0}/mapdata/symbols/16x16/q3_notch.xbm +0 -0
  141. {mapdata-3.18.0 → mapdata-3.20.0}/mapdata/symbols/16x16/q4.xbm +0 -0
  142. {mapdata-3.18.0 → mapdata-3.20.0}/mapdata/symbols/16x16/q4_notch.xbm +0 -0
  143. {mapdata-3.18.0 → mapdata-3.20.0}/mapdata/symbols/16x16/qmark_circle.xbm +0 -0
  144. {mapdata-3.18.0 → mapdata-3.20.0}/mapdata/symbols/16x16/qmark_circle2.xbm +0 -0
  145. {mapdata-3.18.0 → mapdata-3.20.0}/mapdata/symbols/16x16/raincloud.xbm +0 -0
  146. {mapdata-3.18.0 → mapdata-3.20.0}/mapdata/symbols/16x16/right.xbm +0 -0
  147. {mapdata-3.18.0 → mapdata-3.20.0}/mapdata/symbols/16x16/rocket.xbm +0 -0
  148. {mapdata-3.18.0 → mapdata-3.20.0}/mapdata/symbols/16x16/rocket2.xbm +0 -0
  149. {mapdata-3.18.0 → mapdata-3.20.0}/mapdata/symbols/16x16/rose.xbm +0 -0
  150. {mapdata-3.18.0 → mapdata-3.20.0}/mapdata/symbols/16x16/rows.xbm +0 -0
  151. {mapdata-3.18.0 → mapdata-3.20.0}/mapdata/symbols/16x16/scales.xbm +0 -0
  152. {mapdata-3.18.0 → mapdata-3.20.0}/mapdata/symbols/16x16/search.xbm +0 -0
  153. {mapdata-3.18.0 → mapdata-3.20.0}/mapdata/symbols/16x16/search2.xbm +0 -0
  154. {mapdata-3.18.0 → mapdata-3.20.0}/mapdata/symbols/16x16/skull.xbm +0 -0
  155. {mapdata-3.18.0 → mapdata-3.20.0}/mapdata/symbols/16x16/square.xbm +0 -0
  156. {mapdata-3.18.0 → mapdata-3.20.0}/mapdata/symbols/16x16/star.xbm +0 -0
  157. {mapdata-3.18.0 → mapdata-3.20.0}/mapdata/symbols/16x16/stipple.xbm +0 -0
  158. {mapdata-3.18.0 → mapdata-3.20.0}/mapdata/symbols/16x16/stop.xbm +0 -0
  159. {mapdata-3.18.0 → mapdata-3.20.0}/mapdata/symbols/16x16/surprise_circle.xbm +0 -0
  160. {mapdata-3.18.0 → mapdata-3.20.0}/mapdata/symbols/16x16/swamp.xbm +0 -0
  161. {mapdata-3.18.0 → mapdata-3.20.0}/mapdata/symbols/16x16/target.xbm +0 -0
  162. {mapdata-3.18.0 → mapdata-3.20.0}/mapdata/symbols/16x16/target2.xbm +0 -0
  163. {mapdata-3.18.0 → mapdata-3.20.0}/mapdata/symbols/16x16/ten.xbm +0 -0
  164. {mapdata-3.18.0 → mapdata-3.20.0}/mapdata/symbols/16x16/trash.xbm +0 -0
  165. {mapdata-3.18.0 → mapdata-3.20.0}/mapdata/symbols/16x16/tree.xbm +0 -0
  166. {mapdata-3.18.0 → mapdata-3.20.0}/mapdata/symbols/16x16/tree2.xbm +0 -0
  167. {mapdata-3.18.0 → mapdata-3.20.0}/mapdata/symbols/16x16/tree3.xbm +0 -0
  168. {mapdata-3.18.0 → mapdata-3.20.0}/mapdata/symbols/16x16/triangle.xbm +0 -0
  169. {mapdata-3.18.0 → mapdata-3.20.0}/mapdata/symbols/16x16/triangle_open.xbm +0 -0
  170. {mapdata-3.18.0 → mapdata-3.20.0}/mapdata/symbols/16x16/triangle_sm.xbm +0 -0
  171. {mapdata-3.18.0 → mapdata-3.20.0}/mapdata/symbols/16x16/up.xbm +0 -0
  172. {mapdata-3.18.0 → mapdata-3.20.0}/mapdata/symbols/16x16/vapor.xbm +0 -0
  173. {mapdata-3.18.0 → mapdata-3.20.0}/mapdata/symbols/16x16/warning.xbm +0 -0
  174. {mapdata-3.18.0 → mapdata-3.20.0}/mapdata/symbols/16x16/wave.xbm +0 -0
  175. {mapdata-3.18.0 → mapdata-3.20.0}/mapdata/symbols/16x16/wave2.xbm +0 -0
  176. {mapdata-3.18.0 → mapdata-3.20.0}/mapdata/symbols/16x16/wave3.xbm +0 -0
  177. {mapdata-3.18.0 → mapdata-3.20.0}/mapdata/symbols/16x16/weather.xbm +0 -0
  178. {mapdata-3.18.0 → mapdata-3.20.0}/mapdata/symbols/16x16/wedge.xbm +0 -0
  179. {mapdata-3.18.0 → mapdata-3.20.0}/mapdata/symbols/16x16/wedge_sm.xbm +0 -0
  180. {mapdata-3.18.0 → mapdata-3.20.0}/mapdata/symbols/16x16/wedges_3.xbm +0 -0
  181. {mapdata-3.18.0 → mapdata-3.20.0}/mapdata/symbols/16x16/well.xbm +0 -0
  182. {mapdata-3.18.0 → mapdata-3.20.0}/mapdata/symbols/16x16/whale.xbm +0 -0
  183. {mapdata-3.18.0 → mapdata-3.20.0}/mapdata/symbols/16x16/whale2.xbm +0 -0
  184. {mapdata-3.18.0 → mapdata-3.20.0}/mapdata/symbols/16x16/wheelchair.xbm +0 -0
  185. {mapdata-3.18.0 → mapdata-3.20.0}/mapdata/symbols/16x16/zigzags.xbm +0 -0
  186. {mapdata-3.18.0 → mapdata-3.20.0}/mapdata/symbols/16x16/zigzags2.xbm +0 -0
  187. {mapdata-3.18.0 → mapdata-3.20.0}/mapdata/symbols/20x20/ball20.xbm +0 -0
  188. {mapdata-3.18.0 → mapdata-3.20.0}/mapdata/symbols/20x20/block20.xbm +0 -0
  189. {mapdata-3.18.0 → mapdata-3.20.0}/mapdata/symbols/20x20/circle20.xbm +0 -0
  190. {mapdata-3.18.0 → mapdata-3.20.0}/mapdata/symbols/20x20/q1_20.xbm +0 -0
  191. {mapdata-3.18.0 → mapdata-3.20.0}/mapdata/symbols/20x20/q2_20.xbm +0 -0
  192. {mapdata-3.18.0 → mapdata-3.20.0}/mapdata/symbols/20x20/q3_20.xbm +0 -0
  193. {mapdata-3.18.0 → mapdata-3.20.0}/mapdata/symbols/20x20/q4_20.xbm +0 -0
  194. {mapdata-3.18.0 → mapdata-3.20.0}/mapdata/symbols/20x20/square20.xbm +0 -0
  195. {mapdata-3.18.0 → mapdata-3.20.0}/mapdata/symbols/24x24/ball24.xbm +0 -0
  196. {mapdata-3.18.0 → mapdata-3.20.0}/mapdata/symbols/24x24/block24.xbm +0 -0
  197. {mapdata-3.18.0 → mapdata-3.20.0}/mapdata/symbols/24x24/circle24.xbm +0 -0
  198. {mapdata-3.18.0 → mapdata-3.20.0}/mapdata/symbols/24x24/square24.xbm +0 -0
  199. {mapdata-3.18.0 → mapdata-3.20.0}/mapdata/symbols/28x28/ball28.xbm +0 -0
  200. {mapdata-3.18.0 → mapdata-3.20.0}/mapdata/symbols/28x28/block28.xbm +0 -0
  201. {mapdata-3.18.0 → mapdata-3.20.0}/mapdata/symbols/28x28/circle28.xbm +0 -0
  202. {mapdata-3.18.0 → mapdata-3.20.0}/mapdata/symbols/28x28/square28.xbm +0 -0
  203. {mapdata-3.18.0 → mapdata-3.20.0}/mapdata.egg-info/SOURCES.txt +0 -0
  204. {mapdata-3.18.0 → mapdata-3.20.0}/mapdata.egg-info/dependency_links.txt +0 -0
  205. {mapdata-3.18.0 → mapdata-3.20.0}/mapdata.egg-info/requires.txt +0 -0
  206. {mapdata-3.18.0 → mapdata-3.20.0}/mapdata.egg-info/top_level.txt +0 -0
  207. {mapdata-3.18.0 → mapdata-3.20.0}/setup.cfg +0 -0
@@ -1,12 +1,12 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: mapdata
3
- Version: 3.18.0
3
+ Version: 3.20.0
4
4
  Summary: An interactive map and table explorer for geographic coordinates in a spreadsheet, CSV file, or database that includes data plotting and statistical summaries
5
5
  Home-page: https:/hg.sr.ht/~rdnielsen/mapdata
6
6
  Author: Dreas Nielsen
7
7
  Author-email: cortice@tutanota.com
8
8
  License: GPL
9
- Keywords: Map,Locations,CRS,CSV,Spreadsheet,Database,PNG,JPG,Postscript
9
+ Keywords: Map,Locations,CRS,CSV,Spreadsheet,Database,Statistics,Plotting,PNG,JPG,Postscript
10
10
  Classifier: Development Status :: 5 - Production/Stable
11
11
  Classifier: Environment :: Console
12
12
  Classifier: Environment :: X11 Applications
@@ -24,8 +24,8 @@
24
24
  #
25
25
  # ==================================================================
26
26
 
27
- version = "3.18.0"
28
- vdate = "2026-02-02"
27
+ version = "3.20.0"
28
+ vdate = "2026-03-09"
29
29
 
30
30
  copyright = "2023-2026"
31
31
 
@@ -1332,12 +1332,14 @@ def enable_if(widget, tf_val):
1332
1332
  widget["state"] = tk.NORMAL if tf_val else tk.DISABLED
1333
1333
 
1334
1334
  def chosen_dataset(maingui, column_list, selected_only):
1335
+ # Returns the dataset as a column-oriented list of lists.
1335
1336
  if selected_only:
1336
1337
  return maingui.get_sel_data(column_list)
1337
1338
  else:
1338
1339
  return maingui.get_all_data(column_list)
1339
1340
 
1340
1341
  def chosen_dataset_and_ids(maingui, column_list, selected_only):
1342
+ # Returns the dataset as a column-oriented list of lists.
1341
1343
  if selected_only:
1342
1344
  return maingui.get_sel_data(column_list), maingui.get_sel_rowids()
1343
1345
  else:
@@ -3401,7 +3403,7 @@ class MapUI(object):
3401
3403
  def get_all_rowids(self):
3402
3404
  return self.tbl.get_children()
3403
3405
  def get_sel_data(self, column_list):
3404
- # Plotting and statistics support. Return data from selected rows for the specified columns, as a list of lists.
3406
+ # Plotting and statistics support. Return data from selected rows for the specified columns, as a list of column-oriented lists.
3405
3407
  res = [[] for _ in column_list]
3406
3408
  indices = [self.headers.index(c) for c in column_list]
3407
3409
  for sel_row in self.tbl.selection():
@@ -4015,6 +4017,14 @@ class MapUI(object):
4015
4017
  dlg = UniqueValuesDialog(self, self.data_types)
4016
4018
  dlg.show()
4017
4019
 
4020
+ def show_missing_byrow(self, args=None):
4021
+ dlg = MissingByRowDialog(self, self.data_types)
4022
+ dlg.show()
4023
+
4024
+ def show_missing_byvariable(self, args=None):
4025
+ dlg = MissingByVariableDialog(self, self.data_types)
4026
+ dlg.show()
4027
+
4018
4028
  def add_rowid(self, args=None):
4019
4029
  dlg = AddRowIDDialog(self, self.data_types)
4020
4030
  colname, prefix = dlg.show()
@@ -4523,6 +4533,8 @@ class MapUI(object):
4523
4533
  tbl_menu.add_command(label="Hide/show columns", command = self.hide_columns, underline=0)
4524
4534
  tbl_menu.add_command(label="Counts by location", command=self.counts_by_loc, underline=0)
4525
4535
  tbl_menu.add_command(label="Unique values", command=self.unique_data_values, underline=3)
4536
+ tbl_menu.add_command(label="Missing by row", command=self.show_missing_byrow, underline=0)
4537
+ tbl_menu.add_command(label="Missing by variable", command=self.show_missing_byvariable, underline=11)
4526
4538
  tbl_menu.add_command(label="Find candidate keys", command=self.find_candkeys, underline=0)
4527
4539
  tbl_menu.add_command(label="Find duplicate rows", command=self.find_duprows, underline=3)
4528
4540
  tbl_menu.add_command(label="Test cardinality", command=self.cardinality_test, underline=10)
@@ -6798,6 +6810,277 @@ class UniqueValuesDialog(Dialog):
6798
6810
  self.dlg.wait_window(self.dlg)
6799
6811
 
6800
6812
 
6813
+ class MissingByRowDialog(Dialog):
6814
+ def __init__(self, parent, column_specs):
6815
+ self.parent = parent
6816
+ self.column_specs = column_specs
6817
+ self.auto_update = True
6818
+ super().__init__("Rows with Missing Values",
6819
+ "Select one or more variables from the left to see how many rows have 0, 1, 2, or more missing values for these variables. A grouping variable may optionally be used. Use Ctrl-click or Shift-click to select multiple rows.",
6820
+ help_url="https://mapdata.readthedocs.io/en/latest/missing_by_row.html")
6821
+ # Data
6822
+ self.dataset = None
6823
+ self.data_labels = None
6824
+ self.all_columns = sorted([c[0] for c in self.column_specs])
6825
+ self.categ_columns = sorted([c[0] for c in self.column_specs if c[1] in ("string", "boolean", "date", "timestamp")])
6826
+ self.dnames = ["Group", "Missing values", "Number of rows"]
6827
+ self.dlg.bind("<Control-s>")
6828
+
6829
+ # Top controls
6830
+ self.sel_only_var, self.sel_only_ck = add_sel_only(self.ctrl_frame, 0, 0, self.q_recalc)
6831
+ self.autoupdate_var = add_autoupdate(self.ctrl_frame, 0, 1, self.set_autoupdate)
6832
+ self.ctrl_frame.columnconfigure(0, weight=0)
6833
+ self.ctrl_frame.columnconfigure(1, weight=1)
6834
+
6835
+ # Two panes for the variable frame and the content frame
6836
+ frame_panes = ttk.PanedWindow(self.content_frame, orient=tk.HORIZONTAL)
6837
+ frame_panes.grid(row=0, column=0, sticky=tk.NSEW, padx=3, pady=3)
6838
+
6839
+ # Variable frame for list of columns/variables
6840
+ var_frame = tk.Frame(frame_panes, borderwidth=2, relief=tk.RIDGE)
6841
+ var_frame.grid(row=0, column=0, sticky=tk.NSEW)
6842
+ var_frame.rowconfigure(0, weight=1)
6843
+ var_frame.columnconfigure(0, weight=1)
6844
+ frame_panes.add(var_frame, weight=1)
6845
+ # Add multi-select list of variables to the leftmost pane
6846
+ self.column_frame, self.column_table = treeview_table(var_frame, rowset=[[v] for v in self.all_columns], \
6847
+ column_headers=['Variable'], select_mode=tk.EXTENDED, nrows=min(10, len(self.all_columns)))
6848
+ self.column_frame.grid(row=0, column=0, sticky=tk.NSEW)
6849
+ self.column_table.bind('<ButtonRelease-1>', self.q_recalc)
6850
+
6851
+ # Add an optional 'group by' variable selection
6852
+ self.groupby_var = tk.StringVar(var_frame, "")
6853
+ groupby_lbl = ttk.Label(var_frame, text="Group by:")
6854
+ groupby_lbl.grid(row=1, column=0, sticky=tk.W, padx=(6,3), pady=(3,3))
6855
+ self.groupby_sel = ttk.Combobox(var_frame, state="readonly", textvariable=self.groupby_var,
6856
+ values= [''] + self.categ_columns, width=24)
6857
+ self.groupby_sel.grid(row=2, column=0, sticky=tk.W, padx=(12,3), pady=(3,3))
6858
+ self.groupby_sel.bind("<<ComboboxSelected>>", self.q_recalc)
6859
+
6860
+ # output frame. This contains a Treeview table with the counts of missing values.
6861
+ self.output_frame = tk.Frame(frame_panes, borderwidth=3, relief=tk.RIDGE)
6862
+ self.output_frame.grid(row=0, column=0, sticky=tk.NSEW)
6863
+ self.output_frame.rowconfigure(0, weight=1)
6864
+ self.output_frame.columnconfigure(0, weight=1)
6865
+ frame_panes.add(self.output_frame, weight=12)
6866
+
6867
+ # initialize content frame with headings, no data
6868
+ self.clear_output()
6869
+
6870
+ # Buttons
6871
+ add_help_close_buttons(self.dlg, self.btn_frame, self.do_help, self.do_close)
6872
+
6873
+ def clear_output(self):
6874
+ for ctl in self.output_frame.winfo_children():
6875
+ ctl.destroy()
6876
+ clear_dlg_hotkeys(self.dlg)
6877
+ self.dataset = None
6878
+ self.missingdata = None
6879
+ tframe, tdata = treeview_table(self.output_frame, [], self.dnames)
6880
+ tframe.grid(row=0, column=0, sticky=tk.NSEW)
6881
+
6882
+ def q_recalc(self, *args):
6883
+ if len(self.column_table.selection()) > 0:
6884
+ self.clear_output()
6885
+ self.get_data()
6886
+ if self.dataset is not None and len(self.dataset[0]) > 0:
6887
+ self.recalc()
6888
+
6889
+ def get_data(self):
6890
+ # Get the selected data into 'dataset'
6891
+ self.dataset = None
6892
+ self.n_dataset_columns = 0
6893
+ column_list = []
6894
+ for sel_row in self.column_table.selection():
6895
+ datarow = self.column_table.item(sel_row)["values"]
6896
+ column_list.append(datarow[0])
6897
+ if len(column_list) > 0:
6898
+ self.n_dataset_columns = len(column_list)
6899
+ if self.groupby_var.get() != "":
6900
+ column_list.append(self.groupby_var.get())
6901
+ # Get either only the selected data or all data.
6902
+ dataset = chosen_dataset(self.parent, column_list, self.sel_only_var.get() == "1")
6903
+ if dataset is None or len(dataset[0]) == 0:
6904
+ self.dataset = None
6905
+ self.data_labels = None
6906
+ else:
6907
+ self.dataset = dataset
6908
+ self.data_labels = column_list
6909
+
6910
+ def recalc(self):
6911
+ # Find the numbers of missing values of all selected rows. This is accumulated as a dictionary
6912
+ # with keys equal to numbers of missing values in a row and values of the number of rows with
6913
+ # that number of missing values.
6914
+ def incmissing(dic, n_missing):
6915
+ if n_missing not in dic.keys():
6916
+ dic[n_missing] = 0
6917
+ dic[n_missing] = dic[n_missing] + 1
6918
+
6919
+ if self.data_labels is not None:
6920
+ if self.groupby_var.get() == "":
6921
+ missings = {}
6922
+ for datarow in columns_to_rows(self.dataset):
6923
+ incmissing(missings, sum(val == '' for val in datarow))
6924
+ self.missingdata = sorted(list(zip(missings.keys(), missings.values())))
6925
+ self.dnames = ["Missing", "Rows"]
6926
+ else:
6927
+ datasetdict = subset_by_groups(self.dataset[0:self.n_dataset_columns], self.dataset[self.n_dataset_columns])
6928
+ self.missingdata = []
6929
+ for grp in datasetdict.keys():
6930
+ ds = columns_to_rows(datasetdict[grp])
6931
+ missings = {}
6932
+ for datarow in ds:
6933
+ incmissing(missings, sum(val == '' for val in datarow))
6934
+ self.missingdata.extend(sorted(list(zip([grp]*len(missings.keys()), missings.keys(), missings.values())), key=lambda x: x[1]))
6935
+ self.dnames = ["Group", "Missing", "Rows"]
6936
+ tframe, tdata = treeview_table(self.output_frame, self.missingdata, self.dnames)
6937
+ tframe.grid(row=0, column=0, sticky=tk.NSEW)
6938
+ self.dlg.bind("<Control-s>", self.save_data)
6939
+ def set_autoupdate(self):
6940
+ self.auto_update = self.autoupdate_var.get() == "1"
6941
+ if self.auto_update:
6942
+ self.q_recalc(None)
6943
+ def save_data(self, *args):
6944
+ export_data_table(self.dnames, self.missingdata, sheetname="Numbers of missing values")
6945
+ def do_close(self, *args):
6946
+ self.parent.remove_univar(self)
6947
+ super().do_cancel(args)
6948
+
6949
+
6950
+
6951
+ class MissingByVariableDialog(Dialog):
6952
+ def __init__(self, parent, column_specs):
6953
+ self.parent = parent
6954
+ self.column_specs = column_specs
6955
+ self.auto_update = True
6956
+ super().__init__("Variables with Missing Values",
6957
+ "Select one or more variables from the left to see how many missing values each has. A grouping variable may optionally be used. Use Ctrl-click or Shift-click to select multiple rows.",
6958
+ help_url="https://mapdata.readthedocs.io/en/latest/missing_by_variable.html")
6959
+ # Data
6960
+ self.dataset = None
6961
+ self.data_labels = None
6962
+ self.all_columns = sorted([c[0] for c in self.column_specs])
6963
+ self.categ_columns = sorted([c[0] for c in self.column_specs if c[1] in ("string", "boolean", "date", "timestamp")])
6964
+ self.dnames = ["Variable", "Missing"]
6965
+ self.dlg.bind("<Control-s>")
6966
+
6967
+ # Top controls
6968
+ self.sel_only_var, self.sel_only_ck = add_sel_only(self.ctrl_frame, 0, 0, self.q_recalc)
6969
+ self.autoupdate_var = add_autoupdate(self.ctrl_frame, 0, 1, self.set_autoupdate)
6970
+ self.ctrl_frame.columnconfigure(0, weight=0)
6971
+ self.ctrl_frame.columnconfigure(1, weight=1)
6972
+
6973
+ # Two panes for the variable frame and the content frame
6974
+ frame_panes = ttk.PanedWindow(self.content_frame, orient=tk.HORIZONTAL)
6975
+ frame_panes.grid(row=0, column=0, sticky=tk.NSEW, padx=3, pady=3)
6976
+
6977
+ # Variable frame for list of all columns/variables
6978
+ var_frame = tk.Frame(frame_panes, borderwidth=2, relief=tk.RIDGE)
6979
+ var_frame.grid(row=0, column=0, sticky=tk.NSEW)
6980
+ var_frame.rowconfigure(0, weight=1)
6981
+ var_frame.columnconfigure(0, weight=1)
6982
+ frame_panes.add(var_frame, weight=1)
6983
+ # Add multi-select list of variables to the leftmost pane
6984
+ self.column_frame, self.column_table = treeview_table(var_frame, rowset=[[v] for v in self.all_columns], \
6985
+ column_headers=['Variable'], select_mode=tk.EXTENDED, nrows=min(10, len(self.all_columns)))
6986
+ self.column_frame.grid(row=0, column=0, sticky=tk.NSEW)
6987
+ self.column_table.bind('<ButtonRelease-1>', self.q_recalc)
6988
+
6989
+ # Add an optional 'group by' variable selection
6990
+ self.groupby_var = tk.StringVar(var_frame, "")
6991
+ groupby_lbl = ttk.Label(var_frame, text="Group by:")
6992
+ groupby_lbl.grid(row=1, column=0, sticky=tk.W, padx=(6,3), pady=(3,3))
6993
+ self.groupby_sel = ttk.Combobox(var_frame, state="readonly", textvariable=self.groupby_var,
6994
+ values= [''] + self.categ_columns, width=24)
6995
+ self.groupby_sel.grid(row=2, column=0, sticky=tk.W, padx=(12,3), pady=(3,3))
6996
+ self.groupby_sel.bind("<<ComboboxSelected>>", self.q_recalc)
6997
+
6998
+ # Output frame. This contains a Treeview table with the counts of missing values.
6999
+ self.output_frame = tk.Frame(frame_panes, borderwidth=3, relief=tk.RIDGE)
7000
+ self.output_frame.grid(row=0, column=0, sticky=tk.NSEW)
7001
+ self.output_frame.rowconfigure(0, weight=1)
7002
+ self.output_frame.columnconfigure(0, weight=1)
7003
+ frame_panes.add(self.output_frame, weight=12)
7004
+
7005
+ # initialize content frame with headings, no data
7006
+ self.clear_output()
7007
+
7008
+ # Buttons
7009
+ add_help_close_buttons(self.dlg, self.btn_frame, self.do_help, self.do_close)
7010
+
7011
+ def clear_output(self):
7012
+ for ctl in self.output_frame.winfo_children():
7013
+ ctl.destroy()
7014
+ clear_dlg_hotkeys(self.dlg)
7015
+ self.dataset = None
7016
+ self.missingdata = None
7017
+ tframe, tdata = treeview_table(self.output_frame, [], self.dnames)
7018
+ tframe.grid(row=0, column=0, sticky=tk.NSEW)
7019
+
7020
+ def q_recalc(self, *args):
7021
+ if len(self.column_table.selection()) > 0:
7022
+ self.clear_output()
7023
+ self.get_data()
7024
+ if self.dataset is not None and len(self.dataset[0]) > 0:
7025
+ self.recalc()
7026
+
7027
+ def get_data(self):
7028
+ # Get the selected data into 'dataset'
7029
+ self.dataset = None
7030
+ self.n_dataset_columns = 0
7031
+ column_list = []
7032
+ for sel_row in self.column_table.selection():
7033
+ datarow = self.column_table.item(sel_row)["values"]
7034
+ column_list.append(datarow[0])
7035
+ if len(column_list) > 0:
7036
+ self.n_dataset_columns = len(column_list)
7037
+ if self.groupby_var.get() != "":
7038
+ column_list.append(self.groupby_var.get())
7039
+ # Get either only the selected data or all data.
7040
+ dataset = chosen_dataset(self.parent, column_list, self.sel_only_var.get() == "1")
7041
+ if dataset is None or len(dataset[0]) == 0:
7042
+ self.dataset = None
7043
+ self.data_labels = None
7044
+ else:
7045
+ self.dataset = dataset
7046
+ self.data_labels = column_list
7047
+
7048
+ def recalc(self):
7049
+ # Find the numbers of missing values of all selected variables.
7050
+ if self.data_labels is not None:
7051
+ if self.groupby_var.get() == "":
7052
+ # Output is two columns, one with the variable name and one with the number of missing values.
7053
+ n_missing = []
7054
+ for col in self.dataset:
7055
+ n_missing.append(sum(val == '' for val in col))
7056
+ self.missingdata = sorted(list(zip(self.data_labels, n_missing)))
7057
+ self.dnames = ["Variable", "Missing"]
7058
+ else:
7059
+ # Output is a table with groups in rows, variables in columns, missing values in cells
7060
+ datasetdict = subset_by_groups(self.dataset[0:self.n_dataset_columns], self.dataset[self.n_dataset_columns])
7061
+ self.missingdata = []
7062
+ for grp in datasetdict.keys():
7063
+ ds = datasetdict[grp]
7064
+ n_missing = [grp]
7065
+ for col in ds:
7066
+ n_missing.append(sum(val == '' for val in col))
7067
+ self.missingdata.append(n_missing)
7068
+ self.dnames = ["Group"] + self.data_labels[:-1]
7069
+ tframe, tdata = treeview_table(self.output_frame, self.missingdata, self.dnames)
7070
+ tframe.grid(row=0, column=0, sticky=tk.NSEW)
7071
+ self.dlg.bind("<Control-s>", self.save_data)
7072
+ def set_autoupdate(self):
7073
+ self.auto_update = self.autoupdate_var.get() == "1"
7074
+ if self.auto_update:
7075
+ self.q_recalc(None)
7076
+ def save_data(self, *args):
7077
+ export_data_table(self.dnames, self.missingdata, sheetname="Numbers of missing values")
7078
+ def do_close(self, *args):
7079
+ self.parent.remove_univar(self)
7080
+ super().do_cancel(args)
7081
+
7082
+
7083
+
6801
7084
  class SelNonMissingDialog(Dialog):
6802
7085
  def __init__(self, column_specs):
6803
7086
  super().__init__("Select Non-Missing Values",
@@ -6948,7 +7231,7 @@ class PlotDialog(Dialog):
6948
7231
  plot_types.append("Date range by category")
6949
7232
  plot_types.extend(["Empirical CDF", "Histogram", "Kernel density (KD) plot", "Line plot", "Mean by category",
6950
7233
  "Min-max by bin", "Min-max by category", "Normal Q-Q plot", "Pareto chart", "Scatter plot", "Stripchart",
6951
- "Total by category", "Violin plot", "Y range plot"])
7234
+ "Total by category", "Violin plot", "Y range plot", "Zipf's Law"])
6952
7235
  self.type_sel = ttk.Combobox(self.ctrl_frame, state="readonly", textvariable=self.type_var, width=20, height=21, values=plot_types)
6953
7236
  self.type_sel.grid(row=0, column=1, columnspan=2, sticky=tk.W, padx=(3,6), pady=(3,3))
6954
7237
  self.type_sel["state"] = tk.NORMAL
@@ -7174,9 +7457,11 @@ class PlotDialog(Dialog):
7174
7457
  elif plot_type == "Min-max by category":
7175
7458
  self.x_sel["state"] = "readonly"
7176
7459
  self.x_sel["values"] = self.quant_columns
7177
- self.xlog_ck["state"] = tk.NORMAL
7178
7460
  self.y_sel["state"] = "readonly"
7179
7461
  self.y_sel["values"] = self.categ_columns2
7462
+ elif plot_type == "Zipf's Law":
7463
+ self.x_sel["state"] = "readonly"
7464
+ self.x_sel["values"] = sorted([c[0] for c in self.column_specs if c[1] == "string"])
7180
7465
  else:
7181
7466
  self.x_sel["state"] = "readonly"
7182
7467
  self.x_sel["values"] = self.quant_columns
@@ -7197,7 +7482,7 @@ class PlotDialog(Dialog):
7197
7482
  # Conditionally (re)draw the plot.
7198
7483
  plot_type = self.type_var.get()
7199
7484
  can_redraw = (plot_type in ("Count by category", "Empirical CDF", "Normal Q-Q plot", "Breaks groups", "Breaks optimum", \
7200
- "Histogram", "Pareto chart") and self.x_var.get() != '') \
7485
+ "Histogram", "Pareto chart", "Zipf's Law") and self.x_var.get() != '') \
7201
7486
  or (plot_type in ("Scatter plot", "Line plot", "Min-max by bin", "Min-max by category", "Y range plot") and \
7202
7487
  self.x_var.get() != '' and self.y_var.get() != '') \
7203
7488
  or (plot_type in ("Box plot", "Kernel density (KD) plot", "Stripchart", "Violin plot") and self.x_var.get() != '') \
@@ -7293,6 +7578,19 @@ class PlotDialog(Dialog):
7293
7578
  x_counts = [counter[k] for k in x_vals]
7294
7579
  self.plot_data = [x_vals, x_counts]
7295
7580
  self.plot_data_labels = [self.data_labels[0], "Count"]
7581
+ elif plot_type == "Zipf's Law":
7582
+ counter = collections.Counter(self.dataset[0])
7583
+ zcts = sorted(list(zip(counter.values(), counter.keys())), key=lambda x: x[0], reverse=True)
7584
+ zd = list(zip(*zcts))
7585
+ zdata = [list(zd[1]), list(zd[0])]
7586
+ zdata.append(list(range(1, len(zdata[0])+1)))
7587
+ tot = sum(zdata[1])
7588
+ zdata.append([x/tot for x in zdata[1]])
7589
+ zdata.append([math.log10(x) for x in zdata[2]])
7590
+ zdata.append([math.log10(x) for x in zdata[3]])
7591
+ self.plot_data = zdata
7592
+ self.plot_data_labels = [self.data_labels[0], "Count", "Rank", "Frequency", "Log10_Rank", "Log10_Frequency"]
7593
+ self.xlog_ck["state"] = tk.DISABLED
7296
7594
  elif plot_type in ("Box plot", "Histogram", "Kernel density (KD) plot", "Stripchart", "Violin plot"):
7297
7595
  if self.groupby_var.get() != '':
7298
7596
  self.plot_data_labels, self.plot_data = spread_by_groups(self.dataset[1], self.dataset[0])
@@ -7869,7 +8167,7 @@ class PlotDialog(Dialog):
7869
8167
  self.plot.axes.plot([pmin, pmax], [pmin, pmax])
7870
8168
  self.plot.set_axis_labels(self.xlabel or self.plot_data_labels[2], self.ylabel or self.plot_data_labels[1])
7871
8169
  elif plot_type == "Pareto chart":
7872
- groups = self.plot_data[0]
8170
+ groups = [str(g) for g in self.plot_data[0]]
7873
8171
  grp_lbls = []
7874
8172
  for g in groups:
7875
8173
  if wrap_at_underscores:
@@ -7983,6 +8281,13 @@ class PlotDialog(Dialog):
7983
8281
  else:
7984
8282
  sns.violinplot({self.x_var.get(): self.dataset[0]}, x=self.x_var.get(), alpha=self.alpha, ax=self.plot_axes)
7985
8283
  self.plot.set_axis_labels(self.ylabel or self.data_labels[0], self.xlabel or self.x_var.get())
8284
+ elif plot_type == "Zipf's Law":
8285
+ self.plot.axes.set_xscale('log')
8286
+ self.plot.axes.set_yscale('log')
8287
+ self.plot.axes.grid(visible=True, color="0.8", linestyle="dotted", which='both', axis='both')
8288
+ self.plot.axes.plot(self.plot_data[2], self.plot_data[3], alpha=self.alpha)
8289
+ self.plot.set_axis_labels(self.plot_data_labels[2], self.xlabel or self.plot_data_labels[3])
8290
+ self.plot_title = self.data_labels[0]
7986
8291
  if self.plot_title is not None:
7987
8292
  self.plot.axes.set_title(self.plot_title)
7988
8293
  self.plot.axes.title.set_visible(True)
@@ -13541,7 +13846,7 @@ class NMFUnmixingDialog(Dialog):
13541
13846
  if self.em_var.get() == 0:
13542
13847
  max_ems = min(12, self.n_dataset_columns-1, len(self.dataset[0])-1)
13543
13848
  test_ems = list(range(1, max_ems))
13544
- #rmses = []
13849
+ rmses = []
13545
13850
  frobs = []
13546
13851
  unmixes = []
13547
13852
  diagnostics = []
@@ -13549,24 +13854,25 @@ class NMFUnmixingDialog(Dialog):
13549
13854
  W, H, frobnorm = iterate_nmf(ds, em_no)
13550
13855
  fit_ds = np.matmul(W, H)
13551
13856
  fit_rss = array_rss(ds, fit_ds)
13552
- fit_aic = n * math.log(fit_rss/n) + 2*em_no
13857
+ fit_aic = n * math.log(fit_rss/n) + 2*(em_no+1)
13553
13858
  fit_rmse = math.sqrt(mean_squared_error(ds, fit_ds))
13859
+ rmses.append(fit_rmse)
13554
13860
  frobs.append(frobnorm)
13555
13861
  kl_div = spstats.entropy(np.ravel(fit_ds), np.ravel(ds))
13556
13862
  unmixes.append((W, H))
13557
13863
  # Diagnostics: Total residual, RSS, AIC, RMSE, Frobenius norm of matrix difference, K-L divergence
13558
13864
  diagnostics.append([em_no, fp_display(arraysum(fit_ds)-arraysum(ds), 4), fp_display(fit_rss,5),
13559
13865
  fp_display(fit_aic,4), fp_display(fit_rmse,4), fp_display(frobnorm,4), fp_display(kl_div,3)])
13560
- if len(frobs) > 1:
13561
- frob_diffs = [frobs[i] - frobs[i+1] for i in range(len(frobs)-1)]
13562
- sel_em = frob_diffs.index(max(frob_diffs))+2
13563
- if len(frob_diffs) > 2:
13564
- frob_diffs2 = [frob_diffs[i] - frob_diffs[i+1] for i in range(len(frob_diffs)-1)]
13565
- sel_em2 = frob_diffs2.index(max(frob_diffs2))+2
13866
+ if len(rmses) > 1:
13867
+ rmse_diffs = [rmses[i] - rmses[i+1] for i in range(len(rmses)-1)]
13868
+ sel_em = rmse_diffs.index(max(rmse_diffs))+2
13869
+ if len(rmse_diffs) > 2:
13870
+ rmse_diffs2 = [rmse_diffs[i] - rmse_diffs[i+1] for i in range(len(rmse_diffs)-1)]
13871
+ sel_em2 = rmse_diffs2.index(max(rmse_diffs2))+2
13566
13872
  if sel_em != max_ems-1:
13567
13873
  sel_em = sel_em2
13568
13874
  else:
13569
- sel_em = frob_diffs.index(max(frob_diffs))+2
13875
+ sel_em = rmse_diffs.index(max(rmse_diffs))+2
13570
13876
  self.em_var.set(sel_em)
13571
13877
  sel_em_index = sel_em - 1
13572
13878
  else:
@@ -1,12 +1,12 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: mapdata
3
- Version: 3.18.0
3
+ Version: 3.20.0
4
4
  Summary: An interactive map and table explorer for geographic coordinates in a spreadsheet, CSV file, or database that includes data plotting and statistical summaries
5
5
  Home-page: https:/hg.sr.ht/~rdnielsen/mapdata
6
6
  Author: Dreas Nielsen
7
7
  Author-email: cortice@tutanota.com
8
8
  License: GPL
9
- Keywords: Map,Locations,CRS,CSV,Spreadsheet,Database,PNG,JPG,Postscript
9
+ Keywords: Map,Locations,CRS,CSV,Spreadsheet,Database,Statistics,Plotting,PNG,JPG,Postscript
10
10
  Classifier: Development Status :: 5 - Production/Stable
11
11
  Classifier: Environment :: Console
12
12
  Classifier: Environment :: X11 Applications
@@ -9,7 +9,7 @@ symbol_files = glob.glob("mapdata/symbols/16x16/*.xbm") + glob.glob("mapdata/sym
9
9
  glob.glob("mapdata/symbols/24x24/*.xbm") + glob.glob("mapdata/symbols/28x28/*.xbm")
10
10
 
11
11
  setuptools.setup(name='mapdata',
12
- version='3.18.0',
12
+ version='3.20.0',
13
13
  description="An interactive map and table explorer for geographic coordinates in a spreadsheet, CSV file, or database that includes data plotting and statistical summaries",
14
14
  author='Dreas Nielsen',
15
15
  author_email='cortice@tutanota.com',
@@ -36,7 +36,7 @@ setuptools.setup(name='mapdata',
36
36
  'Topic :: Office/Business',
37
37
  'Topic :: Scientific/Engineering'
38
38
  ],
39
- keywords=['Map', 'Locations', 'CRS', 'CSV', 'Spreadsheet', 'Database', 'PNG', 'JPG', 'Postscript'],
39
+ keywords=['Map', 'Locations', 'CRS', 'CSV', 'Spreadsheet', 'Database', 'Statistics', 'Plotting', 'PNG', 'JPG', 'Postscript'],
40
40
  long_description_content_type="text/markdown",
41
41
  long_description=long_description
42
42
  )
File without changes
File without changes
File without changes