plotjs 0.0.3__tar.gz → 0.0.4__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.
- {plotjs-0.0.3 → plotjs-0.0.4}/.coverage +0 -0
- {plotjs-0.0.3 → plotjs-0.0.4}/.github/workflows/tests.yaml +5 -2
- {plotjs-0.0.3 → plotjs-0.0.4}/.gitignore +2 -0
- {plotjs-0.0.3 → plotjs-0.0.4}/Makefile +3 -2
- {plotjs-0.0.3/plotjs.egg-info → plotjs-0.0.4}/PKG-INFO +1 -1
- {plotjs-0.0.3 → plotjs-0.0.4}/coverage-badge.svg +1 -1
- {plotjs-0.0.3 → plotjs-0.0.4}/docs/gallery/index.md +17 -5
- plotjs-0.0.4/docs/guides/advanced/advanced.py +213 -0
- plotjs-0.0.4/docs/guides/advanced/index.md +201 -0
- {plotjs-0.0.3 → plotjs-0.0.4}/docs/iframes/CSS-2.html +407 -347
- {plotjs-0.0.3 → plotjs-0.0.4}/docs/iframes/CSS.html +407 -347
- plotjs-0.0.4/docs/iframes/area-natural-disasters.html +3878 -0
- {plotjs-0.0.3 → plotjs-0.0.4}/docs/iframes/javascript.html +407 -347
- {plotjs-0.0.3 → plotjs-0.0.4}/docs/iframes/javascript2.html +265 -205
- {plotjs-0.0.3 → plotjs-0.0.4}/docs/iframes/quickstart.html +407 -347
- plotjs-0.0.4/docs/iframes/quickstart10.html +989 -0
- plotjs-0.0.4/docs/iframes/quickstart11.html +2407 -0
- {plotjs-0.0.3 → plotjs-0.0.4}/docs/iframes/quickstart2.html +407 -347
- {plotjs-0.0.3 → plotjs-0.0.4}/docs/iframes/quickstart3.html +407 -347
- plotjs-0.0.4/docs/iframes/quickstart4.html +1253 -0
- plotjs-0.0.4/docs/iframes/quickstart5.html +1507 -0
- {plotjs-0.0.3 → plotjs-0.0.4}/docs/iframes/quickstart6.html +108 -48
- {plotjs-0.0.3 → plotjs-0.0.4}/docs/iframes/quickstart7.html +265 -205
- {plotjs-0.0.3 → plotjs-0.0.4}/docs/iframes/quickstart8.html +106 -46
- {plotjs-0.0.3 → plotjs-0.0.4}/docs/iframes/quickstart9.html +722 -662
- {plotjs-0.0.3 → plotjs-0.0.4}/docs/index.md +129 -1
- {plotjs-0.0.3 → plotjs-0.0.4}/docs/index.qmd +113 -1
- plotjs-0.0.4/package-lock.json +6317 -0
- plotjs-0.0.4/package.json +11 -0
- {plotjs-0.0.3 → plotjs-0.0.4}/plotjs/__init__.py +1 -1
- {plotjs-0.0.3 → plotjs-0.0.4}/plotjs/main.py +28 -8
- plotjs-0.0.4/plotjs/static/main.js +87 -0
- {plotjs-0.0.3 → plotjs-0.0.4}/plotjs/static/template.html +84 -24
- {plotjs-0.0.3 → plotjs-0.0.4/plotjs.egg-info}/PKG-INFO +1 -1
- {plotjs-0.0.3 → plotjs-0.0.4}/plotjs.egg-info/SOURCES.txt +14 -8
- {plotjs-0.0.3 → plotjs-0.0.4}/pyproject.toml +3 -4
- plotjs-0.0.4/tests/PlotSVGParser.test.js +83 -0
- {plotjs-0.0.3/tests → plotjs-0.0.4/tests/test-python}/test_css_and_js_utils.py +3 -3
- {plotjs-0.0.3/tests → plotjs-0.0.4/tests/test-python}/test_main.py +1 -1
- plotjs-0.0.4/vitest.config.js +9 -0
- plotjs-0.0.3/docs/guides/advanced/advanced.py +0 -2
- plotjs-0.0.3/docs/guides/advanced/index.md +0 -1
- plotjs-0.0.3/docs/iframes/quickstart4.html +0 -1193
- plotjs-0.0.3/docs/iframes/quickstart5.html +0 -1419
- plotjs-0.0.3/plotjs/static/d3.min.js +0 -2
- plotjs-0.0.3/plotjs/static/main.js +0 -143
- {plotjs-0.0.3 → plotjs-0.0.4}/.gitattributes +0 -0
- {plotjs-0.0.3 → plotjs-0.0.4}/.github/workflows/doc.yaml +0 -0
- {plotjs-0.0.3 → plotjs-0.0.4}/.github/workflows/lint.yaml +0 -0
- {plotjs-0.0.3 → plotjs-0.0.4}/.github/workflows/pypi.yaml +0 -0
- {plotjs-0.0.3 → plotjs-0.0.4}/.github/workflows/type.yaml +0 -0
- {plotjs-0.0.3 → plotjs-0.0.4}/.pre-commit-config.yaml +0 -0
- {plotjs-0.0.3 → plotjs-0.0.4}/LICENSE +0 -0
- {plotjs-0.0.3 → plotjs-0.0.4}/README.md +0 -0
- {plotjs-0.0.3 → plotjs-0.0.4}/docs/developers/contributing.md +0 -0
- {plotjs-0.0.3 → plotjs-0.0.4}/docs/developers/how-it-works.md +0 -0
- {plotjs-0.0.3 → plotjs-0.0.4}/docs/gallery/index.qmd +0 -0
- {plotjs-0.0.3 → plotjs-0.0.4}/docs/guides/css/CSS.py +0 -0
- {plotjs-0.0.3 → plotjs-0.0.4}/docs/guides/css/index.md +0 -0
- {plotjs-0.0.3 → plotjs-0.0.4}/docs/guides/javascript/index.md +0 -0
- {plotjs-0.0.3 → plotjs-0.0.4}/docs/guides/javascript/javascript.py +0 -0
- {plotjs-0.0.3 → plotjs-0.0.4}/docs/guides/troubleshooting/index.md +0 -0
- {plotjs-0.0.3 → plotjs-0.0.4}/docs/img/how-it-works-1.png +0 -0
- {plotjs-0.0.3 → plotjs-0.0.4}/docs/img/how-it-works-2.png +0 -0
- {plotjs-0.0.3 → plotjs-0.0.4}/docs/index_files/figure-commonmark/cell-3-output-1.png +0 -0
- {plotjs-0.0.3 → plotjs-0.0.4}/docs/reference/css.md +0 -0
- {plotjs-0.0.3 → plotjs-0.0.4}/docs/reference/datasets.md +0 -0
- {plotjs-0.0.3 → plotjs-0.0.4}/docs/reference/javascript.md +0 -0
- {plotjs-0.0.3 → plotjs-0.0.4}/docs/reference/magic-plot.md +0 -0
- {plotjs-0.0.3 → plotjs-0.0.4}/docs/static/style.css +0 -0
- {plotjs-0.0.3 → plotjs-0.0.4}/docs/stylesheets/style.css +0 -0
- {plotjs-0.0.3 → plotjs-0.0.4}/mkdocs.yaml +0 -0
- {plotjs-0.0.3 → plotjs-0.0.4}/overrides/partials/footer.html +0 -0
- {plotjs-0.0.3 → plotjs-0.0.4}/plotjs/css.py +0 -0
- {plotjs-0.0.3 → plotjs-0.0.4}/plotjs/data/__init__.py +0 -0
- {plotjs-0.0.3 → plotjs-0.0.4}/plotjs/data/datasets.py +0 -0
- {plotjs-0.0.3 → plotjs-0.0.4}/plotjs/data/iris.csv +0 -0
- {plotjs-0.0.3 → plotjs-0.0.4}/plotjs/data/mtcars.csv +0 -0
- {plotjs-0.0.3 → plotjs-0.0.4}/plotjs/data/titanic.csv +0 -0
- {plotjs-0.0.3 → plotjs-0.0.4}/plotjs/javascript.py +0 -0
- {plotjs-0.0.3 → plotjs-0.0.4}/plotjs/static/default.css +0 -0
- {plotjs-0.0.3 → plotjs-0.0.4}/plotjs/utils.py +0 -0
- {plotjs-0.0.3 → plotjs-0.0.4}/plotjs.egg-info/dependency_links.txt +0 -0
- {plotjs-0.0.3 → plotjs-0.0.4}/plotjs.egg-info/requires.txt +0 -0
- {plotjs-0.0.3 → plotjs-0.0.4}/plotjs.egg-info/top_level.txt +0 -0
- {plotjs-0.0.3 → plotjs-0.0.4}/setup.cfg +0 -0
- {plotjs-0.0.3/tests → plotjs-0.0.4/tests/test-python}/__init__.py +0 -0
- {plotjs-0.0.3/tests → plotjs-0.0.4/tests/test-python}/static/script.js +0 -0
- {plotjs-0.0.3/tests → plotjs-0.0.4/tests/test-python}/static/style.css +0 -0
- {plotjs-0.0.3/tests → plotjs-0.0.4/tests/test-python}/test_data.py +0 -0
- {plotjs-0.0.3/tests → plotjs-0.0.4/tests/test-python}/test_magic_plot.py +0 -0
|
Binary file
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
name:
|
|
1
|
+
name: Tests (Python + JS)
|
|
2
2
|
|
|
3
3
|
on:
|
|
4
4
|
pull_request:
|
|
@@ -24,5 +24,8 @@ jobs:
|
|
|
24
24
|
- name: Install the project
|
|
25
25
|
run: uv sync --all-groups
|
|
26
26
|
|
|
27
|
+
- name: Install npm dependencies
|
|
28
|
+
run: npm install
|
|
29
|
+
|
|
27
30
|
- name: Run tests
|
|
28
|
-
run:
|
|
31
|
+
run: make test
|
|
@@ -1 +1 @@
|
|
|
1
|
-
<svg xmlns="http://www.w3.org/2000/svg" width="114" height="20" role="img" aria-label="coverage:
|
|
1
|
+
<svg xmlns="http://www.w3.org/2000/svg" width="114" height="20" role="img" aria-label="coverage: 93.02%"><title>coverage: 93.02%</title><linearGradient id="s" x2="0" y2="100%"><stop offset="0" stop-color="#bbb" stop-opacity=".1"/><stop offset="1" stop-opacity=".1"/></linearGradient><clipPath id="r"><rect width="114" height="20" rx="3" fill="#fff"/></clipPath><g clip-path="url(#r)"><rect width="61" height="20" fill="#555"/><rect x="61" width="53" height="20" fill="#4c1"/><rect width="114" height="20" fill="url(#s)"/></g><g fill="#fff" text-anchor="middle" font-family="Verdana,Geneva,DejaVu Sans,sans-serif" text-rendering="geometricPrecision" font-size="110"><text aria-hidden="true" x="315" y="150" fill="#010101" fill-opacity=".3" transform="scale(.1)" textLength="510">coverage</text><text x="315" y="140" transform="scale(.1)" fill="#fff" textLength="510">coverage</text><text aria-hidden="true" x="865" y="150" fill="#010101" fill-opacity=".3" transform="scale(.1)" textLength="430">93.02%</text><text x="865" y="140" transform="scale(.1)" fill="#fff" textLength="430">93.02%</text></g></svg>
|
|
@@ -18,11 +18,11 @@ This page contains all the `plotjs` examples from this website.
|
|
|
18
18
|
|
|
19
19
|
<div style="display: flex;">
|
|
20
20
|
|
|
21
|
-
<iframe width="100%" height="300" src="../iframes/
|
|
21
|
+
<iframe width="100%" height="300" src="../iframes/area-natural-disasters.html" style="flex: 1; border: none;">
|
|
22
22
|
|
|
23
23
|
</iframe>
|
|
24
24
|
|
|
25
|
-
<iframe width="100%" height="300" src="../iframes/
|
|
25
|
+
<iframe width="100%" height="300" src="../iframes/quickstart4.html" style="flex: 1; border: none;">
|
|
26
26
|
|
|
27
27
|
</iframe>
|
|
28
28
|
|
|
@@ -30,11 +30,11 @@ This page contains all the `plotjs` examples from this website.
|
|
|
30
30
|
|
|
31
31
|
<div style="display: flex;">
|
|
32
32
|
|
|
33
|
-
<iframe width="100%" height="300" src="../iframes/
|
|
33
|
+
<iframe width="100%" height="300" src="../iframes/quickstart5.html" style="flex: 1; border: none;">
|
|
34
34
|
|
|
35
35
|
</iframe>
|
|
36
36
|
|
|
37
|
-
<iframe width="100%" height="300" src="../iframes/
|
|
37
|
+
<iframe width="100%" height="300" src="../iframes/quickstart9.html" style="flex: 1; border: none;">
|
|
38
38
|
|
|
39
39
|
</iframe>
|
|
40
40
|
|
|
@@ -42,19 +42,31 @@ This page contains all the `plotjs` examples from this website.
|
|
|
42
42
|
|
|
43
43
|
<div style="display: flex;">
|
|
44
44
|
|
|
45
|
+
<iframe width="100%" height="300" src="../iframes/CSS.html" style="flex: 1; border: none;">
|
|
46
|
+
|
|
47
|
+
</iframe>
|
|
48
|
+
|
|
45
49
|
<iframe width="100%" height="300" src="../iframes/quickstart2.html" style="flex: 1; border: none;">
|
|
46
50
|
|
|
47
51
|
</iframe>
|
|
48
52
|
|
|
53
|
+
</div>
|
|
54
|
+
|
|
55
|
+
<div style="display: flex;">
|
|
56
|
+
|
|
49
57
|
<iframe width="100%" height="300" src="../iframes/javascript.html" style="flex: 1; border: none;">
|
|
50
58
|
|
|
51
59
|
</iframe>
|
|
52
60
|
|
|
61
|
+
<iframe width="100%" height="300" src="../iframes/quickstart3.html" style="flex: 1; border: none;">
|
|
62
|
+
|
|
63
|
+
</iframe>
|
|
64
|
+
|
|
53
65
|
</div>
|
|
54
66
|
|
|
55
67
|
<div style="display: flex;">
|
|
56
68
|
|
|
57
|
-
<iframe width="100%" height="300" src="../iframes/
|
|
69
|
+
<iframe width="100%" height="300" src="../iframes/quickstart10.html" style="flex: 1; border: none;">
|
|
58
70
|
|
|
59
71
|
</iframe>
|
|
60
72
|
|
|
@@ -0,0 +1,213 @@
|
|
|
1
|
+
from plotjs import MagicPlot, css
|
|
2
|
+
import pandas as pd
|
|
3
|
+
import numpy as np
|
|
4
|
+
import matplotlib.pyplot as plt
|
|
5
|
+
from pypalettes import load_cmap
|
|
6
|
+
from highlight_text import fig_text, ax_text
|
|
7
|
+
from pyfonts import load_google_font
|
|
8
|
+
from drawarrow import ax_arrow
|
|
9
|
+
|
|
10
|
+
url = "https://raw.githubusercontent.com/holtzy/The-Python-Graph-Gallery/master/static/data/disaster-events.csv"
|
|
11
|
+
df = pd.read_csv(url)
|
|
12
|
+
|
|
13
|
+
|
|
14
|
+
def remove_agg_rows(entity: str):
|
|
15
|
+
if entity.lower().startswith("all disasters"):
|
|
16
|
+
return False
|
|
17
|
+
else:
|
|
18
|
+
return True
|
|
19
|
+
|
|
20
|
+
|
|
21
|
+
df = df.replace("Dry mass movement", "Drought")
|
|
22
|
+
df = df[df["Entity"].apply(remove_agg_rows)]
|
|
23
|
+
df = df[~df["Entity"].isin(["Fog", "Glacial lake outburst flood"])]
|
|
24
|
+
df = df.pivot_table(index="Entity", columns="Year", values="Disasters").T
|
|
25
|
+
df.loc[1900, :] = df.loc[1900, :].fillna(0)
|
|
26
|
+
df = df[df.index >= 1960]
|
|
27
|
+
df = df[df.index <= 2023]
|
|
28
|
+
df = df.interpolate(axis=1)
|
|
29
|
+
df.head()
|
|
30
|
+
|
|
31
|
+
# set up the font properties
|
|
32
|
+
font = load_google_font("Bebas Neue")
|
|
33
|
+
other_font = load_google_font("Fira Sans", weight="light")
|
|
34
|
+
other_bold_font = load_google_font("Fira Sans", weight="medium")
|
|
35
|
+
|
|
36
|
+
# initialize the figure
|
|
37
|
+
fig, ax = plt.subplots(figsize=(14, 7), dpi=300)
|
|
38
|
+
ax.set_axis_off()
|
|
39
|
+
|
|
40
|
+
# define the x-axis variable and order the columns
|
|
41
|
+
columns = df.sum().sort_values().index.to_list()
|
|
42
|
+
x = df.index
|
|
43
|
+
|
|
44
|
+
# defines color map and mapping with columns
|
|
45
|
+
colors = load_cmap("Dali").colors
|
|
46
|
+
color_mapping = {
|
|
47
|
+
"Flood": colors[4],
|
|
48
|
+
"Volcanic activity": colors[0],
|
|
49
|
+
"Wildfire": colors[6],
|
|
50
|
+
"Drought": colors[7],
|
|
51
|
+
"Extreme temperature": colors[5],
|
|
52
|
+
"Wet mass movement": colors[3],
|
|
53
|
+
"Earthquake": colors[2],
|
|
54
|
+
"Extreme weather": colors[1],
|
|
55
|
+
}
|
|
56
|
+
colors = [color_mapping[col] for col in columns]
|
|
57
|
+
|
|
58
|
+
# create the stacked area plot
|
|
59
|
+
areas = np.stack(df[columns].values, axis=-1)
|
|
60
|
+
ax.stackplot(x, areas, colors=colors)
|
|
61
|
+
|
|
62
|
+
# add label for the x-axis
|
|
63
|
+
for year in range(1960, 2030, 10):
|
|
64
|
+
ax_text(
|
|
65
|
+
x=year,
|
|
66
|
+
y=-10,
|
|
67
|
+
s=f"{year}",
|
|
68
|
+
va="top",
|
|
69
|
+
ha="left",
|
|
70
|
+
fontsize=13,
|
|
71
|
+
font=font,
|
|
72
|
+
color="grey",
|
|
73
|
+
)
|
|
74
|
+
|
|
75
|
+
# add label for the y-axis
|
|
76
|
+
for value in range(100, 400, 100):
|
|
77
|
+
ax_text(
|
|
78
|
+
x=1960,
|
|
79
|
+
y=value,
|
|
80
|
+
s=f"{value}",
|
|
81
|
+
va="center",
|
|
82
|
+
ha="left",
|
|
83
|
+
fontsize=13,
|
|
84
|
+
font=font,
|
|
85
|
+
color="grey",
|
|
86
|
+
)
|
|
87
|
+
ax.plot([1963, 2023], [value, value], color="grey", lw=0.1)
|
|
88
|
+
|
|
89
|
+
# add title
|
|
90
|
+
fig_text(
|
|
91
|
+
s="More than 1 natural disaster occurs\n<every day> since the 21st century",
|
|
92
|
+
x=0.16,
|
|
93
|
+
y=0.83,
|
|
94
|
+
fontsize=24,
|
|
95
|
+
ha="left",
|
|
96
|
+
va="top",
|
|
97
|
+
color="black",
|
|
98
|
+
font=other_font,
|
|
99
|
+
fig=fig,
|
|
100
|
+
highlight_textprops=[{"font": other_bold_font}],
|
|
101
|
+
)
|
|
102
|
+
|
|
103
|
+
# source and credit
|
|
104
|
+
text = """
|
|
105
|
+
<Design>: barbierjoseph.com
|
|
106
|
+
<Data>: EM-DAT, CRED / UCLouvain (2024)
|
|
107
|
+
"""
|
|
108
|
+
fig_text(
|
|
109
|
+
s=text,
|
|
110
|
+
x=0.16,
|
|
111
|
+
y=0.05,
|
|
112
|
+
fontsize=10,
|
|
113
|
+
ha="left",
|
|
114
|
+
va="top",
|
|
115
|
+
color="black",
|
|
116
|
+
fontproperties=other_font,
|
|
117
|
+
highlight_textprops=[{"font": other_bold_font}, {"font": other_bold_font}],
|
|
118
|
+
)
|
|
119
|
+
|
|
120
|
+
# add inline labels
|
|
121
|
+
y_pos = [330, 220, 180, 100, 70, 30, -10, -30]
|
|
122
|
+
for i in range(len(y_pos)):
|
|
123
|
+
country = columns[::-1][i]
|
|
124
|
+
val_2023 = int(df.loc[2023, country])
|
|
125
|
+
ax_text(
|
|
126
|
+
x=2030,
|
|
127
|
+
y=y_pos[i],
|
|
128
|
+
s=f"{country.upper()} - {val_2023} disasters in 2023",
|
|
129
|
+
va="center",
|
|
130
|
+
ha="left",
|
|
131
|
+
font=other_bold_font,
|
|
132
|
+
fontsize=12,
|
|
133
|
+
color=colors[7 - i],
|
|
134
|
+
)
|
|
135
|
+
|
|
136
|
+
# add inflexion arrows
|
|
137
|
+
x_axis_start = 2023
|
|
138
|
+
x_axis_end = 2030
|
|
139
|
+
radius = 10
|
|
140
|
+
arrow_props = {"clip_on": False, "color": "black", "fill_head": False}
|
|
141
|
+
ax_arrow(
|
|
142
|
+
tail_position=(x_axis_start, 330), head_position=(x_axis_end, 330), **arrow_props
|
|
143
|
+
)
|
|
144
|
+
ax_arrow(
|
|
145
|
+
tail_position=(x_axis_start, 220), head_position=(x_axis_end, 220), **arrow_props
|
|
146
|
+
)
|
|
147
|
+
ax_arrow(
|
|
148
|
+
tail_position=(x_axis_start, 90),
|
|
149
|
+
head_position=(x_axis_end, 180),
|
|
150
|
+
inflection_position=(2040, 180),
|
|
151
|
+
**arrow_props,
|
|
152
|
+
)
|
|
153
|
+
ax_arrow(
|
|
154
|
+
tail_position=(x_axis_start, 60),
|
|
155
|
+
head_position=(x_axis_end, 100),
|
|
156
|
+
inflection_position=(2040, 100),
|
|
157
|
+
**arrow_props,
|
|
158
|
+
)
|
|
159
|
+
ax_arrow(
|
|
160
|
+
tail_position=(x_axis_start, 45),
|
|
161
|
+
head_position=(x_axis_end, 70),
|
|
162
|
+
inflection_position=(2040, 70),
|
|
163
|
+
**arrow_props,
|
|
164
|
+
)
|
|
165
|
+
ax_arrow(
|
|
166
|
+
tail_position=(x_axis_start, 30), head_position=(x_axis_end, 30), **arrow_props
|
|
167
|
+
)
|
|
168
|
+
ax_arrow(
|
|
169
|
+
tail_position=(x_axis_start, 20),
|
|
170
|
+
head_position=(x_axis_end, -10),
|
|
171
|
+
inflection_position=(2040, -10),
|
|
172
|
+
**arrow_props,
|
|
173
|
+
)
|
|
174
|
+
ax_arrow(
|
|
175
|
+
tail_position=(x_axis_start, 4),
|
|
176
|
+
head_position=(x_axis_end, -30),
|
|
177
|
+
inflection_position=(2040, -30),
|
|
178
|
+
**arrow_props,
|
|
179
|
+
)
|
|
180
|
+
plt.savefig("debug.svg")
|
|
181
|
+
|
|
182
|
+
MagicPlot(fig, bbox_inches="tight").add_css(
|
|
183
|
+
css.from_dict(
|
|
184
|
+
{
|
|
185
|
+
".tooltip": {
|
|
186
|
+
"width": "180px",
|
|
187
|
+
"text-align": "center",
|
|
188
|
+
"font-size": "1.2em",
|
|
189
|
+
"background": "#000814",
|
|
190
|
+
}
|
|
191
|
+
}
|
|
192
|
+
)
|
|
193
|
+
).add_tooltip(labels=columns).save("docs/iframes/area-natural-disasters.html")
|
|
194
|
+
|
|
195
|
+
#####################################################
|
|
196
|
+
|
|
197
|
+
|
|
198
|
+
(
|
|
199
|
+
MagicPlot(fig)
|
|
200
|
+
.add_css(
|
|
201
|
+
css.from_dict(
|
|
202
|
+
{
|
|
203
|
+
".tooltip": {
|
|
204
|
+
"width": "180px",
|
|
205
|
+
"text-align": "center",
|
|
206
|
+
"font-size": "1.2em",
|
|
207
|
+
"background": "#000814",
|
|
208
|
+
}
|
|
209
|
+
}
|
|
210
|
+
)
|
|
211
|
+
)
|
|
212
|
+
.add_tooltip(labels=columns)
|
|
213
|
+
)
|
|
@@ -0,0 +1,201 @@
|
|
|
1
|
+
# TODO: find cool examples to showcase here
|
|
2
|
+
|
|
3
|
+
## Natural disasters
|
|
4
|
+
|
|
5
|
+
```py
|
|
6
|
+
from plotjs import MagicPlot, css
|
|
7
|
+
import pandas as pd
|
|
8
|
+
import numpy as np
|
|
9
|
+
import matplotlib.pyplot as plt
|
|
10
|
+
from pypalettes import load_cmap
|
|
11
|
+
from highlight_text import fig_text, ax_text
|
|
12
|
+
from pyfonts import load_google_font
|
|
13
|
+
from drawarrow import ax_arrow
|
|
14
|
+
|
|
15
|
+
url = "https://raw.githubusercontent.com/holtzy/The-Python-Graph-Gallery/master/static/data/disaster-events.csv"
|
|
16
|
+
df = pd.read_csv(url)
|
|
17
|
+
|
|
18
|
+
|
|
19
|
+
def remove_agg_rows(entity: str):
|
|
20
|
+
if entity.lower().startswith("all disasters"):
|
|
21
|
+
return False
|
|
22
|
+
else:
|
|
23
|
+
return True
|
|
24
|
+
|
|
25
|
+
|
|
26
|
+
df = df.replace("Dry mass movement", "Drought")
|
|
27
|
+
df = df[df["Entity"].apply(remove_agg_rows)]
|
|
28
|
+
df = df[~df["Entity"].isin(["Fog", "Glacial lake outburst flood"])]
|
|
29
|
+
df = df.pivot_table(index="Entity", columns="Year", values="Disasters").T
|
|
30
|
+
df.loc[1900, :] = df.loc[1900, :].fillna(0)
|
|
31
|
+
df = df[df.index >= 1960]
|
|
32
|
+
df = df[df.index <= 2023]
|
|
33
|
+
df = df.interpolate(axis=1)
|
|
34
|
+
df.head()
|
|
35
|
+
|
|
36
|
+
# set up the font properties
|
|
37
|
+
font = load_google_font("Bebas Neue")
|
|
38
|
+
other_font = load_google_font("Fira Sans", weight="light")
|
|
39
|
+
other_bold_font = load_google_font("Fira Sans", weight="medium")
|
|
40
|
+
|
|
41
|
+
# initialize the figure
|
|
42
|
+
fig, ax = plt.subplots(figsize=(14, 7), dpi=300)
|
|
43
|
+
ax.set_axis_off()
|
|
44
|
+
|
|
45
|
+
# define the x-axis variable and order the columns
|
|
46
|
+
columns = df.sum().sort_values().index.to_list()
|
|
47
|
+
x = df.index
|
|
48
|
+
|
|
49
|
+
# defines color map and mapping with columns
|
|
50
|
+
colors = load_cmap("Dali").colors
|
|
51
|
+
color_mapping = {
|
|
52
|
+
"Flood": colors[4],
|
|
53
|
+
"Volcanic activity": colors[0],
|
|
54
|
+
"Wildfire": colors[6],
|
|
55
|
+
"Drought": colors[7],
|
|
56
|
+
"Extreme temperature": colors[5],
|
|
57
|
+
"Wet mass movement": colors[3],
|
|
58
|
+
"Earthquake": colors[2],
|
|
59
|
+
"Extreme weather": colors[1],
|
|
60
|
+
}
|
|
61
|
+
colors = [color_mapping[col] for col in columns]
|
|
62
|
+
|
|
63
|
+
# create the stacked area plot
|
|
64
|
+
areas = np.stack(df[columns].values, axis=-1)
|
|
65
|
+
ax.stackplot(x, areas, colors=colors)
|
|
66
|
+
|
|
67
|
+
# add label for the x-axis
|
|
68
|
+
for year in range(1960, 2030, 10):
|
|
69
|
+
ax_text(
|
|
70
|
+
x=year,
|
|
71
|
+
y=-10,
|
|
72
|
+
s=f"{year}",
|
|
73
|
+
va="top",
|
|
74
|
+
ha="left",
|
|
75
|
+
fontsize=13,
|
|
76
|
+
font=font,
|
|
77
|
+
color="grey",
|
|
78
|
+
)
|
|
79
|
+
|
|
80
|
+
# add label for the y-axis
|
|
81
|
+
for value in range(100, 400, 100):
|
|
82
|
+
ax_text(
|
|
83
|
+
x=1960,
|
|
84
|
+
y=value,
|
|
85
|
+
s=f"{value}",
|
|
86
|
+
va="center",
|
|
87
|
+
ha="left",
|
|
88
|
+
fontsize=13,
|
|
89
|
+
font=font,
|
|
90
|
+
color="grey",
|
|
91
|
+
)
|
|
92
|
+
ax.plot([1963, 2023], [value, value], color="grey", lw=0.1)
|
|
93
|
+
|
|
94
|
+
# add title
|
|
95
|
+
fig_text(
|
|
96
|
+
s="More than 1 natural disaster occurs\n<every day> since the 21st century",
|
|
97
|
+
x=0.16,
|
|
98
|
+
y=0.83,
|
|
99
|
+
fontsize=24,
|
|
100
|
+
ha="left",
|
|
101
|
+
va="top",
|
|
102
|
+
color="black",
|
|
103
|
+
font=other_font,
|
|
104
|
+
fig=fig,
|
|
105
|
+
highlight_textprops=[{"font": other_bold_font}],
|
|
106
|
+
)
|
|
107
|
+
|
|
108
|
+
# source and credit
|
|
109
|
+
text = """
|
|
110
|
+
<Design>: barbierjoseph.com
|
|
111
|
+
<Data>: EM-DAT, CRED / UCLouvain (2024)
|
|
112
|
+
"""
|
|
113
|
+
fig_text(
|
|
114
|
+
s=text,
|
|
115
|
+
x=0.16,
|
|
116
|
+
y=0.05,
|
|
117
|
+
fontsize=10,
|
|
118
|
+
ha="left",
|
|
119
|
+
va="top",
|
|
120
|
+
color="black",
|
|
121
|
+
fontproperties=other_font,
|
|
122
|
+
highlight_textprops=[{"font": other_bold_font}, {"font": other_bold_font}],
|
|
123
|
+
)
|
|
124
|
+
|
|
125
|
+
# add inline labels
|
|
126
|
+
y_pos = [330, 220, 180, 100, 70, 30, -10, -30]
|
|
127
|
+
for i in range(len(y_pos)):
|
|
128
|
+
country = columns[::-1][i]
|
|
129
|
+
val_2023 = int(df.loc[2023, country])
|
|
130
|
+
ax_text(
|
|
131
|
+
x=2030,
|
|
132
|
+
y=y_pos[i],
|
|
133
|
+
s=f"{country.upper()} - {val_2023} disasters in 2023",
|
|
134
|
+
va="center",
|
|
135
|
+
ha="left",
|
|
136
|
+
font=other_bold_font,
|
|
137
|
+
fontsize=12,
|
|
138
|
+
color=colors[7 - i],
|
|
139
|
+
)
|
|
140
|
+
|
|
141
|
+
# add inflexion arrows
|
|
142
|
+
x_axis_start = 2023
|
|
143
|
+
x_axis_end = 2030
|
|
144
|
+
radius = 10
|
|
145
|
+
arrow_props = {"clip_on": False, "color": "black", "fill_head": False}
|
|
146
|
+
ax_arrow(
|
|
147
|
+
tail_position=(x_axis_start, 330), head_position=(x_axis_end, 330), **arrow_props
|
|
148
|
+
)
|
|
149
|
+
ax_arrow(
|
|
150
|
+
tail_position=(x_axis_start, 220), head_position=(x_axis_end, 220), **arrow_props
|
|
151
|
+
)
|
|
152
|
+
ax_arrow(
|
|
153
|
+
tail_position=(x_axis_start, 90),
|
|
154
|
+
head_position=(x_axis_end, 180),
|
|
155
|
+
inflection_position=(2040, 180),
|
|
156
|
+
**arrow_props,
|
|
157
|
+
)
|
|
158
|
+
ax_arrow(
|
|
159
|
+
tail_position=(x_axis_start, 60),
|
|
160
|
+
head_position=(x_axis_end, 100),
|
|
161
|
+
inflection_position=(2040, 100),
|
|
162
|
+
**arrow_props,
|
|
163
|
+
)
|
|
164
|
+
ax_arrow(
|
|
165
|
+
tail_position=(x_axis_start, 45),
|
|
166
|
+
head_position=(x_axis_end, 70),
|
|
167
|
+
inflection_position=(2040, 70),
|
|
168
|
+
**arrow_props,
|
|
169
|
+
)
|
|
170
|
+
ax_arrow(
|
|
171
|
+
tail_position=(x_axis_start, 30), head_position=(x_axis_end, 30), **arrow_props
|
|
172
|
+
)
|
|
173
|
+
ax_arrow(
|
|
174
|
+
tail_position=(x_axis_start, 20),
|
|
175
|
+
head_position=(x_axis_end, -10),
|
|
176
|
+
inflection_position=(2040, -10),
|
|
177
|
+
**arrow_props,
|
|
178
|
+
)
|
|
179
|
+
ax_arrow(
|
|
180
|
+
tail_position=(x_axis_start, 4),
|
|
181
|
+
head_position=(x_axis_end, -30),
|
|
182
|
+
inflection_position=(2040, -30),
|
|
183
|
+
**arrow_props,
|
|
184
|
+
)
|
|
185
|
+
plt.savefig("debug.svg")
|
|
186
|
+
|
|
187
|
+
MagicPlot(fig, bbox_inches="tight").add_css(
|
|
188
|
+
css.from_dict(
|
|
189
|
+
{
|
|
190
|
+
".tooltip": {
|
|
191
|
+
"width": "180px",
|
|
192
|
+
"text-align": "center",
|
|
193
|
+
"font-size": "1.2em",
|
|
194
|
+
"background": "#000814",
|
|
195
|
+
}
|
|
196
|
+
}
|
|
197
|
+
)
|
|
198
|
+
).add_tooltip(labels=columns).save("docs/iframes/area-natural-disasters.html")
|
|
199
|
+
```
|
|
200
|
+
|
|
201
|
+
<iframe width="1000" height="400" src="../../iframes/area-natural-disasters.html" style="border:none;"></iframe>
|