newsworthycharts 1.72.0__tar.gz → 1.73.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 (52) hide show
  1. {newsworthycharts-1.72.0/newsworthycharts.egg-info → newsworthycharts-1.73.0}/PKG-INFO +15 -4
  2. {newsworthycharts-1.72.0 → newsworthycharts-1.73.0}/README.rst +12 -1
  3. {newsworthycharts-1.72.0 → newsworthycharts-1.73.0}/newsworthycharts/__init__.py +1 -1
  4. {newsworthycharts-1.72.0 → newsworthycharts-1.73.0}/newsworthycharts/chart.py +7 -1
  5. {newsworthycharts-1.72.0 → newsworthycharts-1.73.0}/newsworthycharts/lib/utils.py +4 -0
  6. {newsworthycharts-1.72.0 → newsworthycharts-1.73.0}/newsworthycharts/serialchart.py +75 -39
  7. {newsworthycharts-1.72.0 → newsworthycharts-1.73.0/newsworthycharts.egg-info}/PKG-INFO +15 -4
  8. {newsworthycharts-1.72.0 → newsworthycharts-1.73.0}/newsworthycharts.egg-info/requires.txt +1 -1
  9. {newsworthycharts-1.72.0 → newsworthycharts-1.73.0}/setup.py +1 -1
  10. {newsworthycharts-1.72.0 → newsworthycharts-1.73.0}/LICENSE.txt +0 -0
  11. {newsworthycharts-1.72.0 → newsworthycharts-1.73.0}/MANIFEST.in +0 -0
  12. {newsworthycharts-1.72.0 → newsworthycharts-1.73.0}/newsworthycharts/bubblemap.py +0 -0
  13. {newsworthycharts-1.72.0 → newsworthycharts-1.73.0}/newsworthycharts/categoricalchart.py +0 -0
  14. {newsworthycharts-1.72.0 → newsworthycharts-1.73.0}/newsworthycharts/choroplethmap.py +0 -0
  15. {newsworthycharts-1.72.0 → newsworthycharts-1.73.0}/newsworthycharts/custom/__init__.py +0 -0
  16. {newsworthycharts-1.72.0 → newsworthycharts-1.73.0}/newsworthycharts/custom/climate_cars.py +0 -0
  17. {newsworthycharts-1.72.0 → newsworthycharts-1.73.0}/newsworthycharts/datawrapper.py +0 -0
  18. {newsworthycharts-1.72.0 → newsworthycharts-1.73.0}/newsworthycharts/lib/__init__.py +0 -0
  19. {newsworthycharts-1.72.0 → newsworthycharts-1.73.0}/newsworthycharts/lib/color_fn.py +0 -0
  20. {newsworthycharts-1.72.0 → newsworthycharts-1.73.0}/newsworthycharts/lib/colors.py +0 -0
  21. {newsworthycharts-1.72.0 → newsworthycharts-1.73.0}/newsworthycharts/lib/datalist.py +0 -0
  22. {newsworthycharts-1.72.0 → newsworthycharts-1.73.0}/newsworthycharts/lib/formatter.py +0 -0
  23. {newsworthycharts-1.72.0 → newsworthycharts-1.73.0}/newsworthycharts/lib/geography.py +0 -0
  24. {newsworthycharts-1.72.0 → newsworthycharts-1.73.0}/newsworthycharts/lib/locator.py +0 -0
  25. {newsworthycharts-1.72.0 → newsworthycharts-1.73.0}/newsworthycharts/lib/mimetypes.py +0 -0
  26. {newsworthycharts-1.72.0 → newsworthycharts-1.73.0}/newsworthycharts/map.py +0 -0
  27. {newsworthycharts-1.72.0 → newsworthycharts-1.73.0}/newsworthycharts/maps/se-4.gpkg +0 -0
  28. {newsworthycharts-1.72.0 → newsworthycharts-1.73.0}/newsworthycharts/maps/se-7.gpkg +0 -0
  29. {newsworthycharts-1.72.0 → newsworthycharts-1.73.0}/newsworthycharts/rangeplot.py +0 -0
  30. {newsworthycharts-1.72.0 → newsworthycharts-1.73.0}/newsworthycharts/rankchart.py +0 -0
  31. {newsworthycharts-1.72.0 → newsworthycharts-1.73.0}/newsworthycharts/rc/newsworthy +0 -0
  32. {newsworthycharts-1.72.0 → newsworthycharts-1.73.0}/newsworthycharts/scatterplot.py +0 -0
  33. {newsworthycharts-1.72.0 → newsworthycharts-1.73.0}/newsworthycharts/seasonalchart.py +0 -0
  34. {newsworthycharts-1.72.0 → newsworthycharts-1.73.0}/newsworthycharts/storage.py +0 -0
  35. {newsworthycharts-1.72.0 → newsworthycharts-1.73.0}/newsworthycharts/stripechart.py +0 -0
  36. {newsworthycharts-1.72.0 → newsworthycharts-1.73.0}/newsworthycharts/translations/datawrapper_regions.csv +0 -0
  37. {newsworthycharts-1.72.0 → newsworthycharts-1.73.0}/newsworthycharts/translations/regions.py +0 -0
  38. {newsworthycharts-1.72.0 → newsworthycharts-1.73.0}/newsworthycharts/translations/se_municipalities.csv +0 -0
  39. {newsworthycharts-1.72.0 → newsworthycharts-1.73.0}/newsworthycharts.egg-info/SOURCES.txt +0 -0
  40. {newsworthycharts-1.72.0 → newsworthycharts-1.73.0}/newsworthycharts.egg-info/dependency_links.txt +0 -0
  41. {newsworthycharts-1.72.0 → newsworthycharts-1.73.0}/newsworthycharts.egg-info/not-zip-safe +0 -0
  42. {newsworthycharts-1.72.0 → newsworthycharts-1.73.0}/newsworthycharts.egg-info/top_level.txt +0 -0
  43. {newsworthycharts-1.72.0 → newsworthycharts-1.73.0}/setup.cfg +0 -0
  44. {newsworthycharts-1.72.0 → newsworthycharts-1.73.0}/test/test_categorical_chart.py +0 -0
  45. {newsworthycharts-1.72.0 → newsworthycharts-1.73.0}/test/test_choropleth_maps.py +0 -0
  46. {newsworthycharts-1.72.0 → newsworthycharts-1.73.0}/test/test_custom_climate_cars.py +0 -0
  47. {newsworthycharts-1.72.0 → newsworthycharts-1.73.0}/test/test_data_list.py +0 -0
  48. {newsworthycharts-1.72.0 → newsworthycharts-1.73.0}/test/test_datawrapper.py +0 -0
  49. {newsworthycharts-1.72.0 → newsworthycharts-1.73.0}/test/test_main.py +0 -0
  50. {newsworthycharts-1.72.0 → newsworthycharts-1.73.0}/test/test_rangeplot.py +0 -0
  51. {newsworthycharts-1.72.0 → newsworthycharts-1.73.0}/test/test_scatterplot.py +0 -0
  52. {newsworthycharts-1.72.0 → newsworthycharts-1.73.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.72.0
3
+ Version: 1.73.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.72.0.tar.gz
6
+ Download-URL: https://github.com/jplusplus/newsworthycharts/archive/1.73.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
@@ -18,7 +18,7 @@ Requires-Dist: PyYAML>=3
18
18
  Requires-Dist: adjustText==1.3.0
19
19
  Requires-Dist: numpy>2
20
20
  Requires-Dist: python-dateutil<3,>=2
21
- Requires-Dist: Pillow==11.1.0
21
+ Requires-Dist: Pillow==11.2.1
22
22
  Requires-Dist: requests>=2.22
23
23
  Requires-Dist: matplotlib-label-lines==0.5.1
24
24
  Requires-Dist: geopandas==1.0.1
@@ -154,7 +154,7 @@ These settings are available for all chart types:
154
154
 
155
155
  **SerialChart**
156
156
 
157
- - type = 'line' # line|bars, or a list of types for each data serie
157
+ - type = 'line' # line|bars|markers, or a list of types for each data serie
158
158
  - bar_width = 0.9 # percent of data point width
159
159
  - allow_broken_y_axis = True|False # default depends on chart type
160
160
  - baseline = 0 # The “zero” line. Useful for plotting deviations, e.g. temperatures above/below mean
@@ -271,6 +271,17 @@ Roadmap
271
271
  Changelog
272
272
  ---------
273
273
 
274
+ - 1.73.0
275
+
276
+ - Add `type: "markers"` to serial charts. Uses a thin line with a marker at each data point as default.
277
+ - Make sure `baseline` goes behind lines in serial charts
278
+ - Make sure baseline annotation goes above lines in serial charts
279
+
280
+ - 1.72.1
281
+
282
+ - Better interval detection in SerialChart when years are all in different decades
283
+ - Pillow==11.2.0
284
+
274
285
  - 1.72.0
275
286
 
276
287
  - Use gradient legend för continuous choropleth maps
@@ -128,7 +128,7 @@ These settings are available for all chart types:
128
128
 
129
129
  **SerialChart**
130
130
 
131
- - type = 'line' # line|bars, or a list of types for each data serie
131
+ - type = 'line' # line|bars|markers, or a list of types for each data serie
132
132
  - bar_width = 0.9 # percent of data point width
133
133
  - allow_broken_y_axis = True|False # default depends on chart type
134
134
  - baseline = 0 # The “zero” line. Useful for plotting deviations, e.g. temperatures above/below mean
@@ -245,6 +245,17 @@ Roadmap
245
245
  Changelog
246
246
  ---------
247
247
 
248
+ - 1.73.0
249
+
250
+ - Add `type: "markers"` to serial charts. Uses a thin line with a marker at each data point as default.
251
+ - Make sure `baseline` goes behind lines in serial charts
252
+ - Make sure baseline annotation goes above lines in serial charts
253
+
254
+ - 1.72.1
255
+
256
+ - Better interval detection in SerialChart when years are all in different decades
257
+ - Pillow==11.2.0
258
+
248
259
  - 1.72.0
249
260
 
250
261
  - Use gradient legend för continuous choropleth maps
@@ -1,4 +1,4 @@
1
- __version__ = "1.72.0"
1
+ __version__ = "1.73.0"
2
2
 
3
3
  from .chart import Chart
4
4
  from .choroplethmap import ChoroplethMap
@@ -776,7 +776,13 @@ class Chart(object):
776
776
  'Creator': f"NWCharts {__version__}",
777
777
  }
