newsworthycharts 1.64.0__tar.gz → 1.65.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 (51) hide show
  1. {newsworthycharts-1.64.0/newsworthycharts.egg-info → newsworthycharts-1.65.0}/PKG-INFO +15 -2
  2. {newsworthycharts-1.64.0 → newsworthycharts-1.65.0}/README.rst +13 -0
  3. {newsworthycharts-1.64.0 → newsworthycharts-1.65.0}/newsworthycharts/__init__.py +1 -1
  4. {newsworthycharts-1.64.0 → newsworthycharts-1.65.0}/newsworthycharts/categoricalchart.py +4 -0
  5. {newsworthycharts-1.64.0 → newsworthycharts-1.65.0}/newsworthycharts/chart.py +29 -5
  6. {newsworthycharts-1.64.0 → newsworthycharts-1.65.0}/newsworthycharts/lib/datalist.py +12 -0
  7. {newsworthycharts-1.64.0 → newsworthycharts-1.65.0}/newsworthycharts/serialchart.py +7 -4
  8. {newsworthycharts-1.64.0 → newsworthycharts-1.65.0/newsworthycharts.egg-info}/PKG-INFO +15 -2
  9. {newsworthycharts-1.64.0 → newsworthycharts-1.65.0}/LICENSE.txt +0 -0
  10. {newsworthycharts-1.64.0 → newsworthycharts-1.65.0}/MANIFEST.in +0 -0
  11. {newsworthycharts-1.64.0 → newsworthycharts-1.65.0}/newsworthycharts/bubblemap.py +0 -0
  12. {newsworthycharts-1.64.0 → newsworthycharts-1.65.0}/newsworthycharts/choroplethmap.py +0 -0
  13. {newsworthycharts-1.64.0 → newsworthycharts-1.65.0}/newsworthycharts/custom/__init__.py +0 -0
  14. {newsworthycharts-1.64.0 → newsworthycharts-1.65.0}/newsworthycharts/custom/climate_cars.py +0 -0
  15. {newsworthycharts-1.64.0 → newsworthycharts-1.65.0}/newsworthycharts/datawrapper.py +0 -0
  16. {newsworthycharts-1.64.0 → newsworthycharts-1.65.0}/newsworthycharts/lib/__init__.py +0 -0
  17. {newsworthycharts-1.64.0 → newsworthycharts-1.65.0}/newsworthycharts/lib/color_fn.py +0 -0
  18. {newsworthycharts-1.64.0 → newsworthycharts-1.65.0}/newsworthycharts/lib/colors.py +0 -0
  19. {newsworthycharts-1.64.0 → newsworthycharts-1.65.0}/newsworthycharts/lib/formatter.py +0 -0
  20. {newsworthycharts-1.64.0 → newsworthycharts-1.65.0}/newsworthycharts/lib/geography.py +0 -0
  21. {newsworthycharts-1.64.0 → newsworthycharts-1.65.0}/newsworthycharts/lib/locator.py +0 -0
  22. {newsworthycharts-1.64.0 → newsworthycharts-1.65.0}/newsworthycharts/lib/mimetypes.py +0 -0
  23. {newsworthycharts-1.64.0 → newsworthycharts-1.65.0}/newsworthycharts/lib/utils.py +0 -0
  24. {newsworthycharts-1.64.0 → newsworthycharts-1.65.0}/newsworthycharts/map.py +0 -0
  25. {newsworthycharts-1.64.0 → newsworthycharts-1.65.0}/newsworthycharts/maps/se-4.gpkg +0 -0
  26. {newsworthycharts-1.64.0 → newsworthycharts-1.65.0}/newsworthycharts/maps/se-7.gpkg +0 -0
  27. {newsworthycharts-1.64.0 → newsworthycharts-1.65.0}/newsworthycharts/rangeplot.py +0 -0
  28. {newsworthycharts-1.64.0 → newsworthycharts-1.65.0}/newsworthycharts/rc/newsworthy +0 -0
  29. {newsworthycharts-1.64.0 → newsworthycharts-1.65.0}/newsworthycharts/scatterplot.py +0 -0
  30. {newsworthycharts-1.64.0 → newsworthycharts-1.65.0}/newsworthycharts/seasonalchart.py +0 -0
  31. {newsworthycharts-1.64.0 → newsworthycharts-1.65.0}/newsworthycharts/storage.py +0 -0
  32. {newsworthycharts-1.64.0 → newsworthycharts-1.65.0}/newsworthycharts/stripechart.py +0 -0
  33. {newsworthycharts-1.64.0 → newsworthycharts-1.65.0}/newsworthycharts/translations/datawrapper_regions.csv +0 -0
  34. {newsworthycharts-1.64.0 → newsworthycharts-1.65.0}/newsworthycharts/translations/regions.py +0 -0
  35. {newsworthycharts-1.64.0 → newsworthycharts-1.65.0}/newsworthycharts/translations/se_municipalities.csv +0 -0
  36. {newsworthycharts-1.64.0 → newsworthycharts-1.65.0}/newsworthycharts.egg-info/SOURCES.txt +0 -0
  37. {newsworthycharts-1.64.0 → newsworthycharts-1.65.0}/newsworthycharts.egg-info/dependency_links.txt +0 -0
  38. {newsworthycharts-1.64.0 → newsworthycharts-1.65.0}/newsworthycharts.egg-info/not-zip-safe +0 -0
  39. {newsworthycharts-1.64.0 → newsworthycharts-1.65.0}/newsworthycharts.egg-info/requires.txt +0 -0
  40. {newsworthycharts-1.64.0 → newsworthycharts-1.65.0}/newsworthycharts.egg-info/top_level.txt +0 -0
  41. {newsworthycharts-1.64.0 → newsworthycharts-1.65.0}/setup.cfg +0 -0
  42. {newsworthycharts-1.64.0 → newsworthycharts-1.65.0}/setup.py +0 -0
  43. {newsworthycharts-1.64.0 → newsworthycharts-1.65.0}/test/test_categorical_chart.py +0 -0
  44. {newsworthycharts-1.64.0 → newsworthycharts-1.65.0}/test/test_choropleth_maps.py +0 -0
  45. {newsworthycharts-1.64.0 → newsworthycharts-1.65.0}/test/test_custom_climate_cars.py +0 -0
  46. {newsworthycharts-1.64.0 → newsworthycharts-1.65.0}/test/test_data_list.py +0 -0
  47. {newsworthycharts-1.64.0 → newsworthycharts-1.65.0}/test/test_datawrapper.py +0 -0
  48. {newsworthycharts-1.64.0 → newsworthycharts-1.65.0}/test/test_main.py +0 -0
  49. {newsworthycharts-1.64.0 → newsworthycharts-1.65.0}/test/test_rangeplot.py +0 -0
  50. {newsworthycharts-1.64.0 → newsworthycharts-1.65.0}/test/test_scatterplot.py +0 -0
  51. {newsworthycharts-1.64.0 → newsworthycharts-1.65.0}/test/test_serial_chart.py +0 -0
