-
Notifications
You must be signed in to change notification settings - Fork 1
/
Copy pathproject_5.html
200 lines (191 loc) · 8.77 KB
/
project_5.html
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<link href="https://fonts.googleapis.com/css?family=Montserrat:600,700,800" rel="stylesheet">
<link href="https://fonts.googleapis.com/css?family=Open+Sans:300,400,600,700,800&display=swap" rel="stylesheet">
<link rel="stylesheet" href="https://use.fontawesome.com/releases/v5.8.2/css/all.css"
integrity="sha384-oS3vJWv+0UjzBfQzYUhtDYW+Pj2yciDJxpsK1OYPAYjqT085Qq/1cq5FLXAZQ7Ay" crossorigin="anonymous">
<link rel="stylesheet" href="./style.css">
<script src="https://cdn.jsdelivr.net/npm/vue"></script>
<script src="https://cdn.jsdelivr.net/npm/[email protected]"></script>
<script src="https://cdn.jsdelivr.net/gh/google/code-prettify@master/loader/run_prettify.js"></script>
<link rel="stylesheet" href="./code.css">
<title>Pascal Schlaak | Portfolio</title>
<link rel="icon" type="image/png" href="./imgs/icons/logo_small.svg">
</head>
<body>
<div id="app">
<navbar-normal></navbar-normal>
<navbar-small></navbar-small>
<hamburger></hamburger>
<section id="project">
<img src="./imgs/dots.png" id="dots">
<div class="container project-text">
<h1>WhatsApp chat history analysis & visualization</h1>
<div class="flex-row">
<div class="column-65">
<p class="text">In my freetime I wanted to analyze an old <code>WhatsApp</code> group chat and
compare it with its new one to see things like
difference in activity. <code>WhatsApp</code> offers functionality to download group chats
as <code>.txt</code> files. I wrote
a <code>Python</code> script to read group chat content in data structures and analyze all
messages on things I was interested in.
Following algorithm was build to fetch content of every participants message and split it
into <code>datetime</code>, <code>sender</code> and <code>message</code>.
</p>
<pre class="prettyprint text fact">
<code class="lang-py">
...
# Add all senders by name to name array
for arg in argv:
name_set.add(arg.lower())
# Split chat_data back into messages
splitted_chat_data = raw_chat_data.split("[")
# Iterate through messages
for element in splitted_chat_data:
# Reset variables after every message
datetime, sender, message = "", "", ""
# Strip unnecessary characters
element = element.strip("\r\n")
# Split message into date and content
item = element.split("]")
# Get date
datetime = item[0]
# Check if message was writted by name of a sender which
# should be analysed
for name in name_set:
# Get sender and content (equals last element in item array)
content = item[-1]
if name in content:
content = content.split(name)
sender = name
content = content[-1]
message = content[2:]
break
chat_messages[message_number] = {"datetime": datetime,
"sender":sender, "message":message}
message_number += 1
print("\nNumber of messages:\t%d\n" % message_number)
return chat_messages, name_set
...</code>
</pre>
<p class="text">
For example I was interested in the number of messages every participant was writing and how
many words he used in his messages, because
there are some participants that are relatively quit.
</p>
<div class="graph">
<p class="text bold">Number of words and messages by group member</p>
<canvas id="plot_wm"></canvas>
</div>
<p class="text">
I also wanted to know, which time is the best time to ask questions depending on the
activity of all participants. I often found myself
in situations where I asked a question and waited a long period of time since nobody was
active.
</p>
<div class="graph">
<p class="text bold">Activity by number of messages at specific daytime</p>
<canvas id="plot_daytime"></canvas>
</div>
<p class="text">
I got some very interesting results like in the plots above. You can find the complete code
on my <a href="https://github.com/Schlagoo/whatsapp_data_analysis"
style="color: #2F58F7">Github repository</a>!</p>
</div>
<div>
<div class="information border">
<p class="text"><b>Type</b></p>
<p class="text">Private project</p>
<p class="text"><b>Tools</b></p>
<p class="text">Python, Matplotlib</p>
<p class="text"><b>Partners</b></p>
<p class="text">-</p>
<p class="text"><b>Date</b></p>
<p class="text">2019-06-27</p>
<p class="text"><b>Source</b></p>
<p class="text">
<a href="https://github.com/Schlagoo/stock_data_analysis" style="color: #2F58F7">Github
repository</a>
</p>
</div>
</div>
</div>
</div>
</section>
<footer-portfolio></footer-portfolio>
</div>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.4.1/jquery.min.js"></script>
<script>
$(document).ready(function () {
$('#hamburger, #home, #proj, abo').click(function () {
$("#hamburger").toggleClass('open');
});
});
</script>
<script type="text/javascript" src="./main.js"></script>
<script>
// Number of words and messages
var ye = document.getElementById("plot_wm").getContext("2d");
var plot_wm = new Chart(ye, {
type: "bar",
data: {
labels: ["Pers. 1", "Pers. 2", "Pers. 3", "Pers. 4", "Pers. 5", "Pers. 6", "Pers. 7", "Pers. 8"],
datasets: [{
label: "Messages",
backgroundColor: "#E6AC5C",
borderColor: "#E6AC5C",
borderWidth: 2,
data: [484, 254, 838, 615, 320, 894, 819, 524]
}, {
label: "Words",
backgroundColor: "#2269E3",
borderColor: "#2269E3",
borderWidth: 2,
data: [2693, 1580, 4004, 4319, 2974, 7356, 5446, 3115]
}
]
},
options: {
legend: {
display: false
},
scales: {
yAxes: [{
ticks: {
beginAtZero: true
}
}]
}
}
});
// Daytime plot
var dte = document.getElementById("plot_daytime").getContext("2d");
var plot_daytime = new Chart(dte, {
type: "line",
data: {
labels: ["0", "1", "2", "3", "4", "5", "6", "7", "8", "9", "10", "11", "12", "13", "14", "15", "16", "17", "18", "19", "20", "21", "22", "23"],
datasets: [{
backgroundColor: "#2269E3",
borderColor: "#2269E3",
borderWidth: 2,
data: [58, 39, 24, 22, 1, 6, 19, 31, 55, 120, 168, 227, 282, 439, 332, 266, 367, 467, 447, 411, 370, 345, 183, 96]
}]
},
options: {
legend: {
display: false
},
tooltips: {
callbacks: {
label: function (tooltipItem) {
return tooltipItem.yLabel;
}
}
}
}
});
</script>
</body>
</html>