778
778
  """
779
-
779
+ """
780
+ if img_format == "avif":
781
+ from matplotlib.animation import FuncAnimation, PillowWriter
782
+ ani = FuncAnimation(self._fig, lambda x: [], frames=[0], blit=True)
783
+ ani.save(buf, writer=PillowWriter(fps=1), dpi=self._fig.dpi * factor)
784
+ else:
785
+ """
780
786
  self._fig.savefig(buf, **args) # , bbox_inches="tight")
781
787
  buf.seek(0)
782
788
  self._storage.save(key, buf, img_format, storage_options)
@@ -172,6 +172,10 @@ def guess_date_interval(data):
172
172
  # Are there decades with more than one year?
173
173
  if len(set(years)) > len(set(decades)):
174
174
  interval = "yearly"
175
+ # Are years from different parts of the decade?
176
+ last_digits = [x % 10 for x in years]
177
+ if len(set(last_digits)) > 1:
178
+ interval = "yearly"
175
179
 
176
180
  months = [x.month for x in dates]
177
181
  yearmonths = [x.strftime("%Y-%m") for x in dates]
@@ -37,7 +37,7 @@ class SerialChart(Chart):
37
37
 
38
38
  self.grid = True
39
39
  self.point_marker = "."
40
- self.line_marker = "-"
40
+ self.line_marker = None
41
41
  self.line_marker_size = 3
42
42
 
43
43
  self.max_ticks = 10
@@ -234,16 +234,26 @@ class SerialChart(Chart):
234
234
  highlight_value)
235
235
  highlight_diff['y1'] = max(highlight_diff['y1'],
236
236
  highlight_value)
237
- if self.type[i] == "line":
237
+ if self.type[i] in ["line", "markers"]:
238
238
  # Put first series on top
239
239
  zo = len(series) - i + 1
240
240
  zo += 10 # Make sure lines are on top of bars
241
241
 
242
- if self.line_width is None:
243
- lw = self._nwc_style.get("lines.linewidth", 2)
242
+ lw = self.line_width
243
+ mz = self.line_marker_size
244
+ lm = self.line_marker
245
+ if self.type[i] == "markers":
246
+ if lm is None:
247
+ lm = "o"
248
+ if lw is None:
249
+ lw = self._nwc_style.get("lines.linewidth", 2) / 2
250
+ mz *= 3
244
251
  else:
245
- lw = self.line_width
246
-
252
+ if lm is None:
253
+ lm = "-"
254
+ if lw is None:
255
+ lw = self._nwc_style.get("lines.linewidth", 2)
256
+
247
257
  if hasattr(self, "_get_line_colors"):
248
258
  # Hook for sub classes
249
259
  color = self._get_line_colors(i)
@@ -252,6 +262,9 @@ class SerialChart(Chart):
252
262
  color = self._nwc_style["qualitative_colors"][i]
253
263
  else:
254
264
  color = self.colors[i]
265
+ elif self.highlight in dates_str and self.type[i] == "markers":
266
+ # For markers, will will use a logic similar to bars
267
+ color = self._nwc_style["neutral_color"]
255
268
  elif i == 0:
256
269
  color = self._nwc_style["strong_color"]
257
270
  else:
@@ -263,44 +276,67 @@ class SerialChart(Chart):
263
276
  line, = self.ax.plot(
264
277
  dates,
265
278
  values,
266
- self.line_marker,
267
- markersize=self.line_marker_size,
279
+ lm,
280
+ markersize=mz,
268
281
  color=color,
269
282
  markerfacecolor=marker_fill,
270
283
  markeredgewidth=0,
271
284
  zorder=zo,
272
285
  lw=lw,
273
286
  )
274
- # Add single, orphaned data points as markers
275
- # None, 1, None, 1, 1, 1 => . ---
276
- num_values = len(values)
277
- if num_values == 1:
287
+ if self.highlight in dates_str and self.type[i] == "markers":
288
+ # Highlight specific date (Motplotlib has no better option than to overwrite the marker)
278
289
  self.ax.plot(
279
- dates[0],
280
- values[0],
281
- c=color,
282
- marker=self.point_marker,
283
- zorder=12,
290
+ highlight_date,
291
+ highlight_value,
292
+ c=self._nwc_style["strong_color"],
293
+ marker=lm,
294
+ markersize=mz,
295
+ markerfacecolor=marker_fill,
296
+ markeredgewidth=0,
297
+ zorder=zo + 1,
298
+ )
299
+
300
+ if self.type[i] == "markers":
301
+ # Join the dots with a line
302
+ self.ax.plot(
303
+ dates,
304
+ values,
305
+ color=color,
306
+ zorder=zo - 1,
307
+ lw=lw,
284
308
  )
285
- elif num_values > 1:
286
- for j, v in enumerate(values):
287
- def nullish(val):
288
- return val is None or np.isnan(val)
289
- plot_me = False
290
- if not nullish(v):
291
- if j == 0 and nullish(values[1]):
292
- plot_me = True
293
- elif j == num_values - 1 and nullish(values[j - 1]):
294
- plot_me = True
295
- elif nullish(values[j - 1]) and nullish(values[j + 1]):
296
- plot_me = True
297
- if plot_me:
298
- self.ax.plot(
299
- dates[j], v,
300
- c=color,
301
- marker=self.point_marker,
302
- zorder=12
303
- )
309
+ else:
310
+ # Add single, orphaned data points as markers
311
+ # None, 1, None, 1, 1, 1 => . ---
312
+ num_values = len(values)
313
+ if num_values == 1:
314
+ self.ax.plot(
315
+ dates[0],
316
+ values[0],
317
+ c=color,
318
+ marker=self.point_marker,
319
+ zorder=12,
320
+ )
321
+ elif num_values > 1:
322
+ for j, v in enumerate(values):
323
+ def nullish(val):
324
+ return val is None or np.isnan(val)
325
+ plot_me = False
326
+ if not nullish(v):
327
+ if j == 0 and nullish(values[1]):
328
+ plot_me = True
329
+ elif j == num_values - 1 and nullish(values[j - 1]):
330
+ plot_me = True
331
+ elif nullish(values[j - 1]) and nullish(values[j + 1]):
332
+ plot_me = True
333
+ if plot_me:
334
+ self.ax.plot(
335
+ dates[j], v,
336
+ c=color,
337
+ marker=self.point_marker,
338
+ zorder=12
339
+ )
304
340
 
305
341
  if len(self.labels) > i and any([x[1] for x in serie]):
306
342
  line.set_label(self.labels[i])
@@ -460,7 +496,7 @@ class SerialChart(Chart):
460
496
  dir = "up"
461
497
  else:
462
498
  dir = "down"
463
- if self.type[i] == "line":
499
+ if self.type[i] in ["line", "markers"]:
464
500
  if len(highlight_values) > 1:
465
501
  # When highlighting two values on the same point,
466
502
  # put them in opposite direction
@@ -519,7 +555,7 @@ class SerialChart(Chart):
519
555
  y=self.baseline,
520
556
  linewidth=1,
521
557
  color="#444444",
522
- zorder=11,
558
+ zorder=11 if "bars" in self.type else 9,
523
559
  linestyle="--" if self.baseline else "-",
524
560
  )
525
561
  if self.baseline_annotation:
@@ -531,7 +567,7 @@ class SerialChart(Chart):
531
567
  xy,
532
568
  direction="down" if first_val and first_val >= self.baseline else "up",
533
569
  color=self._nwc_style["neutral_color"],
534
- zorder=11,
570
+ zorder=12,
535
571
  )
536
572
 
537
573
  # Shade area between lines if there are exactly 2 series
@@ -1,9 +1,9 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: newsworthycharts
3
- Version: 1.72.0
3
+ Version: 1.73.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.72.0.tar.gz
6
+ Download-URL: https://github.com/jplusplus/newsworthycharts/archive/1.73.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
@@ -18,7 +18,7 @@ Requires-Dist: PyYAML>=3
18
18
  Requires-Dist: adjustText==1.3.0
19
19
  Requires-Dist: numpy>2
20
20
  Requires-Dist: python-dateutil<3,>=2
21
- Requires-Dist: Pillow==11.1.0
21
+ Requires-Dist: Pillow==11.2.1
22
22
  Requires-Dist: requests>=2.22
23
23
  Requires-Dist: matplotlib-label-lines==0.5.1
24
24
  Requires-Dist: geopandas==1.0.1
@@ -154,7 +154,7 @@ These settings are available for all chart types:
154
154
 
155
155
  **SerialChart**
156
156
 
157
- - type = 'line' # line|bars, or a list of types for each data serie
157
+ - type = 'line' # line|bars|markers, or a list of types for each data serie
158
158
  - bar_width = 0.9 # percent of data point width
159
159
  - allow_broken_y_axis = True|False # default depends on chart type
160
160
  - baseline = 0 # The “zero” line. Useful for plotting deviations, e.g. temperatures above/below mean
@@ -271,6 +271,17 @@ Roadmap
271
271
  Changelog
272
272
  ---------
273
273
 
274
+ - 1.73.0
275
+
276
+ - Add `type: "markers"` to serial charts. Uses a thin line with a marker at each data point as default.
277
+ - Make sure `baseline` goes behind lines in serial charts
278
+ - Make sure baseline annotation goes above lines in serial charts
279
+
280
+ - 1.72.1
281
+
282
+ - Better interval detection in SerialChart when years are all in different decades
283
+ - Pillow==11.2.0
284
+
274
285
  - 1.72.0
275
286
 
276
287
  - Use gradient legend för continuous choropleth maps
@@ -6,7 +6,7 @@ PyYAML>=3
6
6
  adjustText==1.3.0
7
7
  numpy>2
8
8
  python-dateutil<3,>=2
9
- Pillow==11.1.0
9
+ Pillow==11.2.1
10
10
  requests>=2.22
11
11
  matplotlib-label-lines==0.5.1
12
12
  geopandas==1.0.1
@@ -32,7 +32,7 @@ setup(
32
32
  "adjustText==1.3.0",
33
33
  "numpy>2",
34
34
  "python-dateutil>=2,<3",
35
- "Pillow==11.1.0",
35
+ "Pillow==11.2.1",
36
36
  "requests>=2.22",
37
37
  "matplotlib-label-lines==0.5.1",
38
38
  "geopandas==1.0.1",