@@ -1,9 +1,9 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: newsworthycharts
3
- Version: 1.64.0
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.64.0.tar.gz
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
@@ -187,6 +187,10 @@ _ Inherits from Map _
187
187
 
188
188
  **ProgressChart**
189
189
 
190
+ _ Inherits from CategoricalChart _
191
+
192
+ - `target` = None # A target value to compare to, often 1 (when using percentages)
193
+
190
194
  **RangePlot**
191
195
 
192
196
  **ScatterPlot**
@@ -228,6 +232,15 @@ Roadmap
228
232
  Changelog
229
233
  ---------
230
234
 
235
+ - 1.65.0
236
+
237
+ - Stacked data with percentages summing to very close to 100 % will now be treated as 100 %, assuming rounding error artifacts
238
+
239
+ - 1.64.1
240
+
241
+ - Fixed assumption about y axis being the value axis in tick cleaning
242
+ - Fix floating point bug in label handling, causing some integer labels to disappear when decimals=0
243
+
231
244
  - 1.64.0
232
245
 
233
246
  - Improved handling of value axis in categorical charts
@@ -1,4 +1,4 @@
1
- __version__ = "1.64.0"
1
+ __version__ = "1.65.0"
2
2
 
3
3
  from .chart import Chart
4
4
  from .choroplethmap import ChoroplethMap
@@ -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.")
@@ -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._y) for x in ticks]
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]._y), self.data.max_val])
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._y) for x in ticks_]
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
@@ -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
 
@@ -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 is_stacked:
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 is_stacked and i > 0:
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 is_stacked:
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.64.0
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.64.0.tar.gz
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