newsworthycharts 1.66.0__tar.gz → 1.68.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.
- {newsworthycharts-1.66.0/newsworthycharts.egg-info → newsworthycharts-1.68.0}/PKG-INFO +15 -2
- {newsworthycharts-1.66.0 → newsworthycharts-1.68.0}/README.rst +13 -0
- {newsworthycharts-1.66.0 → newsworthycharts-1.68.0}/newsworthycharts/__init__.py +1 -1
- {newsworthycharts-1.66.0 → newsworthycharts-1.68.0}/newsworthycharts/categoricalchart.py +69 -21
- {newsworthycharts-1.66.0 → newsworthycharts-1.68.0}/newsworthycharts/chart.py +3 -3
- {newsworthycharts-1.66.0 → newsworthycharts-1.68.0}/newsworthycharts/lib/datalist.py +5 -0
- {newsworthycharts-1.66.0 → newsworthycharts-1.68.0/newsworthycharts.egg-info}/PKG-INFO +15 -2
- {newsworthycharts-1.66.0 → newsworthycharts-1.68.0}/LICENSE.txt +0 -0
- {newsworthycharts-1.66.0 → newsworthycharts-1.68.0}/MANIFEST.in +0 -0
- {newsworthycharts-1.66.0 → newsworthycharts-1.68.0}/newsworthycharts/bubblemap.py +0 -0
- {newsworthycharts-1.66.0 → newsworthycharts-1.68.0}/newsworthycharts/choroplethmap.py +0 -0
- {newsworthycharts-1.66.0 → newsworthycharts-1.68.0}/newsworthycharts/custom/__init__.py +0 -0
- {newsworthycharts-1.66.0 → newsworthycharts-1.68.0}/newsworthycharts/custom/climate_cars.py +0 -0
- {newsworthycharts-1.66.0 → newsworthycharts-1.68.0}/newsworthycharts/datawrapper.py +0 -0
- {newsworthycharts-1.66.0 → newsworthycharts-1.68.0}/newsworthycharts/lib/__init__.py +0 -0
- {newsworthycharts-1.66.0 → newsworthycharts-1.68.0}/newsworthycharts/lib/color_fn.py +0 -0
- {newsworthycharts-1.66.0 → newsworthycharts-1.68.0}/newsworthycharts/lib/colors.py +0 -0
- {newsworthycharts-1.66.0 → newsworthycharts-1.68.0}/newsworthycharts/lib/formatter.py +0 -0
- {newsworthycharts-1.66.0 → newsworthycharts-1.68.0}/newsworthycharts/lib/geography.py +0 -0
- {newsworthycharts-1.66.0 → newsworthycharts-1.68.0}/newsworthycharts/lib/locator.py +0 -0
- {newsworthycharts-1.66.0 → newsworthycharts-1.68.0}/newsworthycharts/lib/mimetypes.py +0 -0
- {newsworthycharts-1.66.0 → newsworthycharts-1.68.0}/newsworthycharts/lib/utils.py +0 -0
- {newsworthycharts-1.66.0 → newsworthycharts-1.68.0}/newsworthycharts/map.py +0 -0
- {newsworthycharts-1.66.0 → newsworthycharts-1.68.0}/newsworthycharts/maps/se-4.gpkg +0 -0
- {newsworthycharts-1.66.0 → newsworthycharts-1.68.0}/newsworthycharts/maps/se-7.gpkg +0 -0
- {newsworthycharts-1.66.0 → newsworthycharts-1.68.0}/newsworthycharts/rangeplot.py +0 -0
- {newsworthycharts-1.66.0 → newsworthycharts-1.68.0}/newsworthycharts/rc/newsworthy +0 -0
- {newsworthycharts-1.66.0 → newsworthycharts-1.68.0}/newsworthycharts/scatterplot.py +0 -0
- {newsworthycharts-1.66.0 → newsworthycharts-1.68.0}/newsworthycharts/seasonalchart.py +0 -0
- {newsworthycharts-1.66.0 → newsworthycharts-1.68.0}/newsworthycharts/serialchart.py +0 -0
- {newsworthycharts-1.66.0 → newsworthycharts-1.68.0}/newsworthycharts/storage.py +0 -0
- {newsworthycharts-1.66.0 → newsworthycharts-1.68.0}/newsworthycharts/stripechart.py +0 -0
- {newsworthycharts-1.66.0 → newsworthycharts-1.68.0}/newsworthycharts/translations/datawrapper_regions.csv +0 -0
- {newsworthycharts-1.66.0 → newsworthycharts-1.68.0}/newsworthycharts/translations/regions.py +0 -0
- {newsworthycharts-1.66.0 → newsworthycharts-1.68.0}/newsworthycharts/translations/se_municipalities.csv +0 -0
- {newsworthycharts-1.66.0 → newsworthycharts-1.68.0}/newsworthycharts.egg-info/SOURCES.txt +0 -0
- {newsworthycharts-1.66.0 → newsworthycharts-1.68.0}/newsworthycharts.egg-info/dependency_links.txt +0 -0
- {newsworthycharts-1.66.0 → newsworthycharts-1.68.0}/newsworthycharts.egg-info/not-zip-safe +0 -0
- {newsworthycharts-1.66.0 → newsworthycharts-1.68.0}/newsworthycharts.egg-info/requires.txt +0 -0
- {newsworthycharts-1.66.0 → newsworthycharts-1.68.0}/newsworthycharts.egg-info/top_level.txt +0 -0
- {newsworthycharts-1.66.0 → newsworthycharts-1.68.0}/setup.cfg +0 -0
- {newsworthycharts-1.66.0 → newsworthycharts-1.68.0}/setup.py +0 -0
- {newsworthycharts-1.66.0 → newsworthycharts-1.68.0}/test/test_categorical_chart.py +0 -0
- {newsworthycharts-1.66.0 → newsworthycharts-1.68.0}/test/test_choropleth_maps.py +0 -0
- {newsworthycharts-1.66.0 → newsworthycharts-1.68.0}/test/test_custom_climate_cars.py +0 -0
- {newsworthycharts-1.66.0 → newsworthycharts-1.68.0}/test/test_data_list.py +0 -0
- {newsworthycharts-1.66.0 → newsworthycharts-1.68.0}/test/test_datawrapper.py +0 -0
- {newsworthycharts-1.66.0 → newsworthycharts-1.68.0}/test/test_main.py +0 -0
- {newsworthycharts-1.66.0 → newsworthycharts-1.68.0}/test/test_rangeplot.py +0 -0
- {newsworthycharts-1.66.0 → newsworthycharts-1.68.0}/test/test_scatterplot.py +0 -0
- {newsworthycharts-1.66.0 → newsworthycharts-1.68.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.
|
3
|
+
Version: 1.68.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.68.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
|
@@ -259,6 +259,19 @@ Roadmap
|
|
259
259
|
Changelog
|
260
260
|
---------
|
261
261
|
|
262
|
+
- 1.68.0
|
263
|
+
|
264
|
+
- Matplotlib==3.9.3
|
265
|
+
- More padding below chart
|
266
|
+
- Fix zorder issue in labeled multiple pie charts
|
267
|
+
|
268
|
+
- 1.67.0
|
269
|
+
|
270
|
+
- Fixed label margins in pie charts
|
271
|
+
- Trim all titles and subtitles of leading and trailing whitespace
|
272
|
+
- Improved piechart annotation
|
273
|
+
- Support `label_placement` (legend|outside|inline) in categorical charts ('legend' is still buggy in pie charts)
|
274
|
+
|
262
275
|
- 1.66.0
|
263
276
|
|
264
277
|
- Support multiple data series in pie charts (displayed as small multiples)
|
@@ -232,6 +232,19 @@ Roadmap
|
|
232
232
|
Changelog
|
233
233
|
---------
|
234
234
|
|
235
|
+
- 1.68.0
|
236
|
+
|
237
|
+
- Matplotlib==3.9.3
|
238
|
+
- More padding below chart
|
239
|
+
- Fix zorder issue in labeled multiple pie charts
|
240
|
+
|
241
|
+
- 1.67.0
|
242
|
+
|
243
|
+
- Fixed label margins in pie charts
|
244
|
+
- Trim all titles and subtitles of leading and trailing whitespace
|
245
|
+
- Improved piechart annotation
|
246
|
+
- Support `label_placement` (legend|outside|inline) in categorical charts ('legend' is still buggy in pie charts)
|
247
|
+
|
235
248
|
- 1.66.0
|
236
249
|
|
237
250
|
- Support multiple data series in pie charts (displayed as small multiples)
|
@@ -1,6 +1,6 @@
|
|
1
1
|
from .chart import Chart
|
2
2
|
from .lib.utils import to_float
|
3
|
-
|
3
|
+
from adjustText import adjust_text
|
4
4
|
import numpy as np
|
5
5
|
|
6
6
|
|
@@ -16,6 +16,7 @@ class CategoricalChart(Chart):
|
|
16
16
|
self.stacked = False
|
17
17
|
self.legend = True
|
18
18
|
self.type = "bars"
|
19
|
+
self.label_placement = None # legend|inline|outside # defaults will vary
|
19
20
|
|
20
21
|
# Optional: specify a list of colors (for multiple datasets)
|
21
22
|
self.colors = None
|
@@ -25,11 +26,11 @@ class CategoricalChart(Chart):
|
|
25
26
|
return self.stacked
|
26
27
|
|
27
28
|
def _add_pie_data(self):
|
28
|
-
self.legend = False
|
29
29
|
self.show_ticks = False
|
30
30
|
|
31
31
|
if len(self.data) > 1:
|
32
|
-
subaxes = self._fig.subplots(1, len(self.data))
|
32
|
+
subaxes = self._fig.subplots(1, len(self.data), subplot_kw={"zorder": -1})
|
33
|
+
patches = []
|
33
34
|
for idx, serie in enumerate(self.data):
|
34
35
|
if len(self.data) == 1:
|
35
36
|
subax = self.ax
|
@@ -45,17 +46,30 @@ class CategoricalChart(Chart):
|
|
45
46
|
colors = [self._nwc_style["qualitative_colors"][i] for i in range(len(values))]
|
46
47
|
|
47
48
|
explode = [0.1 if x == self.highlight else 0 for x in labels]
|
48
|
-
|
49
|
+
legend_placement = self.label_placement or "inline"
|
50
|
+
_pie = subax.pie(
|
49
51
|
values,
|
50
|
-
labels=labels,
|
52
|
+
labels=labels if legend_placement == "inline" else None,
|
51
53
|
startangle=90,
|
52
54
|
colors=colors,
|
53
|
-
explode=explode
|
55
|
+
explode=explode,
|
54
56
|
)
|
55
|
-
|
57
|
+
if idx == 0:
|
58
|
+
patches += _pie[0]
|
59
|
+
if len(self.data) > 1:
|
60
|
+
subax.axis('equal')
|
56
61
|
# `labels` in pie charts are used to label the series, not the values
|
57
62
|
if self.labels:
|
58
|
-
subax.set_title(self.labels[idx], loc='center', y=0
|
63
|
+
subax.set_title(self.labels[idx], loc='center', y=0)
|
64
|
+
if legend_placement == "inline":
|
65
|
+
self.legend = False
|
66
|
+
elif legend_placement == "legend":
|
67
|
+
_ = self.ax.legend(patches, labels, loc='best', frameon=True, fancybox=True)
|
68
|
+
_.set(zorder=20)
|
69
|
+
# self.ax.figure.subplots_adjust()
|
70
|
+
elif legend_placement == "outside":
|
71
|
+
_ = self.ax.legend(patches, labels, bbox_to_anchor=(1.04, 1), loc="upper left")
|
72
|
+
_.set(zorder=20)
|
59
73
|
|
60
74
|
self.ax.axis('off')
|
61
75
|
|
@@ -91,7 +105,7 @@ class CategoricalChart(Chart):
|
|
91
105
|
serie_values.append(_values)
|
92
106
|
|
93
107
|
cum_values = np.cumsum(serie_values, axis=0).tolist()
|
94
|
-
|
108
|
+
self._bars = []
|
95
109
|
for i, data in enumerate(self.data):
|
96
110
|
|
97
111
|
# Replace None values with 0's to be able to plot bars
|
@@ -167,6 +181,7 @@ class CategoricalChart(Chart):
|
|
167
181
|
bar_pos = [x + i * bar_width
|
168
182
|
for x in np.arange(len(values))]
|
169
183
|
|
184
|
+
_bar = None
|
170
185
|
if self.bar_orientation == "horizontal":
|
171
186
|
kwargs = dict(align='center', height=bar_width,
|
172
187
|
color=colors, zorder=2)
|
@@ -174,7 +189,7 @@ class CategoricalChart(Chart):
|
|
174
189
|
# To make stacked bars we need to set bottom value
|
175
190
|
kwargs["left"] = cum_values[i - 1]
|
176
191
|
|
177
|
-
self.ax.barh(bar_pos, values, **kwargs)
|
192
|
+
_bar = self.ax.barh(bar_pos, values, **kwargs)
|
178
193
|
|
179
194
|
elif self.bar_orientation == "vertical":
|
180
195
|
kwargs = dict(
|
@@ -185,7 +200,8 @@ class CategoricalChart(Chart):
|
|
185
200
|
if self.stacked and i > 0:
|
186
201
|
# To make stacked bars we need to set bottom value
|
187
202
|
kwargs["bottom"] = cum_values[i - 1]
|
188
|
-
self.ax.bar(bar_pos, values, **kwargs)
|
203
|
+
_bar = self.ax.bar(bar_pos, values, **kwargs)
|
204
|
+
self._bars.append(_bar)
|
189
205
|
|
190
206
|
if self.bar_orientation == "horizontal":
|
191
207
|
margin = 0.02 # above and below first/last bar on horizontal
|
@@ -207,9 +223,6 @@ class CategoricalChart(Chart):
|
|
207
223
|
self.ax.set_xticklabels(categories)
|
208
224
|
self.ax.xaxis.set_ticks_position('none')
|
209
225
|
|
210
|
-
if len(self.data) > 1:
|
211
|
-
self.ax.legend(self.labels, loc='best')
|
212
|
-
|
213
226
|
self._setup_legend()
|
214
227
|
|
215
228
|
def _setup_legend(self):
|
@@ -218,6 +231,31 @@ class CategoricalChart(Chart):
|
|
218
231
|
legend = self.ax.get_legend()
|
219
232
|
if legend:
|
220
233
|
legend.remove()
|
234
|
+
else:
|
235
|
+
if len(self.data) == 0 and self.type != "pie":
|
236
|
+
return
|
237
|
+
placement = self.label_placement or "legend"
|
238
|
+
if placement == "legend":
|
239
|
+
self.ax.legend(self.labels, loc='best')
|
240
|
+
elif placement == "outside":
|
241
|
+
_ = self.ax.legend(self.labels, bbox_to_anchor=(1.04, 1), loc="upper left")
|
242
|
+
_.set(zorder=20)
|
243
|
+
elif placement == "inline":
|
244
|
+
texts = []
|
245
|
+
for idx, _bar in enumerate(self._bars):
|
246
|
+
_texts = self.ax.bar_label(
|
247
|
+
_bar,
|
248
|
+
labels=[self.labels[idx]] * self.data.num_categories,
|
249
|
+
label_type="center",
|
250
|
+
backgroundcolor="#f0f0f099",
|
251
|
+
)
|
252
|
+
if idx > 0:
|
253
|
+
texts += [*_texts]
|
254
|
+
adjust_text(
|
255
|
+
texts,
|
256
|
+
ax=self.ax,
|
257
|
+
autoalign="x" if self.bar_orientation == "horizontal" else "y",
|
258
|
+
)
|
221
259
|
|
222
260
|
|
223
261
|
class CategoricalChartWithReference(CategoricalChart):
|
@@ -243,6 +281,7 @@ class CategoricalChartWithReference(CategoricalChart):
|
|
243
281
|
self.value_axis.grid(True)
|
244
282
|
|
245
283
|
bar_width = 0.8 / len(self.data)
|
284
|
+
self._bars = []
|
246
285
|
for i, data in enumerate(self.data):
|
247
286
|
|
248
287
|
# Replace None values with 0's to be able to plot bars
|
@@ -270,18 +309,30 @@ class CategoricalChartWithReference(CategoricalChart):
|
|
270
309
|
|
271
310
|
zorder = len(self.data) - i
|
272
311
|
if self.bar_orientation == "horizontal":
|
273
|
-
self.ax.barh(
|
274
|
-
|
312
|
+
bar = self.ax.barh(
|
313
|
+
bar_pos,
|
314
|
+
values,
|
315
|
+
height=bar_width,
|
316
|
+
align='center',
|
317
|
+
color=color,
|
318
|
+
zorder=zorder,
|
319
|
+
)
|
275
320
|
self.ax.set_yticks(tick_pos)
|
276
321
|
self.ax.set_yticklabels(categories)
|
277
322
|
# self.ax.invert_yaxis()
|
278
323
|
|
279
324
|
elif self.bar_orientation == "vertical":
|
280
|
-
self.ax.bar(
|
281
|
-
|
325
|
+
bar = self.ax.bar(
|
326
|
+
bar_pos,
|
327
|
+
values,
|
328
|
+
width=bar_width,
|
329
|
+
color=color,
|
330
|
+
zorder=zorder,
|
331
|
+
)
|
282
332
|
self.ax.set_xticks(tick_pos)
|
283
333
|
self.ax.set_xticklabels(categories)
|
284
334
|
self.ax.xaxis.set_ticks_position('none')
|
335
|
+
self._bars.append(bar)
|
285
336
|
|
286
337
|
# Make sure labels are not cropped
|
287
338
|
yaxis_bbox = self.ax.yaxis.get_tightbbox(self._fig.canvas.get_renderer())
|
@@ -289,9 +340,6 @@ class CategoricalChartWithReference(CategoricalChart):
|
|
289
340
|
margin -= yaxis_bbox.min[0] / float(self._w)
|
290
341
|
self._fig.subplots_adjust(left=margin)
|
291
342
|
|
292
|
-
if self.labels:
|
293
|
-
self.ax.legend(self.labels, loc='best')
|
294
|
-
|
295
343
|
self._setup_legend()
|
296
344
|
|
297
345
|
|
@@ -285,7 +285,7 @@ class Chart(object):
|
|
285
285
|
def _add_title(self, title_text):
|
286
286
|
"""Add a title."""
|
287
287
|
text = self._fig.suptitle(
|
288
|
-
title_text, wrap=True,
|
288
|
+
title_text.strip(), wrap=True,
|
289
289
|
x=0,
|
290
290
|
y=0.985, # default: 0.98
|
291
291
|
horizontalalignment="left",
|
@@ -300,7 +300,7 @@ class Chart(object):
|
|
300
300
|
text = self._fig.text(
|
301
301
|
0,
|
302
302
|
y_pos,
|
303
|
-
subtitle_text,
|
303
|
+
subtitle_text.strip(),
|
304
304
|
wrap=True,
|
305
305
|
verticalalignment="top",
|
306
306
|
linespacing=1.4,
|
@@ -648,7 +648,7 @@ class Chart(object):
|
|
648
648
|
# ticks labels
|
649
649
|
tick_label_height
|
650
650
|
# some padding
|
651
|
-
|
651
|
+
+ 15 / self._h
|
652
652
|
# chart notes (if any)
|
653
653
|
+ self._note_rel_height
|
654
654
|
# chart caption and logo (if any)
|
@@ -196,6 +196,11 @@ class DataSet(MutableSequence):
|
|
196
196
|
values = array(self.values, dtype=float)
|
197
197
|
return np.nansum(values, axis=0).tolist()
|
198
198
|
|
199
|
+
@property
|
200
|
+
def num_categories(self):
|
201
|
+
categories = set([x[0] for s in self.list for x in s])
|
202
|
+
return len(categories)
|
203
|
+
|
199
204
|
def __len__(self):
|
200
205
|
return len(self.list)
|
201
206
|
|
@@ -1,9 +1,9 @@
|
|
1
1
|
Metadata-Version: 2.1
|
2
2
|
Name: newsworthycharts
|
3
|
-
Version: 1.
|
3
|
+
Version: 1.68.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.68.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
|
@@ -259,6 +259,19 @@ Roadmap
|
|
259
259
|
Changelog
|
260
260
|
---------
|
261
261
|
|
262
|
+
- 1.68.0
|
263
|
+
|
264
|
+
- Matplotlib==3.9.3
|
265
|
+
- More padding below chart
|
266
|
+
- Fix zorder issue in labeled multiple pie charts
|
267
|
+
|
268
|
+
- 1.67.0
|
269
|
+
|
270
|
+
- Fixed label margins in pie charts
|
271
|
+
- Trim all titles and subtitles of leading and trailing whitespace
|
272
|
+
- Improved piechart annotation
|
273
|
+
- Support `label_placement` (legend|outside|inline) in categorical charts ('legend' is still buggy in pie charts)
|
274
|
+
|
262
275
|
- 1.66.0
|
263
276
|
|
264
277
|
- Support multiple data series in pie charts (displayed as small multiples)
|
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
|
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
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
{newsworthycharts-1.66.0 → newsworthycharts-1.68.0}/newsworthycharts/translations/regions.py
RENAMED
File without changes
|
File without changes
|
File without changes
|
{newsworthycharts-1.66.0 → newsworthycharts-1.68.0}/newsworthycharts.egg-info/dependency_links.txt
RENAMED
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
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|