mapdata 2.11.0__tar.gz → 2.12.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.
- {mapdata-2.11.0/mapdata.egg-info → mapdata-2.12.0}/PKG-INFO +1 -1
- {mapdata-2.11.0 → mapdata-2.12.0}/mapdata/mapdata.py +67 -13
- {mapdata-2.11.0 → mapdata-2.12.0/mapdata.egg-info}/PKG-INFO +1 -1
- {mapdata-2.11.0 → mapdata-2.12.0}/setup.py +1 -1
- {mapdata-2.11.0 → mapdata-2.12.0}/LICENSE.txt +0 -0
- {mapdata-2.11.0 → mapdata-2.12.0}/MANIFEST.in +0 -0
- {mapdata-2.11.0 → mapdata-2.12.0}/README.md +0 -0
- {mapdata-2.11.0 → mapdata-2.12.0}/mapdata/mapdata_2.py +0 -0
- {mapdata-2.11.0 → mapdata-2.12.0}/mapdata/mapdata_cli.py +0 -0
- {mapdata-2.11.0 → mapdata-2.12.0}/mapdata.egg-info/SOURCES.txt +0 -0
- {mapdata-2.11.0 → mapdata-2.12.0}/mapdata.egg-info/dependency_links.txt +0 -0
- {mapdata-2.11.0 → mapdata-2.12.0}/mapdata.egg-info/top_level.txt +0 -0
- {mapdata-2.11.0 → mapdata-2.12.0}/setup.cfg +0 -0
|
@@ -24,8 +24,8 @@
|
|
|
24
24
|
#
|
|
25
25
|
# ==================================================================
|
|
26
26
|
|
|
27
|
-
version = "2.
|
|
28
|
-
vdate = "2023-
|
|
27
|
+
version = "2.12.0"
|
|
28
|
+
vdate = "2023-12-28"
|
|
29
29
|
|
|
30
30
|
copyright = "2023"
|
|
31
31
|
|
|
@@ -459,6 +459,16 @@ class CsvFile(object):
|
|
|
459
459
|
return self
|
|
460
460
|
|
|
461
461
|
|
|
462
|
+
def sort_columns(columns):
|
|
463
|
+
# Sorts a list of one or two sublists, where each sublist is a column. Rows are sorted by the first column.
|
|
464
|
+
# The returned value is also column-wise, but sorted by rows.
|
|
465
|
+
if len(columns) == 1:
|
|
466
|
+
return sorted(columns)
|
|
467
|
+
nrows = len(columns[0])
|
|
468
|
+
rowdata = [[columns[0][i], columns[1][i]] for i in range(nrows)]
|
|
469
|
+
rowdata.sort()
|
|
470
|
+
return [[rowdata[i][0] for i in range(nrows)], [rowdata[i][1] for i in range(nrows)]]
|
|
471
|
+
|
|
462
472
|
def treeview_sort_column(tv, col, reverse):
|
|
463
473
|
# Sort columns in Tkinter Treeview. From https://stackoverflow.com/questions/1966929/tk-treeview-column-sort#1967793
|
|
464
474
|
colvals = [(tv.set(k, col), k) for k in tv.get_children()]
|
|
@@ -2805,8 +2815,8 @@ class PlotDialog(object):
|
|
|
2805
2815
|
self.type_var = tk.StringVar(ctrl_frame, "")
|
|
2806
2816
|
type_lbl = ttk.Label(ctrl_frame, text="Plot type:")
|
|
2807
2817
|
type_lbl.grid(row=0, column=0, sticky=tk.E, padx=(6,3), pady=(3,3))
|
|
2808
|
-
self.type_sel = ttk.Combobox(ctrl_frame, state="readonly", textvariable=self.type_var, width=20,
|
|
2809
|
-
values=["Box plot", "Breaks groups", "Breaks optimum", "Category counts", "Categorical KD plot", "Categorical stripchart", "Empirical CDF", "Histogram", "Kernel density (KD) plot", "Line plot", "Normal Q-Q plot", "Scatter plot", "Violin plot", "Y range plot"])
|
|
2818
|
+
self.type_sel = ttk.Combobox(ctrl_frame, state="readonly", textvariable=self.type_var, width=20, height=15,
|
|
2819
|
+
values=["Box plot", "Breaks groups", "Breaks optimum", "Category counts", "Categorical KD plot", "Categorical stripchart", "Empirical CDF", "Histogram", "Kernel density (KD) plot", "Line plot", "Min-max plot", "Normal Q-Q plot", "Scatter plot", "Violin plot", "Y range plot"])
|
|
2810
2820
|
self.type_sel.grid(row=0, column=1, columnspan=2, sticky=tk.W, padx=(3,6), pady=(3,3))
|
|
2811
2821
|
self.type_sel.bind("<<ComboboxSelected>>", self.set_xy)
|
|
2812
2822
|
|
|
@@ -2940,7 +2950,7 @@ class PlotDialog(object):
|
|
|
2940
2950
|
|
|
2941
2951
|
def y_changed(self, *args):
|
|
2942
2952
|
plot_type = self.type_var.get()
|
|
2943
|
-
if plot_type in ("Category counts", "Histogram", "Empirical CDF"):
|
|
2953
|
+
if plot_type in ("Category counts", "Histogram", "Empirical CDF", "Min-max plot"):
|
|
2944
2954
|
self.ylog_ck["state"] = "disabled"
|
|
2945
2955
|
else:
|
|
2946
2956
|
self.ylog_ck["state"] = "normal"
|
|
@@ -2960,8 +2970,11 @@ class PlotDialog(object):
|
|
|
2960
2970
|
self.plot_data_labels = None
|
|
2961
2971
|
self.data_btn["state"] = "disabled"
|
|
2962
2972
|
self.plot_data_btn["state"] = "disabled"
|
|
2973
|
+
# Category columns. Does not include date columns for most uses, but may include dates for some.
|
|
2963
2974
|
categ_columns = [c[0] for c in self.column_specs if c[1] in ("string", "boolean")]
|
|
2964
2975
|
categ_columns.sort()
|
|
2976
|
+
categ_columns2 = [c[0] for c in self.column_specs if c[1] in ("string", "boolean", "date")]
|
|
2977
|
+
categ_columns2.sort()
|
|
2965
2978
|
# quant_columns includes date and timestamp columns
|
|
2966
2979
|
quant_columns = [c[0] for c in self.column_specs if c[1] in ("int", "float", "date", "timestamp", "timestamptz")]
|
|
2967
2980
|
quant_columns.sort()
|
|
@@ -2990,9 +3003,15 @@ class PlotDialog(object):
|
|
|
2990
3003
|
if plot_type == "Normal Q-Q plot":
|
|
2991
3004
|
self.dlg.bind("<Alt-g>", self.show_groups)
|
|
2992
3005
|
elif plot_type in ("Box plot", "Categorical KD plot", "Categorical stripchart", "Violin plot"):
|
|
2993
|
-
|
|
3006
|
+
xcols = list(set(categ_columns) | set(date_columns))
|
|
3007
|
+
xcols.sort()
|
|
3008
|
+
self.x_sel["values"] = xcols
|
|
2994
3009
|
self.xlog_ck["state"] = "disabled"
|
|
2995
3010
|
self.y_sel["values"] = numeric_columns
|
|
3011
|
+
elif plot_type == "Min-max plot":
|
|
3012
|
+
self.x_sel["values"] = quant_columns
|
|
3013
|
+
self.y_sel["values"] = categ_columns2
|
|
3014
|
+
self.ylog_ck["state"] = "disabled"
|
|
2996
3015
|
else:
|
|
2997
3016
|
self.x_sel["values"] = quant_columns
|
|
2998
3017
|
self.y_sel["values"] = quant_columns
|
|
@@ -3004,7 +3023,7 @@ class PlotDialog(object):
|
|
|
3004
3023
|
"Normal Q-Q plot", "Breaks groups", "Breaks optimum", "Histogram") \
|
|
3005
3024
|
and self.x_var.get() != '') \
|
|
3006
3025
|
or (plot_type in ("Scatter plot", "Line plot", "Box plot", "Categorical KD plot", "Categorical stripchart", \
|
|
3007
|
-
"Violin plot", "Y range plot") and self.x_var.get() != '' and self.y_var.get() != '')
|
|
3026
|
+
"Min-max plot", "Violin plot", "Y range plot") and self.x_var.get() != '' and self.y_var.get() != '')
|
|
3008
3027
|
if can_redraw:
|
|
3009
3028
|
self.plotfig.clear()
|
|
3010
3029
|
self.plot_axes = self.plotfig.add_subplot(111)
|
|
@@ -3022,6 +3041,7 @@ class PlotDialog(object):
|
|
|
3022
3041
|
column_list = [self.x_var.get()]
|
|
3023
3042
|
if self.y_var.get() != '':
|
|
3024
3043
|
column_list.append(self.y_var.get())
|
|
3044
|
+
# Get either only the selected data or all data.
|
|
3025
3045
|
if self.sel_only_var.get() == "1":
|
|
3026
3046
|
dataset = self.parent.get_sel_data(column_list)
|
|
3027
3047
|
else:
|
|
@@ -3057,6 +3077,8 @@ class PlotDialog(object):
|
|
|
3057
3077
|
cast_fn = data_type_cast_fn(y_data_type)
|
|
3058
3078
|
for i in range(len(clean_data[1])):
|
|
3059
3079
|
clean_data[1][i] = cast_fn(clean_data[1][i])
|
|
3080
|
+
# Sort the dataset by X values
|
|
3081
|
+
clean_data = sort_columns(clean_data)
|
|
3060
3082
|
# Set data labels
|
|
3061
3083
|
if self.y_var.get() != '':
|
|
3062
3084
|
self.data_labels = [self.x_var.get(), self.y_var.get()]
|
|
@@ -3106,6 +3128,7 @@ class PlotDialog(object):
|
|
|
3106
3128
|
elif plot_type in ("Box plot", "Categorical KD plot", "Categorical stripchart", "Violin plot"):
|
|
3107
3129
|
# A list of Y values for each X value
|
|
3108
3130
|
x_vals = list(set(self.dataset[0]))
|
|
3131
|
+
x_vals.sort()
|
|
3109
3132
|
ds = list(zip(self.dataset[0], self.dataset[1]))
|
|
3110
3133
|
plot_data = []
|
|
3111
3134
|
for x in x_vals:
|
|
@@ -3135,7 +3158,24 @@ class PlotDialog(object):
|
|
|
3135
3158
|
self.plot_data_labels = [self.data_labels[0], "Cumulative frequency"]
|
|
3136
3159
|
elif plot_type == "Kernel density (KD) plot":
|
|
3137
3160
|
self.plot_data = self.dataset
|
|
3138
|
-
self.plot_data_labels = [self.x_var.get()]
|
|
3161
|
+
#self.plot_data_labels = [self.x_var.get()]
|
|
3162
|
+
elif plot_type == "Min-max plot":
|
|
3163
|
+
# Min and max X for each Y
|
|
3164
|
+
y_vals = list(set(self.dataset[1]))
|
|
3165
|
+
y_vals.sort()
|
|
3166
|
+
plotdata = dict(zip(y_vals, [[None, None] for _ in y_vals]))
|
|
3167
|
+
for i in range(len(self.dataset[1])):
|
|
3168
|
+
x = self.dataset[0][i]
|
|
3169
|
+
y = self.dataset[1][i]
|
|
3170
|
+
x_vals = plotdata[y]
|
|
3171
|
+
if x_vals[0] is None or x < x_vals[0]:
|
|
3172
|
+
plotdata[y][0] = x
|
|
3173
|
+
if x_vals[1] is None or x > x_vals[1]:
|
|
3174
|
+
plotdata[y][1] = x
|
|
3175
|
+
x1 = [plotdata[y][0] for y in y_vals]
|
|
3176
|
+
x2 = [plotdata[y][1] for y in y_vals]
|
|
3177
|
+
self.plot_data = [y_vals, x1, x2]
|
|
3178
|
+
self.plot_data_labels = [self.data_labels[1], self.data_labels[0] + " min", self.data_labels[0] + " max"]
|
|
3139
3179
|
elif plot_type == "Normal Q-Q plot":
|
|
3140
3180
|
x_vals = copy.copy(self.dataset[0])
|
|
3141
3181
|
x_vals.sort()
|
|
@@ -3154,8 +3194,7 @@ class PlotDialog(object):
|
|
|
3154
3194
|
# Min and max Y for each X
|
|
3155
3195
|
x_vals = list(set(self.dataset[0]))
|
|
3156
3196
|
x_vals.sort()
|
|
3157
|
-
|
|
3158
|
-
plotdata = dict(zip(x_vals, y_vals))
|
|
3197
|
+
plotdata = dict(zip(x_vals, [[None, None] for i in x_vals]))
|
|
3159
3198
|
for i in range(len(self.dataset[0])):
|
|
3160
3199
|
x = self.dataset[0][i]
|
|
3161
3200
|
y = self.dataset[1][i]
|
|
@@ -3208,7 +3247,7 @@ class PlotDialog(object):
|
|
|
3208
3247
|
ticks.insert(0,0)
|
|
3209
3248
|
ticks.append(ticks[-1]+1)
|
|
3210
3249
|
self.plot_axes.set_xticks(ticks)
|
|
3211
|
-
lbls = self.plot_data_labels
|
|
3250
|
+
lbls = copy.copy(self.plot_data_labels)
|
|
3212
3251
|
lbls.insert(0, "")
|
|
3213
3252
|
lbls.append("")
|
|
3214
3253
|
self.plot_axes.set_xticklabels(lbls)
|
|
@@ -3227,6 +3266,13 @@ class PlotDialog(object):
|
|
|
3227
3266
|
sns.kdeplot({self.x_var.get(): self.dataset[0]}, x=self.x_var.get(), fill=True, ax=self.plot_axes)
|
|
3228
3267
|
self.plot_axes.set_xlabel(self.x_var.get())
|
|
3229
3268
|
self.plot_axes.set_ylabel("Density")
|
|
3269
|
+
elif plot_type == "Min-max plot":
|
|
3270
|
+
self.plot_axes.hlines(self.plot_data[0], self.plot_data[1], self.plot_data[2], linewidths=5.0)
|
|
3271
|
+
if self.xlog_ck["state"] != "disabled" and self.xlog_var.get() == "1":
|
|
3272
|
+
self.plot_axes.set_xlabel("Log10 of " + self.x_var.get())
|
|
3273
|
+
else:
|
|
3274
|
+
self.plot_axes.set_xlabel(self.x_var.get())
|
|
3275
|
+
self.plot_axes.set_ylabel(self.plot_data_labels[0])
|
|
3230
3276
|
elif plot_type == "Normal Q-Q plot":
|
|
3231
3277
|
if self.qq_groups:
|
|
3232
3278
|
self.plot_axes.scatter(self.plot_data[2], self.plot_data[1], c=self.plot_data[3], cmap="tab10")
|
|
@@ -3240,14 +3286,22 @@ class PlotDialog(object):
|
|
|
3240
3286
|
elif plot_type == "Y range plot":
|
|
3241
3287
|
self.plot_axes.fill_between(self.plot_data[0], self.plot_data[1], self.plot_data[2])
|
|
3242
3288
|
self.plot_axes.set_xlabel(self.x_var.get())
|
|
3243
|
-
self.
|
|
3289
|
+
if self.xlog_ck["state"] != "disabled" and self.xlog_var.get() == "1":
|
|
3290
|
+
self.plot_axes.set_xlabel("Log10 of " + self.x_var.get())
|
|
3291
|
+
else:
|
|
3292
|
+
self.plot_axes.set_xlabel(self.x_var.get())
|
|
3293
|
+
if self.ylog_ck["state"] != "disabled" and self.ylog_var.get() == "1":
|
|
3294
|
+
self.plot_axes.set_ylabel("Log10 of " + self.y_var.get())
|
|
3295
|
+
else:
|
|
3296
|
+
self.plot_axes.set_ylabel(self.y_var.get())
|
|
3244
3297
|
elif plot_type == "Box plot":
|
|
3245
3298
|
self.plot_axes.boxplot(self.plot_data, labels=self.plot_data_labels)
|
|
3246
3299
|
self.plot_axes.set_xlabel(self.x_var.get())
|
|
3247
3300
|
self.plot_axes.set_ylabel(self.data_labels[1])
|
|
3248
3301
|
elif plot_type == "Categorical KD plot":
|
|
3249
3302
|
sns.kdeplot({self.x_var.get(): self.dataset[0], self.y_var.get(): self.dataset[1]},
|
|
3250
|
-
x=self.y_var.get(), hue=self.x_var.get(), multiple="layer", fill=True, alpha=0.35, ax=self.plot_axes
|
|
3303
|
+
x=self.y_var.get(), hue=self.x_var.get(), multiple="layer", fill=True, alpha=0.35, ax=self.plot_axes,
|
|
3304
|
+
warn_singular=False)
|
|
3251
3305
|
self.plot_axes.set_xlabel(self.y_var.get())
|
|
3252
3306
|
self.plot_axes.set_ylabel("Density")
|
|
3253
3307
|
elif plot_type == "Categorical stripchart":
|
|
@@ -5,7 +5,7 @@ with io.open('README.md', encoding='utf-8') as f:
|
|
|
5
5
|
long_description = f.read()
|
|
6
6
|
|
|
7
7
|
setuptools.setup(name='mapdata',
|
|
8
|
-
version='2.
|
|
8
|
+
version='2.12.0',
|
|
9
9
|
description="An interactive map and table explorer for geographic coordinates in a spreadsheet, CSV file, or database",
|
|
10
10
|
author='Dreas Nielsen',
|
|
11
11
|
author_email='dreas.nielsen@gmail.com',
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|