newsworthycharts 1.64.0__py3-none-any.whl → 1.65.0__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- newsworthycharts/__init__.py +1 -1
- newsworthycharts/categoricalchart.py +4 -0
- newsworthycharts/chart.py +29 -5
- newsworthycharts/lib/datalist.py +12 -0
- newsworthycharts/serialchart.py +7 -4
- {newsworthycharts-1.64.0.dist-info → newsworthycharts-1.65.0.dist-info}/METADATA +15 -2
- {newsworthycharts-1.64.0.dist-info → newsworthycharts-1.65.0.dist-info}/RECORD +10 -10
- {newsworthycharts-1.64.0.dist-info → newsworthycharts-1.65.0.dist-info}/LICENSE.txt +0 -0
- {newsworthycharts-1.64.0.dist-info → newsworthycharts-1.65.0.dist-info}/WHEEL +0 -0
- {newsworthycharts-1.64.0.dist-info → newsworthycharts-1.65.0.dist-info}/top_level.txt +0 -0
newsworthycharts/__init__.py
CHANGED
@@ -20,6 +20,10 @@ class CategoricalChart(Chart):
|
|
20
20
|
# Optional: specify a list of colors (for multiple datasets)
|
21
21
|
self.colors = None
|
22
22
|
|
23
|
+
@property
|
24
|
+
def values_will_be_stacked(self):
|
25
|
+
return self.stacked
|
26
|
+
|
23
27
|
def _add_pie_data(self):
|
24
28
|
if len(self.data) > 1:
|
25
29
|
raise ValueError("Pie chart takes one data series only.")
|
newsworthycharts/chart.py
CHANGED
@@ -527,20 +527,21 @@ class Chart(object):
|
|
527
527
|
|
528
528
|
ticks = self.value_axis.get_ticklabels()
|
529
529
|
ticks_ = [x for (i, x) in enumerate(ticks) if ticks[i - 1].get_text() != x.get_text()]
|
530
|
+
value_axis = "_y" if self.value_axis == self.ax.yaxis else "_x"
|
530
531
|
# remove non integer ticks
|
531
532
|
if self.decimals == 0:
|
532
|
-
y = [float(x
|
533
|
+
y = [float(getattr(x, value_axis)) for x in ticks]
|
533
534
|
if self.units == "percent":
|
534
|
-
y = [x for x in y if (x * 100).is_integer()]
|
535
|
+
y = [x for x in y if round(x * 100, 5).is_integer()]
|
535
536
|
else:
|
536
|
-
y = [x for x in y if x.is_integer()]
|
537
|
+
y = [x for x in y if round(x, 5).is_integer()]
|
537
538
|
self.value_axis.set_ticks(y)
|
538
539
|
# Remove duplicate y ticks (most should be gone as per above)
|
539
540
|
elif len(ticks_) == 2 and self.data:
|
540
541
|
# When only two ticks we want them on top and bottom
|
541
|
-
self.value_axis.set_ticks([float(ticks[0]
|
542
|
+
self.value_axis.set_ticks([float(getattr(ticks[0], value_axis)), self.data.max_val])
|
542
543
|
elif len(ticks_) < len(ticks):
|
543
|
-
y = [float(x
|
544
|
+
y = [float(getattr(x, value_axis)) for x in ticks_]
|
544
545
|
self.value_axis.set_ticks(y)
|
545
546
|
|
546
547
|
# Force a second tick if we ended up having just one
|
@@ -549,6 +550,20 @@ class Chart(object):
|
|
549
550
|
if len(ticks_) <= 1 and self.data:
|
550
551
|
self.value_axis.set_ticks([0, self.data.max_val])
|
551
552
|
|
553
|
+
# Special handling for stacked percents, where, we want to fix any rounding errors,
|
554
|
+
# to make sure value max is 100 %, and not something like 100.00000000000001 (which
|
555
|
+
# may cause an extra tick to show up
|
556
|
+
if self.units == "percent" and self.values_will_be_stacked:
|
557
|
+
max_val = max(self.data.stacked_values)
|
558
|
+
diff = abs(1 - max_val)
|
559
|
+
_decimals = self.decimals if self.decimals is not None else 2
|
560
|
+
if diff < (pow(10, -_decimals) / 100): # 0.01 / 100 for 2 decimals, etc
|
561
|
+
value_lim = self.ax.get_ylim() if value_axis == "_y" else self.ax.get_xlim()
|
562
|
+
if value_axis == "_y":
|
563
|
+
self.ax.set_ylim(value_lim[0], 1)
|
564
|
+
else:
|
565
|
+
self.ax.set_xlim(value_lim[0], 1)
|
566
|
+
|
552
567
|
for a in self.annotations:
|
553
568
|
self._annotate_point(a["text"], a["xy"], a["direction"])
|
554
569
|
if self.ylabel is not None:
|
@@ -793,6 +808,15 @@ class Chart(object):
|
|
793
808
|
def units(self):
|
794
809
|
return self._units
|
795
810
|
|
811
|
+
@property
|
812
|
+
def values_will_be_stacked(self):
|
813
|
+
"""
|
814
|
+
Are the values from more than one dataseries going to be stacked or grouped together,
|
815
|
+
e.g. a stacked barchart?
|
816
|
+
This is used to to sanitize the value axis, and work around rounding errors.
|
817
|
+
"""
|
818
|
+
return False
|
819
|
+
|
796
820
|
@units.setter
|
797
821
|
def units(self, val: str):
|
798
822
|
""" Units, used for number formatting. Note that 'degrees' is designed
|
newsworthycharts/lib/datalist.py
CHANGED
@@ -184,6 +184,18 @@ class DataSet(MutableSequence):
|
|
184
184
|
self.max_val = max(self.max_val, max(values))
|
185
185
|
return v
|
186
186
|
|
187
|
+
@property
|
188
|
+
def values(self):
|
189
|
+
""" Return values from each data serie """
|
190
|
+
return [[to_float(x[1]) for x in s] for s in self.list]
|
191
|
+
|
192
|
+
@property
|
193
|
+
def stacked_values(self):
|
194
|
+
"""Returns the sum of all y values in each x """
|
195
|
+
# converts None to np.na for np.sum()
|
196
|
+
values = array(self.values, dtype=float)
|
197
|
+
return np.nansum(values, axis=0).tolist()
|
198
|
+
|
187
199
|
def __len__(self):
|
188
200
|
return len(self.list)
|
189
201
|
|
newsworthycharts/serialchart.py
CHANGED
@@ -143,6 +143,10 @@ class SerialChart(Chart):
|
|
143
143
|
return "down"
|
144
144
|
return "up"
|
145
145
|
|
146
|
+
@property
|
147
|
+
def values_will_be_stacked(self):
|
148
|
+
return (len(self.data) > 1) and all([t == "bars" for t in self.type])
|
149
|
+
|
146
150
|
def _add_data(self):
|
147
151
|
|
148
152
|
series = self.data
|
@@ -150,7 +154,6 @@ class SerialChart(Chart):
|
|
150
154
|
# For backwards compatibility: Convert type = "line" -> type = ["line"]
|
151
155
|
if type(self.type) is str:
|
152
156
|
self.type = [self.type] * len(series)
|
153
|
-
is_stacked = (len(series) > 1) and all([t == "bars" for t in self.type])
|
154
157
|
|
155
158
|
if self.allow_broken_y_axis is None:
|
156
159
|
if "bars" in self.type:
|
@@ -323,7 +326,7 @@ class SerialChart(Chart):
|
|
323
326
|
hl_color_for_series = self._nwc_style["strong_color"]
|
324
327
|
elif i == 0:
|
325
328
|
base_color_for_series = self._nwc_style["strong_color"]
|
326
|
-
elif
|
329
|
+
elif self.values_will_be_stacked:
|
327
330
|
hl_color_for_series = self._nwc_style["strong_color"]
|
328
331
|
base_color_for_series = self._nwc_style["qualitative_colors"][i]
|
329
332
|
else:
|
@@ -370,7 +373,7 @@ class SerialChart(Chart):
|
|
370
373
|
# bar_kwargs["edgecolor"] = "white"
|
371
374
|
# bar_kwargs["linewidth"] = 0 # 1
|
372
375
|
|
373
|
-
if
|
376
|
+
if self.values_will_be_stacked and i > 0:
|
374
377
|
if self.baseline != 0:
|
375
378
|
raise Exception("Setting a baseline is not supported for stacked bars")
|
376
379
|
# To make stacked bars we need to set bottom value
|
@@ -545,7 +548,7 @@ class SerialChart(Chart):
|
|
545
548
|
ymax = self.ymax
|
546
549
|
padding_top = 0
|
547
550
|
else:
|
548
|
-
if
|
551
|
+
if self.values_will_be_stacked:
|
549
552
|
ymax = self.data.stacked_max_val
|
550
553
|
else:
|
551
554
|
ymax = self.data.max_val + self.baseline
|
@@ -1,9 +1,9 @@
|
|
1
1
|
Metadata-Version: 2.1
|
2
2
|
Name: newsworthycharts
|
3
|
-
Version: 1.
|
3
|
+
Version: 1.65.0
|
4
4
|
Summary: Matplotlib wrapper to create charts and publish them on Amazon S3
|
5
5
|
Home-page: https://github.com/jplusplus/newsworthycharts
|
6
|
-
Download-URL: https://github.com/jplusplus/newsworthycharts/archive/1.
|
6
|
+
Download-URL: https://github.com/jplusplus/newsworthycharts/archive/1.65.0.tar.gz
|
7
7
|
Author: Jens Finnäs and Leo Wallentin, J++ Stockholm
|
8
8
|
Author-email: stockholm@jplusplus.org
|
9
9
|
License: MIT
|
@@ -214,6 +214,10 @@ _ Inherits from Map _
|
|
214
214
|
|
215
215
|
**ProgressChart**
|
216
216
|
|
217
|
+
_ Inherits from CategoricalChart _
|
218
|
+
|
219
|
+
- `target` = None # A target value to compare to, often 1 (when using percentages)
|
220
|
+
|
217
221
|
**RangePlot**
|
218
222
|
|
219
223
|
**ScatterPlot**
|
@@ -255,6 +259,15 @@ Roadmap
|
|
255
259
|
Changelog
|
256
260
|
---------
|
257
261
|
|
262
|
+
- 1.65.0
|
263
|
+
|
264
|
+
- Stacked data with percentages summing to very close to 100 % will now be treated as 100 %, assuming rounding error artifacts
|
265
|
+
|
266
|
+
- 1.64.1
|
267
|
+
|
268
|
+
- Fixed assumption about y axis being the value axis in tick cleaning
|
269
|
+
- Fix floating point bug in label handling, causing some integer labels to disappear when decimals=0
|
270
|
+
|
258
271
|
- 1.64.0
|
259
272
|
|
260
273
|
- Improved handling of value axis in categorical charts
|
@@ -1,14 +1,14 @@
|
|
1
|
-
newsworthycharts/__init__.py,sha256=
|
1
|
+
newsworthycharts/__init__.py,sha256=Tw-zK6IN6hHkpecyNWQX_D5QGNkeEVkRxRzIx6pRIH8,1160
|
2
2
|
newsworthycharts/bubblemap.py,sha256=nkocWmpiFgfjEuJGAsthjY5X7Q56jXWsZHUGXw4PwgE,2587
|
3
|
-
newsworthycharts/categoricalchart.py,sha256=
|
4
|
-
newsworthycharts/chart.py,sha256=
|
3
|
+
newsworthycharts/categoricalchart.py,sha256=TySDZf6EfG1fMk7uv2-5aJjjvQRco2YslmH6f05euyk,15729
|
4
|
+
newsworthycharts/chart.py,sha256=y-OjOcFYL4YaqgJEdUyqN6sAqk-8a0wOz5vjktRCr6E,34170
|
5
5
|
newsworthycharts/choroplethmap.py,sha256=bCLf4kcchp1C2djg5AxcOM8BdbaMj0xg7UHrZsDafhI,8013
|
6
6
|
newsworthycharts/datawrapper.py,sha256=RRkAVTpfP4updKxUIBaSmKuBi2RUVPaBRF8HDQhlGGA,11250
|
7
7
|
newsworthycharts/map.py,sha256=c409jEO4L8Yr780sJRC0RchR44roAlgOUDAkuk1SfRg,6057
|
8
8
|
newsworthycharts/rangeplot.py,sha256=NE1W9TnmlpK6T3RvBJOU3nd73EXqkj17OY9i5zlw_cQ,8366
|
9
9
|
newsworthycharts/scatterplot.py,sha256=l2w2JkA_4WzxQG9XG1Pn62IlJOdCMm1VemMiZL0rEfU,4959
|
10
10
|
newsworthycharts/seasonalchart.py,sha256=rr55yqJUkaYDR9Ik98jes6574oY1U8t8LwoLE3gClW4,1967
|
11
|
-
newsworthycharts/serialchart.py,sha256=
|
11
|
+
newsworthycharts/serialchart.py,sha256=_TBZiOyU-TtnnkJGbP4yZcTlypdIpbxHK4AjE4Su3k8,27787
|
12
12
|
newsworthycharts/storage.py,sha256=myERhlpvXyExXxUByBq9eW1bWkCyfH9SwTZbsWSyy3Q,4301
|
13
13
|
newsworthycharts/stripechart.py,sha256=9B6PX2MyLuKNQ8W0OGdKbP0-U32kju0K_NHHwwz_J68,1547
|
14
14
|
newsworthycharts/custom/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
@@ -16,7 +16,7 @@ newsworthycharts/custom/climate_cars.py,sha256=WyNLgjgRCv_zRrzVuk_BmcigFSzpzudjE
|
|
16
16
|
newsworthycharts/lib/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
17
17
|
newsworthycharts/lib/color_fn.py,sha256=ck65GzTS9oPgHUCnKDwX2z8zlnNyzncw97MmhXwi8z8,1282
|
18
18
|
newsworthycharts/lib/colors.py,sha256=U04TDkvoMQkcldRFXfnwyLOTwq1SWW2se-Ad-DNcw9o,485
|
19
|
-
newsworthycharts/lib/datalist.py,sha256=
|
19
|
+
newsworthycharts/lib/datalist.py,sha256=rO7kA0-waYOLMj4AqcksjPWBmn3q1cPyV0xxEUqkukA,6206
|
20
20
|
newsworthycharts/lib/formatter.py,sha256=GNH43hE0bC17OgiV8LYH3YUrEhm7OJh9XzfSV4HVtHo,4838
|
21
21
|
newsworthycharts/lib/geography.py,sha256=K0_teFmuPJwXX7Py-amJB_1YY5_gL2kBYhz1LrRCyTg,584
|
22
22
|
newsworthycharts/lib/locator.py,sha256=rJHdgiA0LASRzdLINhTeU5zOoq1TCMgge4KOBWSagnM,3041
|
@@ -28,8 +28,8 @@ newsworthycharts/rc/newsworthy,sha256=vbYTav1w3DmB5tpaaV7Xl5q7TQJsc9eou6pLCoWc2v
|
|
28
28
|
newsworthycharts/translations/datawrapper_regions.csv,sha256=fzZcQRX6RFMlNNP8mpgfYNdR3Y0QAlQxDXk8FXTaWWI,9214
|
29
29
|
newsworthycharts/translations/regions.py,sha256=Nv1McQjggD4S3JRu82rDMTG3pqUVR13E5-FBpSYbm98,239
|
30
30
|
newsworthycharts/translations/se_municipalities.csv,sha256=br_mm-IvzQtj_W55_ATREhJ97jWnCweBFlDAVY2EBxA,7098
|
31
|
-
newsworthycharts-1.
|
32
|
-
newsworthycharts-1.
|
33
|
-
newsworthycharts-1.
|
34
|
-
newsworthycharts-1.
|
35
|
-
newsworthycharts-1.
|
31
|
+
newsworthycharts-1.65.0.dist-info/LICENSE.txt,sha256=Sq6kGICrehbhC_FolNdXf0djKjTpv3YqjFCIYsxdQN4,1069
|
32
|
+
newsworthycharts-1.65.0.dist-info/METADATA,sha256=5daaEv6MGlSO7H4Z6ELkNTuMMc38LfL-P3OeRVOvM_o,30673
|
33
|
+
newsworthycharts-1.65.0.dist-info/WHEEL,sha256=cVxcB9AmuTcXqmwrtPhNK88dr7IR_b6qagTj0UvIEbY,91
|
34
|
+
newsworthycharts-1.65.0.dist-info/top_level.txt,sha256=dn_kzIj8UgUCMsh1PHdVEQJHVGSsN7Z8YJF-8xXa8n0,17
|
35
|
+
newsworthycharts-1.65.0.dist-info/RECORD,,
|
File without changes
|
File without changes
|
File without changes
|