newsworthycharts 1.70.1__py3-none-any.whl → 1.71.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 +3 -1
- newsworthycharts/chart.py +15 -1
- newsworthycharts/rankchart.py +35 -0
- newsworthycharts/serialchart.py +31 -14
- {newsworthycharts-1.70.1.dist-info → newsworthycharts-1.71.0.dist-info}/METADATA +16 -2
- {newsworthycharts-1.70.1.dist-info → newsworthycharts-1.71.0.dist-info}/RECORD +9 -8
- {newsworthycharts-1.70.1.dist-info → newsworthycharts-1.71.0.dist-info}/LICENSE.txt +0 -0
- {newsworthycharts-1.70.1.dist-info → newsworthycharts-1.71.0.dist-info}/WHEEL +0 -0
- {newsworthycharts-1.70.1.dist-info → newsworthycharts-1.71.0.dist-info}/top_level.txt +0 -0
newsworthycharts/__init__.py
CHANGED
@@ -1,10 +1,11 @@
|
|
1
|
-
__version__ = "1.
|
1
|
+
__version__ = "1.71.0"
|
2
2
|
|
3
3
|
from .chart import Chart
|
4
4
|
from .choroplethmap import ChoroplethMap
|
5
5
|
from .bubblemap import BubbleMap
|
6
6
|
from .serialchart import SerialChart
|
7
7
|
from .seasonalchart import SeasonalChart
|
8
|
+
from .rankchart import BumpChart
|
8
9
|
from .categoricalchart import CategoricalChart, CategoricalChartWithReference, ProgressChart
|
9
10
|
from .scatterplot import ScatterPlot
|
10
11
|
from .datawrapper import DatawrapperChart
|
@@ -26,6 +27,7 @@ CHART_ENGINES = {
|
|
26
27
|
"SeasonalChart": SeasonalChart,
|
27
28
|
"SerialChart": SerialChart,
|
28
29
|
"StripeChart": StripeChart,
|
30
|
+
"BumpChart": BumpChart,
|
29
31
|
|
30
32
|
# custom
|
31
33
|
"ClimateCarsYearlyEmissionsTo2030": ClimateCarsYearlyEmissionsTo2030,
|
newsworthycharts/chart.py
CHANGED
@@ -66,6 +66,7 @@ class Chart(object):
|
|
66
66
|
self.decimals = None
|
67
67
|
self.yline = None
|
68
68
|
self.type = None
|
69
|
+
self.revert_value_axis = False
|
69
70
|
# number of decimals to show in annotations, value ticks, etc
|
70
71
|
# None means automatically chose the best number
|
71
72
|
self.force_decimals = False
|
@@ -572,7 +573,7 @@ class Chart(object):
|
|
572
573
|
elif self.units == "percent":
|
573
574
|
# Cut y axis at 100 percent if not value is above
|
574
575
|
value_lim = self.ax.get_ylim() if value_axis == "_y" else self.ax.get_xlim()
|
575
|
-
if self.data.max_val
|
576
|
+
if self.data.max_val <= 1 and value_lim[1] > 1:
|
576
577
|
value_lim = self.ax.get_ylim() if value_axis == "_y" else self.ax.get_xlim()
|
577
578
|
if value_axis == "_y":
|
578
579
|
self.ax.set_ylim(value_lim[0], 1)
|
@@ -669,6 +670,19 @@ class Chart(object):
|
|
669
670
|
# print(sub_canvas_height, self._note_rel_height, self._footer_rel_height)
|
670
671
|
self._fig.subplots_adjust(bottom=sub_canvas_height)
|
671
672
|
|
673
|
+
if self.revert_value_axis:
|
674
|
+
if hasattr(self, "orientation") and self.orientation == "horizontal":
|
675
|
+
self.ax.invert_xaxis()
|
676
|
+
value_axis = self.ax.get_xaxis()
|
677
|
+
value_ticks = self.ax.get_xticks()
|
678
|
+
else:
|
679
|
+
self.ax.invert_yaxis()
|
680
|
+
value_axis = self.ax.get_yaxis()
|
681
|
+
value_ticks = self.ax.get_yticks()
|
682
|
+
value_ticks = [x for x in value_ticks if x <= self.data.max_val]
|
683
|
+
value_axis.set_ticks(value_ticks)
|
684
|
+
# self.ax.set_ylim(self.data.max_val, self.ymin)
|
685
|
+
|
672
686
|
@classmethod
|
673
687
|
def init_from(cls, args: dict, storage=LocalStorage(),
|
674
688
|
style: str="newsworthy", language: str='en-GB'):
|
@@ -0,0 +1,35 @@
|
|
1
|
+
"""
|
2
|
+
A chart showing ranking over time (like ”most popular baby names”)
|
3
|
+
"""
|
4
|
+
from .serialchart import SerialChart
|
5
|
+
|
6
|
+
|
7
|
+
class BumpChart(SerialChart):
|
8
|
+
"""Plot a rank chart
|
9
|
+
|
10
|
+
Data should be a list of iterables of (rank, date string) tuples, eg:
|
11
|
+
`[ [("2010-01-01", 2), ("2011-01-01", 3)] ]`, combined with a list of
|
12
|
+
labels in the same order
|
13
|
+
"""
|
14
|
+
|
15
|
+
def __init__(self, *args, **kwargs):
|
16
|
+
super(BumpChart, self).__init__(*args, **kwargs)
|
17
|
+
self.line_width = 0.5
|
18
|
+
self.label_placement = 'line'
|
19
|
+
self.type = "line"
|
20
|
+
self.decimals = 0
|
21
|
+
self.revert_value_axis = True
|
22
|
+
self.ymin = 1
|
23
|
+
self.allow_broken_y_axis = False
|
24
|
+
self.grid = False
|
25
|
+
self.line_marker = "o-"
|
26
|
+
|
27
|
+
def _get_line_colors(self, i, *args):
|
28
|
+
if not self.data:
|
29
|
+
# Don't waste time
|
30
|
+
return None
|
31
|
+
if self.highlight and self.highlight in self.labels and i == self.labels.index(self.highlight):
|
32
|
+
return self._nwc_style["strong_color"]
|
33
|
+
elif self.colors and i < len(self.colors):
|
34
|
+
return self.colors[i]
|
35
|
+
return self._nwc_style["neutral_color"]
|
newsworthycharts/serialchart.py
CHANGED
@@ -34,6 +34,10 @@ class SerialChart(Chart):
|
|
34
34
|
# Set with of lines explicitly (otherwise determined by style file)
|
35
35
|
self.line_width = None
|
36
36
|
|
37
|
+
self.grid = True
|
38
|
+
self.point_marker = "."
|
39
|
+
self.line_marker = "-"
|
40
|
+
|
37
41
|
self.max_ticks = 10
|
38
42
|
|
39
43
|
# Manually set tick locations and labels? Provide a list of tuples:
|
@@ -235,7 +239,10 @@ class SerialChart(Chart):
|
|
235
239
|
else:
|
236
240
|
lw = self.line_width
|
237
241
|
|
238
|
-
if self
|
242
|
+
if hasattr(self, "_get_line_colors"):
|
243
|
+
# Hook for sub classes
|
244
|
+
color = self._get_line_colors(i)
|
245
|
+
elif self.colors is not None:
|
239
246
|
if self.colors == "qualitative_colors":
|
240
247
|
color = self._nwc_style["qualitative_colors"][i]
|
241
248
|
else:
|
@@ -245,18 +252,26 @@ class SerialChart(Chart):
|
|
245
252
|
else:
|
246
253
|
color = self._nwc_style["neutral_color"]
|
247
254
|
|
248
|
-
line, = self.ax.plot(
|
249
|
-
|
250
|
-
|
251
|
-
|
255
|
+
line, = self.ax.plot(
|
256
|
+
dates,
|
257
|
+
values,
|
258
|
+
self.line_marker,
|
259
|
+
markersize=4,
|
260
|
+
color=color,
|
261
|
+
zorder=zo,
|
262
|
+
lw=lw,
|
263
|
+
)
|
252
264
|
# Add single, orphaned data points as markers
|
253
265
|
# None, 1, None, 1, 1, 1 => . ---
|
254
266
|
num_values = len(values)
|
255
267
|
if num_values == 1:
|
256
|
-
self.ax.plot(
|
257
|
-
|
258
|
-
|
259
|
-
|
268
|
+
self.ax.plot(
|
269
|
+
dates[0],
|
270
|
+
values[0],
|
271
|
+
c=color,
|
272
|
+
marker=self.point_marker,
|
273
|
+
zorder=12,
|
274
|
+
)
|
260
275
|
elif num_values > 1:
|
261
276
|
for j, v in enumerate(values):
|
262
277
|
def nullish(val):
|
@@ -270,10 +285,12 @@ class SerialChart(Chart):
|
|
270
285
|
elif nullish(values[j - 1]) and nullish(values[j + 1]):
|
271
286
|
plot_me = True
|
272
287
|
if plot_me:
|
273
|
-
self.ax.plot(
|
274
|
-
|
275
|
-
|
276
|
-
|
288
|
+
self.ax.plot(
|
289
|
+
dates[j], v,
|
290
|
+
c=color,
|
291
|
+
marker=self.point_marker,
|
292
|
+
zorder=12
|
293
|
+
)
|
277
294
|
|
278
295
|
if len(self.labels) > i and any([x[1] for x in serie]):
|
279
296
|
line.set_label(self.labels[i])
|
@@ -559,7 +576,7 @@ class SerialChart(Chart):
|
|
559
576
|
ymax=ymax + padding_top)
|
560
577
|
|
561
578
|
self.ax.yaxis.set_major_formatter(y_formatter)
|
562
|
-
self.ax.yaxis.grid(
|
579
|
+
self.ax.yaxis.grid(self.grid)
|
563
580
|
|
564
581
|
if ymin > self.baseline and self.allow_broken_y_axis:
|
565
582
|
self._mark_broken_axis()
|
@@ -1,9 +1,9 @@
|
|
1
1
|
Metadata-Version: 2.1
|
2
2
|
Name: newsworthycharts
|
3
|
-
Version: 1.
|
3
|
+
Version: 1.71.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.71.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
|
@@ -174,6 +174,12 @@ These settings are available for all chart types:
|
|
174
174
|
|
175
175
|
_ Inherits from SerialChart _
|
176
176
|
|
177
|
+
**BumpChart**
|
178
|
+
|
179
|
+
_ Inherits from SerialChart _
|
180
|
+
|
181
|
+
- highlight: The label value to of a line to highlight
|
182
|
+
|
177
183
|
**BubbleMap**
|
178
184
|
|
179
185
|
- bubble_size = 1 # The size of the bubbles
|
@@ -261,6 +267,14 @@ Roadmap
|
|
261
267
|
Changelog
|
262
268
|
---------
|
263
269
|
|
270
|
+
- 1.71.0
|
271
|
+
|
272
|
+
- Add `BumpChart`
|
273
|
+
|
274
|
+
- 1.70.2
|
275
|
+
|
276
|
+
- Fix edge case bug in y axis cutoff logic
|
277
|
+
|
264
278
|
- 1.70.1
|
265
279
|
|
266
280
|
- Make sure y axis is cut at 100 % unless we are really, really certain it should be higher
|
@@ -1,14 +1,15 @@
|
|
1
|
-
newsworthycharts/__init__.py,sha256=
|
1
|
+
newsworthycharts/__init__.py,sha256=mNGMLj9gC8MHheLQftfW3gxIMbVmzuTo9CATDA6O_pw,1221
|
2
2
|
newsworthycharts/bubblemap.py,sha256=nkocWmpiFgfjEuJGAsthjY5X7Q56jXWsZHUGXw4PwgE,2587
|
3
3
|
newsworthycharts/categoricalchart.py,sha256=YL3pzq8a7U5F0MpeRIAEwCAHw1BRDyKjoaAhf-UyRDo,18179
|
4
|
-
newsworthycharts/chart.py,sha256=
|
4
|
+
newsworthycharts/chart.py,sha256=WGrbn4UndhhKq-fbeHMn9vTaEAW3bSHVXrV-8aRqC_8,35692
|
5
5
|
newsworthycharts/choroplethmap.py,sha256=Si-01213rWqDKINkhmKV6x5iSMumQveJfrlCnqYcIJM,8173
|
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
|
+
newsworthycharts/rankchart.py,sha256=G80MO0oF57dgb1Xe3fAQ2hGxU6VhXp_VLev8suhCQjE,1154
|
9
10
|
newsworthycharts/scatterplot.py,sha256=l2w2JkA_4WzxQG9XG1Pn62IlJOdCMm1VemMiZL0rEfU,4959
|
10
11
|
newsworthycharts/seasonalchart.py,sha256=rr55yqJUkaYDR9Ik98jes6574oY1U8t8LwoLE3gClW4,1967
|
11
|
-
newsworthycharts/serialchart.py,sha256=
|
12
|
+
newsworthycharts/serialchart.py,sha256=o8a1X_g1lBReOTEKlFM_KiEMXHZ6ImBWqlBpDaDCMAE,28220
|
12
13
|
newsworthycharts/storage.py,sha256=myERhlpvXyExXxUByBq9eW1bWkCyfH9SwTZbsWSyy3Q,4301
|
13
14
|
newsworthycharts/stripechart.py,sha256=9B6PX2MyLuKNQ8W0OGdKbP0-U32kju0K_NHHwwz_J68,1547
|
14
15
|
newsworthycharts/custom/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
@@ -28,8 +29,8 @@ newsworthycharts/rc/newsworthy,sha256=yOIZvYS6PG1u19VMcdtfj9vbihKQsey5IprwqK59Kg
|
|
28
29
|
newsworthycharts/translations/datawrapper_regions.csv,sha256=fzZcQRX6RFMlNNP8mpgfYNdR3Y0QAlQxDXk8FXTaWWI,9214
|
29
30
|
newsworthycharts/translations/regions.py,sha256=Nv1McQjggD4S3JRu82rDMTG3pqUVR13E5-FBpSYbm98,239
|
30
31
|
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.
|
32
|
+
newsworthycharts-1.71.0.dist-info/LICENSE.txt,sha256=Sq6kGICrehbhC_FolNdXf0djKjTpv3YqjFCIYsxdQN4,1069
|
33
|
+
newsworthycharts-1.71.0.dist-info/METADATA,sha256=Wcl3NZM1kJhK7HiHsongNyXTmVeOj0iDzMIBThn2U1k,32222
|
34
|
+
newsworthycharts-1.71.0.dist-info/WHEEL,sha256=cVxcB9AmuTcXqmwrtPhNK88dr7IR_b6qagTj0UvIEbY,91
|
35
|
+
newsworthycharts-1.71.0.dist-info/top_level.txt,sha256=dn_kzIj8UgUCMsh1PHdVEQJHVGSsN7Z8YJF-8xXa8n0,17
|
36
|
+
newsworthycharts-1.71.0.dist-info/RECORD,,
|
File without changes
|
File without changes
|
File without changes
|