You cannot select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
Comrad/docs/comparisons.ipynb

3837 lines
230 KiB
Plaintext

4 years ago
{
"cells": [
{
"cell_type": "markdown",
"metadata": {},
"source": [
"# Comparison data science for no reason"
]
},
{
"cell_type": "code",
"execution_count": 1,
"metadata": {},
"outputs": [],
"source": [
"with open('comparisons.md') as f:\n",
" doc=f.read()"
]
},
{
"cell_type": "code",
"execution_count": 2,
"metadata": {},
"outputs": [],
"source": [
"datasets=[]\n",
"dataset=[]\n",
"header=None\n",
"for ln in doc.split('\\n'):\n",
" ln=ln.strip()\n",
" if ln.startswith('|'):\n",
" ln=ln[1:-1]\n",
" if header==None:\n",
" header=[x.strip() for x in ln.split('|')]\n",
" else:\n",
" data=[x.strip() for x in ln.split('|')]\n",
" if not data: continue\n",
" if set(data[0])=={'-'}: continue\n",
" data_d = dict(\n",
" (h,k) for h,k\n",
" in zip(header,data)\n",
" if h and k\n",
" )\n",
"# print(data_d)\n",
" dataset.append(data_d)\n",
" else:\n",
" header=None\n",
" if dataset: datasets.append(dataset)\n",
" dataset=[]"
]
},
{
"cell_type": "code",
"execution_count": 3,
"metadata": {},
"outputs": [
{
"data": {
"text/html": [
"<div>\n",
"<style scoped>\n",
" .dataframe tbody tr th:only-of-type {\n",
" vertical-align: middle;\n",
" }\n",
"\n",
" .dataframe tbody tr th {\n",
" vertical-align: top;\n",
" }\n",
"\n",
" .dataframe thead th {\n",
" text-align: right;\n",
" }\n",
"</style>\n",
"<table border=\"1\" class=\"dataframe\">\n",
" <thead>\n",
" <tr style=\"text-align: right;\">\n",
" <th></th>\n",
" <th>What is it?</th>\n",
" <th>Kind of like...</th>\n",
" <th>Decentralized? (P2P?)</th>\n",
" <th>Anonymous? (IP hidden?)</th>\n",
" <th>Confidential? (100% E2EE?)</th>\n",
" <th>Data robustness?</th>\n",
" <th>Identity verification?</th>\n",
" <th>Requires invitation/server?</th>\n",
" </tr>\n",
" <tr>\n",
" <th>Other cool thing</th>\n",
" <th></th>\n",
" <th></th>\n",
" <th></th>\n",
" <th></th>\n",
" <th></th>\n",
" <th></th>\n",
" <th></th>\n",
" <th></th>\n",
" </tr>\n",
" </thead>\n",
" <tbody>\n",
" <tr>\n",
" <th>*[Comrad](http://comrad.app)*</th>\n",
4 years ago
" <td>*Social network*</td>\n",
" <td>*Twitter*</td>\n",
" <td>❌ *No (central server on Tor)*</td>\n",
" <td>✔️ *Yes (everything routed via Tor)*</td>\n",
" <td>✔️ *Yes (100% E2EE)*</td>\n",
" <td>⭕ *Minimal server (deleted ASAP)*</td>\n",
" <td>✔️ *Yes (central public key repository)*</td>\n",
" <td>✔️ *No (works like twitter)*</td>\n",
" </tr>\n",
" <tr>\n",
" <th>[Secure Scuttlebutt](https://scuttlebutt.nz/)</th>\n",
" <td>Social network</td>\n",
" <td>Twitter / Facebook</td>\n",
" <td>✔️ Fully (P2P)</td>\n",
" <td>❌ No (P2P reveals IP; friend networks public)</td>\n",
" <td>⭕ Partly (private E2EE, public unencrypted)</td>\n",
" <td>✔️ Distributed across friend networks?</td>\n",
" <td>✔️ Yes? (federated key exchange?)</td>\n",
" <td>❌ Yes (need initial pub)</td>\n",
" </tr>\n",
" <tr>\n",
" <th>[Diaspora](https://diasporafoundation.org/)</th>\n",
" <td>Social network</td>\n",
" <td>Twitter</td>\n",
" <td>⭕ Halfway (federated)</td>\n",
" <td>⭕ No (unless via Tor Browser)</td>\n",
" <td>❌ No (unencrypted?)</td>\n",
" <td>✔️</td>\n",
" <td>?</td>\n",
" <td>❌ Yes (need 'pod' server)</td>\n",
" </tr>\n",
" <tr>\n",
" <th>[Mastodon](https://joinmastodon.org/)</th>\n",
" <td>Social network</td>\n",
" <td>Twitter</td>\n",
" <td>⭕ Halfway (federated)</td>\n",
" <td>⭕ No (unless via Tor Browser)</td>\n",
" <td>❌ No (unencrypted?)</td>\n",
" <td>✔️</td>\n",
" <td>?</td>\n",
" <td>❌ Yes (need 'instance' server)</td>\n",
" </tr>\n",
" <tr>\n",
" <th>[Matrix](https://matrix.org/)</th>\n",
" <td>Co-working space</td>\n",
" <td>Slack</td>\n",
" <td>⭕ Halfway (federated)</td>\n",
" <td>❌ No?</td>\n",
" <td>✔️ Yes? (100% E2EE)</td>\n",
" <td>?</td>\n",
" <td>✔️ Yes (?)</td>\n",
" <td>❌ Yes (invited channels only?)</td>\n",
" </tr>\n",
" <tr>\n",
" <th>[Briar Messenger](https://briarproject.org/)</th>\n",
" <td>Messenger</td>\n",
" <td>WhatsApp</td>\n",
" <td>✔️ Fully (P2P)</td>\n",
" <td>✔️ Yes? (Tor)</td>\n",
" <td>✔️ Yes (100% E2EE)</td>\n",
" <td>❌ None (needs 24/7 listener)</td>\n",
" <td>⭕ Partly (public keys traded IRL)</td>\n",
" <td>❌ Yes (need initial contact?)</td>\n",
" </tr>\n",
" <tr>\n",
" <th>[Cabal Chat](https://cabal.chat/)</th>\n",
" <td>Private chatrooms</td>\n",
" <td>IRC</td>\n",
" <td>✔️ Fully (P2P)</td>\n",
" <td>❌ No (P2P reveals IP)</td>\n",
" <td>⭕ Mostly (shared key, not E2EE)</td>\n",
" <td>✔️ Distributed Hash Table</td>\n",
" <td>❌ No (?)</td>\n",
" <td>✔️ Not really (public chat is open)</td>\n",
" </tr>\n",
" <tr>\n",
" <th>[Signal](https://signal.org/)</th>\n",
" <td>Messenger</td>\n",
" <td>WhatsApp</td>\n",
" <td>❌ No?</td>\n",
" <td>❌ No</td>\n",
" <td>✔️ Yes (E2EE, and audited)</td>\n",
" <td>?</td>\n",
" <td>?</td>\n",
" <td>✔️</td>\n",
" </tr>\n",
" </tbody>\n",
"</table>\n",
"</div>"
],
"text/plain": [
" What is it? \\\n",
"Other cool thing \n",
"*[Comrad](http://comrad.app)* *Social network* \n",
4 years ago
"[Secure Scuttlebutt](https://scuttlebutt.nz/) Social network \n",
"[Diaspora](https://diasporafoundation.org/) Social network \n",
"[Mastodon](https://joinmastodon.org/) Social network \n",
"[Matrix](https://matrix.org/) Co-working space \n",
"[Briar Messenger](https://briarproject.org/) Messenger \n",
"[Cabal Chat](https://cabal.chat/) Private chatrooms \n",
"[Signal](https://signal.org/) Messenger \n",
"\n",
" Kind of like... \\\n",
"Other cool thing \n",
"*[Comrad](http://comrad.app)* *Twitter* \n",
4 years ago
"[Secure Scuttlebutt](https://scuttlebutt.nz/) Twitter / Facebook \n",
"[Diaspora](https://diasporafoundation.org/) Twitter \n",
"[Mastodon](https://joinmastodon.org/) Twitter \n",
"[Matrix](https://matrix.org/) Slack \n",
"[Briar Messenger](https://briarproject.org/) WhatsApp \n",
"[Cabal Chat](https://cabal.chat/) IRC \n",
"[Signal](https://signal.org/) WhatsApp \n",
"\n",
" Decentralized? (P2P?) \\\n",
"Other cool thing \n",
"*[Comrad](http://comrad.app)* ❌ *No (central server on Tor)* \n",
4 years ago
"[Secure Scuttlebutt](https://scuttlebutt.nz/) ✔️ Fully (P2P) \n",
"[Diaspora](https://diasporafoundation.org/) ⭕ Halfway (federated) \n",
"[Mastodon](https://joinmastodon.org/) ⭕ Halfway (federated) \n",
"[Matrix](https://matrix.org/) ⭕ Halfway (federated) \n",
"[Briar Messenger](https://briarproject.org/) ✔️ Fully (P2P) \n",
"[Cabal Chat](https://cabal.chat/) ✔️ Fully (P2P) \n",
"[Signal](https://signal.org/) ❌ No? \n",
"\n",
" Anonymous? (IP hidden?) \\\n",
"Other cool thing \n",
"*[Comrad](http://comrad.app)* ✔️ *Yes (everything routed via Tor)* \n",
4 years ago
"[Secure Scuttlebutt](https://scuttlebutt.nz/) ❌ No (P2P reveals IP; friend networks public) \n",
"[Diaspora](https://diasporafoundation.org/) ⭕ No (unless via Tor Browser) \n",
"[Mastodon](https://joinmastodon.org/) ⭕ No (unless via Tor Browser) \n",
"[Matrix](https://matrix.org/) ❌ No? \n",
"[Briar Messenger](https://briarproject.org/) ✔️ Yes? (Tor) \n",
"[Cabal Chat](https://cabal.chat/) ❌ No (P2P reveals IP) \n",
"[Signal](https://signal.org/) ❌ No \n",
"\n",
" Confidential? (100% E2EE?) \\\n",
"Other cool thing \n",
"*[Comrad](http://comrad.app)* ✔️ *Yes (100% E2EE)* \n",
4 years ago
"[Secure Scuttlebutt](https://scuttlebutt.nz/) ⭕ Partly (private E2EE, public unencrypted) \n",
"[Diaspora](https://diasporafoundation.org/) ❌ No (unencrypted?) \n",
"[Mastodon](https://joinmastodon.org/) ❌ No (unencrypted?) \n",
"[Matrix](https://matrix.org/) ✔️ Yes? (100% E2EE) \n",
"[Briar Messenger](https://briarproject.org/) ✔️ Yes (100% E2EE) \n",
"[Cabal Chat](https://cabal.chat/) ⭕ Mostly (shared key, not E2EE) \n",
"[Signal](https://signal.org/) ✔️ Yes (E2EE, and audited) \n",
"\n",
" Data robustness? \\\n",
"Other cool thing \n",
"*[Comrad](http://comrad.app)* ⭕ *Minimal server (deleted ASAP)* \n",
4 years ago
"[Secure Scuttlebutt](https://scuttlebutt.nz/) ✔️ Distributed across friend networks? \n",
"[Diaspora](https://diasporafoundation.org/) ✔️ \n",
"[Mastodon](https://joinmastodon.org/) ✔️ \n",
"[Matrix](https://matrix.org/) ? \n",
"[Briar Messenger](https://briarproject.org/) ❌ None (needs 24/7 listener) \n",
"[Cabal Chat](https://cabal.chat/) ✔️ Distributed Hash Table \n",
"[Signal](https://signal.org/) ? \n",
"\n",
" Identity verification? \\\n",
"Other cool thing \n",
"*[Comrad](http://comrad.app)* ✔️ *Yes (central public key repository)* \n",
4 years ago
"[Secure Scuttlebutt](https://scuttlebutt.nz/) ✔️ Yes? (federated key exchange?) \n",
"[Diaspora](https://diasporafoundation.org/) ? \n",
"[Mastodon](https://joinmastodon.org/) ? \n",
"[Matrix](https://matrix.org/) ✔️ Yes (?) \n",
"[Briar Messenger](https://briarproject.org/) ⭕ Partly (public keys traded IRL) \n",
"[Cabal Chat](https://cabal.chat/) ❌ No (?) \n",
"[Signal](https://signal.org/) ? \n",
"\n",
" Requires invitation/server? \n",
"Other cool thing \n",
"*[Comrad](http://comrad.app)* ✔️ *No (works like twitter)* \n",
4 years ago
"[Secure Scuttlebutt](https://scuttlebutt.nz/) ❌ Yes (need initial pub) \n",
"[Diaspora](https://diasporafoundation.org/) ❌ Yes (need 'pod' server) \n",
"[Mastodon](https://joinmastodon.org/) ❌ Yes (need 'instance' server) \n",
"[Matrix](https://matrix.org/) ❌ Yes (invited channels only?) \n",
"[Briar Messenger](https://briarproject.org/) ❌ Yes (need initial contact?) \n",
"[Cabal Chat](https://cabal.chat/) ✔️ Not really (public chat is open) \n",
"[Signal](https://signal.org/) ✔️ "
]
},
"execution_count": 3,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"import pandas as pd\n",
"df1=pd.DataFrame(datasets[0]).set_index('Other cool thing')\n",
"df1"
]
},
{
"cell_type": "code",
"execution_count": 4,
"metadata": {},
"outputs": [
{
"data": {
"text/html": [
"<div>\n",
"<style scoped>\n",
" .dataframe tbody tr th:only-of-type {\n",
" vertical-align: middle;\n",
" }\n",
"\n",
" .dataframe tbody tr th {\n",
" vertical-align: top;\n",
" }\n",
"\n",
" .dataframe thead th {\n",
" text-align: right;\n",
" }\n",
"</style>\n",
"<table border=\"1\" class=\"dataframe\">\n",
" <thead>\n",
" <tr style=\"text-align: right;\">\n",
" <th></th>\n",
" <th>DM users (E2EE)</th>\n",
" <th>Group chat (E2EE)</th>\n",
" <th>Post to world</th>\n",
" <th>Post to friends/ties</th>\n",
" <th>Symmetric ties (friends)</th>\n",
" <th>Asymmetric ties (followers)</th>\n",
" <th>Like posts</th>\n",
" <th>Repost posts</th>\n",
" </tr>\n",
" <tr>\n",
" <th>Other cool thing</th>\n",
" <th></th>\n",
" <th></th>\n",
" <th></th>\n",
" <th></th>\n",
" <th></th>\n",
" <th></th>\n",
" <th></th>\n",
" <th></th>\n",
" </tr>\n",
" </thead>\n",
" <tbody>\n",
" <tr>\n",
" <th>*[Comrad](http://comrad.app)*</th>\n",
4 years ago
" <td>✔️</td>\n",
" <td>❌?</td>\n",
" <td>✔️</td>\n",
" <td>✔️</td>\n",
" <td>✔️</td>\n",
" <td>✔️</td>\n",
" <td>✔️?</td>\n",
" <td>❌</td>\n",
" </tr>\n",
" <tr>\n",
" <th>[Secure Scuttlebutt](https://scuttlebutt.nz/)</th>\n",
" <td>✔️</td>\n",
" <td>❌?</td>\n",
" <td>❌</td>\n",
" <td>✔️</td>\n",
" <td>✔️</td>\n",
" <td>✔️</td>\n",
" <td>✔️</td>\n",
" <td>❌?</td>\n",
" </tr>\n",
" <tr>\n",
" <th>[Diaspora](https://diasporafoundation.org/)</th>\n",
" <td>❌?</td>\n",
" <td>❌?</td>\n",
" <td>❌?</td>\n",
" <td>✔️</td>\n",
" <td>❌</td>\n",
" <td>✔️</td>\n",
" <td>✔️</td>\n",
" <td>✔️?</td>\n",
" </tr>\n",
" <tr>\n",
" <th>[Mastodon](https://joinmastodon.org/)</th>\n",
" <td>❌?</td>\n",
" <td>❌?</td>\n",
" <td>❌?</td>\n",
" <td>✔️</td>\n",
" <td>❌</td>\n",
" <td>✔️</td>\n",
" <td>✔️</td>\n",
" <td>✔️?</td>\n",
" </tr>\n",
" <tr>\n",
" <th>[Matrix](https://matrix.org/)</th>\n",
" <td>✔️</td>\n",
" <td>✔️</td>\n",
" <td>❌?</td>\n",
" <td>✔️</td>\n",
" <td>✔️</td>\n",
" <td>❌</td>\n",
" <td>❌?</td>\n",
" <td>❌?</td>\n",
" </tr>\n",
" <tr>\n",
" <th>[Briar Messenger](https://briarproject.org/)</th>\n",
" <td>✔️</td>\n",
" <td>✔️</td>\n",
" <td>❌?</td>\n",
" <td>✔️</td>\n",
" <td>✔️</td>\n",
" <td>❌</td>\n",
" <td>❌?</td>\n",
" <td>❌?</td>\n",
" </tr>\n",
" <tr>\n",
" <th>[Cabal Chat](https://cabal.chat/)</th>\n",
" <td>?</td>\n",
" <td>✔️</td>\n",
" <td>❌?</td>\n",
" <td>✔️</td>\n",
" <td>❌</td>\n",
" <td>❌</td>\n",
" <td>❌</td>\n",
" <td>❌</td>\n",
" </tr>\n",
" <tr>\n",
" <th>[Signal](https://signal.org/)</th>\n",
" <td>✔️</td>\n",
" <td>✔️</td>\n",
" <td>❌</td>\n",
" <td>❌</td>\n",
" <td>✔️</td>\n",
" <td>❌</td>\n",
" <td>❌</td>\n",
" <td>❌</td>\n",
" </tr>\n",
" </tbody>\n",
"</table>\n",
"</div>"
],
"text/plain": [
" DM users (E2EE) \\\n",
"Other cool thing \n",
"*[Comrad](http://comrad.app)* ✔️ \n",
4 years ago
"[Secure Scuttlebutt](https://scuttlebutt.nz/) ✔️ \n",
"[Diaspora](https://diasporafoundation.org/) ❌? \n",
"[Mastodon](https://joinmastodon.org/) ❌? \n",
"[Matrix](https://matrix.org/) ✔️ \n",
"[Briar Messenger](https://briarproject.org/) ✔️ \n",
"[Cabal Chat](https://cabal.chat/) ? \n",
"[Signal](https://signal.org/) ✔️ \n",
"\n",
" Group chat (E2EE) Post to world \\\n",
"Other cool thing \n",
"*[Comrad](http://comrad.app)* ❌? ✔️ \n",
4 years ago
"[Secure Scuttlebutt](https://scuttlebutt.nz/) ❌? ❌ \n",
"[Diaspora](https://diasporafoundation.org/) ❌? ❌? \n",
"[Mastodon](https://joinmastodon.org/) ❌? ❌? \n",
"[Matrix](https://matrix.org/) ✔️ ❌? \n",
"[Briar Messenger](https://briarproject.org/) ✔️ ❌? \n",
"[Cabal Chat](https://cabal.chat/) ✔️ ❌? \n",
"[Signal](https://signal.org/) ✔️ ❌ \n",
"\n",
" Post to friends/ties \\\n",
"Other cool thing \n",
"*[Comrad](http://comrad.app)* ✔️ \n",
4 years ago
"[Secure Scuttlebutt](https://scuttlebutt.nz/) ✔️ \n",
"[Diaspora](https://diasporafoundation.org/) ✔️ \n",
"[Mastodon](https://joinmastodon.org/) ✔️ \n",
"[Matrix](https://matrix.org/) ✔️ \n",
"[Briar Messenger](https://briarproject.org/) ✔️ \n",
"[Cabal Chat](https://cabal.chat/) ✔️ \n",
"[Signal](https://signal.org/) ❌ \n",
"\n",
" Symmetric ties (friends) \\\n",
"Other cool thing \n",
"*[Comrad](http://comrad.app)* ✔️ \n",
4 years ago
"[Secure Scuttlebutt](https://scuttlebutt.nz/) ✔️ \n",
"[Diaspora](https://diasporafoundation.org/) ❌ \n",
"[Mastodon](https://joinmastodon.org/) ❌ \n",
"[Matrix](https://matrix.org/) ✔️ \n",
"[Briar Messenger](https://briarproject.org/) ✔️ \n",
"[Cabal Chat](https://cabal.chat/) ❌ \n",
"[Signal](https://signal.org/) ✔️ \n",
"\n",
" Asymmetric ties (followers) \\\n",
"Other cool thing \n",
"*[Comrad](http://comrad.app)* ✔️ \n",
4 years ago
"[Secure Scuttlebutt](https://scuttlebutt.nz/) ✔️ \n",
"[Diaspora](https://diasporafoundation.org/) ✔️ \n",
"[Mastodon](https://joinmastodon.org/) ✔️ \n",
"[Matrix](https://matrix.org/) ❌ \n",
"[Briar Messenger](https://briarproject.org/) ❌ \n",
"[Cabal Chat](https://cabal.chat/) ❌ \n",
"[Signal](https://signal.org/) ❌ \n",
"\n",
" Like posts Repost posts \n",
"Other cool thing \n",
"*[Comrad](http://comrad.app)* ✔️? ❌ \n",
4 years ago
"[Secure Scuttlebutt](https://scuttlebutt.nz/) ✔️ ❌? \n",
"[Diaspora](https://diasporafoundation.org/) ✔️ ✔️? \n",
"[Mastodon](https://joinmastodon.org/) ✔️ ✔️? \n",
"[Matrix](https://matrix.org/) ❌? ❌? \n",
"[Briar Messenger](https://briarproject.org/) ❌? ❌? \n",
"[Cabal Chat](https://cabal.chat/) ❌ ❌ \n",
"[Signal](https://signal.org/) ❌ ❌ "
]
},
"execution_count": 4,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"import pandas as pd\n",
"df2=pd.DataFrame(datasets[1]).set_index('Other cool thing')\n",
"df2"
]
},
{
"cell_type": "code",
"execution_count": 5,
"metadata": {},
"outputs": [],
"source": [
"df = df1.join(df2)"
]
},
{
"cell_type": "code",
"execution_count": 6,
"metadata": {},
"outputs": [],
"source": [
"def transform(x):\n",
" return 1 if '✔️' in str(x) else 0\n"
]
},
{
"cell_type": "code",
"execution_count": 7,
"metadata": {},
"outputs": [
{
"data": {
"text/html": [
"<div>\n",
"<style scoped>\n",
" .dataframe tbody tr th:only-of-type {\n",
" vertical-align: middle;\n",
" }\n",
"\n",
" .dataframe tbody tr th {\n",
" vertical-align: top;\n",
" }\n",
"\n",
" .dataframe thead th {\n",
" text-align: right;\n",
" }\n",
"</style>\n",
"<table border=\"1\" class=\"dataframe\">\n",
" <thead>\n",
" <tr style=\"text-align: right;\">\n",
" <th></th>\n",
" <th>What is it?</th>\n",
" <th>Kind of like...</th>\n",
" <th>Decentralized? (P2P?)</th>\n",
" <th>Anonymous? (IP hidden?)</th>\n",
" <th>Confidential? (100% E2EE?)</th>\n",
" <th>Data robustness?</th>\n",
" <th>Identity verification?</th>\n",
" <th>Requires invitation/server?</th>\n",
" <th>DM users (E2EE)</th>\n",
" <th>Group chat (E2EE)</th>\n",
" <th>Post to world</th>\n",
" <th>Post to friends/ties</th>\n",
" <th>Symmetric ties (friends)</th>\n",
" <th>Asymmetric ties (followers)</th>\n",
" <th>Like posts</th>\n",
" <th>Repost posts</th>\n",
" </tr>\n",
" <tr>\n",
" <th>Other cool thing</th>\n",
" <th></th>\n",
" <th></th>\n",
" <th></th>\n",
" <th></th>\n",
" <th></th>\n",
" <th></th>\n",
" <th></th>\n",
" <th></th>\n",
" <th></th>\n",
" <th></th>\n",
" <th></th>\n",
" <th></th>\n",
" <th></th>\n",
" <th></th>\n",
" <th></th>\n",
" <th></th>\n",
" </tr>\n",
" </thead>\n",
" <tbody>\n",
" <tr>\n",
" <th>*[Comrad](http://comrad.app)*</th>\n",
4 years ago
" <td>*Social network*</td>\n",
" <td>*Twitter*</td>\n",
" <td>❌ *No (central server on Tor)*</td>\n",
" <td>✔️ *Yes (everything routed via Tor)*</td>\n",
" <td>✔️ *Yes (100% E2EE)*</td>\n",
" <td>⭕ *Minimal server (deleted ASAP)*</td>\n",
" <td>✔️ *Yes (central public key repository)*</td>\n",
" <td>✔️ *No (works like twitter)*</td>\n",
" <td>✔️</td>\n",
" <td>❌?</td>\n",
" <td>✔️</td>\n",
" <td>✔️</td>\n",
" <td>✔️</td>\n",
" <td>✔️</td>\n",
" <td>✔️?</td>\n",
" <td>❌</td>\n",
" </tr>\n",
" <tr>\n",
" <th>[Secure Scuttlebutt](https://scuttlebutt.nz/)</th>\n",
" <td>Social network</td>\n",
" <td>Twitter / Facebook</td>\n",
" <td>✔️ Fully (P2P)</td>\n",
" <td>❌ No (P2P reveals IP; friend networks public)</td>\n",
" <td>⭕ Partly (private E2EE, public unencrypted)</td>\n",
" <td>✔️ Distributed across friend networks?</td>\n",
" <td>✔️ Yes? (federated key exchange?)</td>\n",
" <td>❌ Yes (need initial pub)</td>\n",
" <td>✔️</td>\n",
" <td>❌?</td>\n",
" <td>❌</td>\n",
" <td>✔️</td>\n",
" <td>✔️</td>\n",
" <td>✔️</td>\n",
" <td>✔️</td>\n",
" <td>❌?</td>\n",
" </tr>\n",
" <tr>\n",
" <th>[Diaspora](https://diasporafoundation.org/)</th>\n",
" <td>Social network</td>\n",
" <td>Twitter</td>\n",
" <td>⭕ Halfway (federated)</td>\n",
" <td>⭕ No (unless via Tor Browser)</td>\n",
" <td>❌ No (unencrypted?)</td>\n",
" <td>✔️</td>\n",
" <td>?</td>\n",
" <td>❌ Yes (need 'pod' server)</td>\n",
" <td>❌?</td>\n",
" <td>❌?</td>\n",
" <td>❌?</td>\n",
" <td>✔️</td>\n",
" <td>❌</td>\n",
" <td>✔️</td>\n",
" <td>✔️</td>\n",
" <td>✔️?</td>\n",
" </tr>\n",
" <tr>\n",
" <th>[Mastodon](https://joinmastodon.org/)</th>\n",
" <td>Social network</td>\n",
" <td>Twitter</td>\n",
" <td>⭕ Halfway (federated)</td>\n",
" <td>⭕ No (unless via Tor Browser)</td>\n",
" <td>❌ No (unencrypted?)</td>\n",
" <td>✔️</td>\n",
" <td>?</td>\n",
" <td>❌ Yes (need 'instance' server)</td>\n",
" <td>❌?</td>\n",
" <td>❌?</td>\n",
" <td>❌?</td>\n",
" <td>✔️</td>\n",
" <td>❌</td>\n",
" <td>✔️</td>\n",
" <td>✔️</td>\n",
" <td>✔️?</td>\n",
" </tr>\n",
" <tr>\n",
" <th>[Matrix](https://matrix.org/)</th>\n",
" <td>Co-working space</td>\n",
" <td>Slack</td>\n",
" <td>⭕ Halfway (federated)</td>\n",
" <td>❌ No?</td>\n",
" <td>✔️ Yes? (100% E2EE)</td>\n",
" <td>?</td>\n",
" <td>✔️ Yes (?)</td>\n",
" <td>❌ Yes (invited channels only?)</td>\n",
" <td>✔️</td>\n",
" <td>✔️</td>\n",
" <td>❌?</td>\n",
" <td>✔️</td>\n",
" <td>✔️</td>\n",
" <td>❌</td>\n",
" <td>❌?</td>\n",
" <td>❌?</td>\n",
" </tr>\n",
" <tr>\n",
" <th>[Briar Messenger](https://briarproject.org/)</th>\n",
" <td>Messenger</td>\n",
" <td>WhatsApp</td>\n",
" <td>✔️ Fully (P2P)</td>\n",
" <td>✔️ Yes? (Tor)</td>\n",
" <td>✔️ Yes (100% E2EE)</td>\n",
" <td>❌ None (needs 24/7 listener)</td>\n",
" <td>⭕ Partly (public keys traded IRL)</td>\n",
" <td>❌ Yes (need initial contact?)</td>\n",
" <td>✔️</td>\n",
" <td>✔️</td>\n",
" <td>❌?</td>\n",
" <td>✔️</td>\n",
" <td>✔️</td>\n",
" <td>❌</td>\n",
" <td>❌?</td>\n",
" <td>❌?</td>\n",
" </tr>\n",
" <tr>\n",
" <th>[Cabal Chat](https://cabal.chat/)</th>\n",
" <td>Private chatrooms</td>\n",
" <td>IRC</td>\n",
" <td>✔️ Fully (P2P)</td>\n",
" <td>❌ No (P2P reveals IP)</td>\n",
" <td>⭕ Mostly (shared key, not E2EE)</td>\n",
" <td>✔️ Distributed Hash Table</td>\n",
" <td>❌ No (?)</td>\n",
" <td>✔️ Not really (public chat is open)</td>\n",
" <td>?</td>\n",
" <td>✔️</td>\n",
" <td>❌?</td>\n",
" <td>✔️</td>\n",
" <td>❌</td>\n",
" <td>❌</td>\n",
" <td>❌</td>\n",
" <td>❌</td>\n",
" </tr>\n",
" <tr>\n",
" <th>[Signal](https://signal.org/)</th>\n",
" <td>Messenger</td>\n",
" <td>WhatsApp</td>\n",
" <td>❌ No?</td>\n",
" <td>❌ No</td>\n",
" <td>✔️ Yes (E2EE, and audited)</td>\n",
" <td>?</td>\n",
" <td>?</td>\n",
" <td>✔️</td>\n",
" <td>✔️</td>\n",
" <td>✔️</td>\n",
" <td>❌</td>\n",
" <td>❌</td>\n",
" <td>✔️</td>\n",
" <td>❌</td>\n",
" <td>❌</td>\n",
" <td>❌</td>\n",
" </tr>\n",
" </tbody>\n",
"</table>\n",
"</div>"
],
"text/plain": [
" What is it? \\\n",
"Other cool thing \n",
"*[Comrad](http://comrad.app)* *Social network* \n",
4 years ago
"[Secure Scuttlebutt](https://scuttlebutt.nz/) Social network \n",
"[Diaspora](https://diasporafoundation.org/) Social network \n",
"[Mastodon](https://joinmastodon.org/) Social network \n",
"[Matrix](https://matrix.org/) Co-working space \n",
"[Briar Messenger](https://briarproject.org/) Messenger \n",
"[Cabal Chat](https://cabal.chat/) Private chatrooms \n",
"[Signal](https://signal.org/) Messenger \n",
"\n",
" Kind of like... \\\n",
"Other cool thing \n",
"*[Comrad](http://comrad.app)* *Twitter* \n",
4 years ago
"[Secure Scuttlebutt](https://scuttlebutt.nz/) Twitter / Facebook \n",
"[Diaspora](https://diasporafoundation.org/) Twitter \n",
"[Mastodon](https://joinmastodon.org/) Twitter \n",
"[Matrix](https://matrix.org/) Slack \n",
"[Briar Messenger](https://briarproject.org/) WhatsApp \n",
"[Cabal Chat](https://cabal.chat/) IRC \n",
"[Signal](https://signal.org/) WhatsApp \n",
"\n",
" Decentralized? (P2P?) \\\n",
"Other cool thing \n",
"*[Comrad](http://comrad.app)* ❌ *No (central server on Tor)* \n",
4 years ago
"[Secure Scuttlebutt](https://scuttlebutt.nz/) ✔️ Fully (P2P) \n",
"[Diaspora](https://diasporafoundation.org/) ⭕ Halfway (federated) \n",
"[Mastodon](https://joinmastodon.org/) ⭕ Halfway (federated) \n",
"[Matrix](https://matrix.org/) ⭕ Halfway (federated) \n",
"[Briar Messenger](https://briarproject.org/) ✔️ Fully (P2P) \n",
"[Cabal Chat](https://cabal.chat/) ✔️ Fully (P2P) \n",
"[Signal](https://signal.org/) ❌ No? \n",
"\n",
" Anonymous? (IP hidden?) \\\n",
"Other cool thing \n",
"*[Comrad](http://comrad.app)* ✔️ *Yes (everything routed via Tor)* \n",
4 years ago
"[Secure Scuttlebutt](https://scuttlebutt.nz/) ❌ No (P2P reveals IP; friend networks public) \n",
"[Diaspora](https://diasporafoundation.org/) ⭕ No (unless via Tor Browser) \n",
"[Mastodon](https://joinmastodon.org/) ⭕ No (unless via Tor Browser) \n",
"[Matrix](https://matrix.org/) ❌ No? \n",
"[Briar Messenger](https://briarproject.org/) ✔️ Yes? (Tor) \n",
"[Cabal Chat](https://cabal.chat/) ❌ No (P2P reveals IP) \n",
"[Signal](https://signal.org/) ❌ No \n",
"\n",
" Confidential? (100% E2EE?) \\\n",
"Other cool thing \n",
"*[Comrad](http://comrad.app)* ✔️ *Yes (100% E2EE)* \n",
4 years ago
"[Secure Scuttlebutt](https://scuttlebutt.nz/) ⭕ Partly (private E2EE, public unencrypted) \n",
"[Diaspora](https://diasporafoundation.org/) ❌ No (unencrypted?) \n",
"[Mastodon](https://joinmastodon.org/) ❌ No (unencrypted?) \n",
"[Matrix](https://matrix.org/) ✔️ Yes? (100% E2EE) \n",
"[Briar Messenger](https://briarproject.org/) ✔️ Yes (100% E2EE) \n",
"[Cabal Chat](https://cabal.chat/) ⭕ Mostly (shared key, not E2EE) \n",
"[Signal](https://signal.org/) ✔️ Yes (E2EE, and audited) \n",
"\n",
" Data robustness? \\\n",
"Other cool thing \n",
"*[Comrad](http://comrad.app)* ⭕ *Minimal server (deleted ASAP)* \n",
4 years ago
"[Secure Scuttlebutt](https://scuttlebutt.nz/) ✔️ Distributed across friend networks? \n",
"[Diaspora](https://diasporafoundation.org/) ✔️ \n",
"[Mastodon](https://joinmastodon.org/) ✔️ \n",
"[Matrix](https://matrix.org/) ? \n",
"[Briar Messenger](https://briarproject.org/) ❌ None (needs 24/7 listener) \n",
"[Cabal Chat](https://cabal.chat/) ✔️ Distributed Hash Table \n",
"[Signal](https://signal.org/) ? \n",
"\n",
" Identity verification? \\\n",
"Other cool thing \n",
"*[Comrad](http://comrad.app)* ✔️ *Yes (central public key repository)* \n",
4 years ago
"[Secure Scuttlebutt](https://scuttlebutt.nz/) ✔️ Yes? (federated key exchange?) \n",
"[Diaspora](https://diasporafoundation.org/) ? \n",
"[Mastodon](https://joinmastodon.org/) ? \n",
"[Matrix](https://matrix.org/) ✔️ Yes (?) \n",
"[Briar Messenger](https://briarproject.org/) ⭕ Partly (public keys traded IRL) \n",
"[Cabal Chat](https://cabal.chat/) ❌ No (?) \n",
"[Signal](https://signal.org/) ? \n",
"\n",
" Requires invitation/server? \\\n",
"Other cool thing \n",
"*[Comrad](http://comrad.app)* ✔️ *No (works like twitter)* \n",
4 years ago
"[Secure Scuttlebutt](https://scuttlebutt.nz/) ❌ Yes (need initial pub) \n",
"[Diaspora](https://diasporafoundation.org/) ❌ Yes (need 'pod' server) \n",
"[Mastodon](https://joinmastodon.org/) ❌ Yes (need 'instance' server) \n",
"[Matrix](https://matrix.org/) ❌ Yes (invited channels only?) \n",
"[Briar Messenger](https://briarproject.org/) ❌ Yes (need initial contact?) \n",
"[Cabal Chat](https://cabal.chat/) ✔️ Not really (public chat is open) \n",
"[Signal](https://signal.org/) ✔️ \n",
"\n",
" DM users (E2EE) \\\n",
"Other cool thing \n",
"*[Comrad](http://comrad.app)* ✔️ \n",
4 years ago
"[Secure Scuttlebutt](https://scuttlebutt.nz/) ✔️ \n",
"[Diaspora](https://diasporafoundation.org/) ❌? \n",
"[Mastodon](https://joinmastodon.org/) ❌? \n",
"[Matrix](https://matrix.org/) ✔️ \n",
"[Briar Messenger](https://briarproject.org/) ✔️ \n",
"[Cabal Chat](https://cabal.chat/) ? \n",
"[Signal](https://signal.org/) ✔️ \n",
"\n",
" Group chat (E2EE) Post to world \\\n",
"Other cool thing \n",
"*[Comrad](http://comrad.app)* ❌? ✔️ \n",
4 years ago
"[Secure Scuttlebutt](https://scuttlebutt.nz/) ❌? ❌ \n",
"[Diaspora](https://diasporafoundation.org/) ❌? ❌? \n",
"[Mastodon](https://joinmastodon.org/) ❌? ❌? \n",
"[Matrix](https://matrix.org/) ✔️ ❌? \n",
"[Briar Messenger](https://briarproject.org/) ✔️ ❌? \n",
"[Cabal Chat](https://cabal.chat/) ✔️ ❌? \n",
"[Signal](https://signal.org/) ✔️ ❌ \n",
"\n",
" Post to friends/ties \\\n",
"Other cool thing \n",
"*[Comrad](http://comrad.app)* ✔️ \n",
4 years ago
"[Secure Scuttlebutt](https://scuttlebutt.nz/) ✔️ \n",
"[Diaspora](https://diasporafoundation.org/) ✔️ \n",
"[Mastodon](https://joinmastodon.org/) ✔️ \n",
"[Matrix](https://matrix.org/) ✔️ \n",
"[Briar Messenger](https://briarproject.org/) ✔️ \n",
"[Cabal Chat](https://cabal.chat/) ✔️ \n",
"[Signal](https://signal.org/) ❌ \n",
"\n",
" Symmetric ties (friends) \\\n",
"Other cool thing \n",
"*[Comrad](http://comrad.app)* ✔️ \n",
4 years ago
"[Secure Scuttlebutt](https://scuttlebutt.nz/) ✔️ \n",
"[Diaspora](https://diasporafoundation.org/) ❌ \n",
"[Mastodon](https://joinmastodon.org/) ❌ \n",
"[Matrix](https://matrix.org/) ✔️ \n",
"[Briar Messenger](https://briarproject.org/) ✔️ \n",
"[Cabal Chat](https://cabal.chat/) ❌ \n",
"[Signal](https://signal.org/) ✔️ \n",
"\n",
" Asymmetric ties (followers) \\\n",
"Other cool thing \n",
"*[Comrad](http://comrad.app)* ✔️ \n",
4 years ago
"[Secure Scuttlebutt](https://scuttlebutt.nz/) ✔️ \n",
"[Diaspora](https://diasporafoundation.org/) ✔️ \n",
"[Mastodon](https://joinmastodon.org/) ✔️ \n",
"[Matrix](https://matrix.org/) ❌ \n",
"[Briar Messenger](https://briarproject.org/) ❌ \n",
"[Cabal Chat](https://cabal.chat/) ❌ \n",
"[Signal](https://signal.org/) ❌ \n",
"\n",
" Like posts Repost posts \n",
"Other cool thing \n",
"*[Comrad](http://comrad.app)* ✔️? ❌ \n",
4 years ago
"[Secure Scuttlebutt](https://scuttlebutt.nz/) ✔️ ❌? \n",
"[Diaspora](https://diasporafoundation.org/) ✔️ ✔️? \n",
"[Mastodon](https://joinmastodon.org/) ✔️ ✔️? \n",
"[Matrix](https://matrix.org/) ❌? ❌? \n",
"[Briar Messenger](https://briarproject.org/) ❌? ❌? \n",
"[Cabal Chat](https://cabal.chat/) ❌ ❌ \n",
"[Signal](https://signal.org/) ❌ ❌ "
]
},
"execution_count": 7,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"df"
]
},
{
"cell_type": "code",
"execution_count": 8,
"metadata": {},
"outputs": [
{
"data": {
"text/plain": [
"(['*[Comrad](http://comrad.app)*',\n",
4 years ago
" '[Secure Scuttlebutt](https://scuttlebutt.nz/)',\n",
" '[Diaspora](https://diasporafoundation.org/)',\n",
" '[Mastodon](https://joinmastodon.org/)',\n",
" '[Matrix](https://matrix.org/)',\n",
" '[Briar Messenger](https://briarproject.org/)',\n",
" '[Cabal Chat](https://cabal.chat/)',\n",
" '[Signal](https://signal.org/)'],\n",
" ['What is it?',\n",
" 'Kind of like...',\n",
" 'Decentralized? (P2P?)',\n",
" 'Anonymous? (IP hidden?)',\n",
" 'Confidential? (100% E2EE?)',\n",
" 'Data robustness?',\n",
" 'Identity verification?',\n",
" 'Requires invitation/server?',\n",
" 'DM users (E2EE)',\n",
" 'Group chat (E2EE)',\n",
" 'Post to world',\n",
" 'Post to friends/ties',\n",
" 'Symmetric ties (friends)',\n",
" 'Asymmetric ties (followers)',\n",
" 'Like posts',\n",
" 'Repost posts'])"
]
},
"execution_count": 8,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"index_orig = list(df.index)\n",
"cols_orig = list(df.columns)\n",
"index_orig, cols_orig"
]
},
{
"cell_type": "code",
"execution_count": 9,
"metadata": {},
"outputs": [
{
"data": {
"text/html": [
"<div>\n",
"<style scoped>\n",
" .dataframe tbody tr th:only-of-type {\n",
" vertical-align: middle;\n",
" }\n",
"\n",
" .dataframe tbody tr th {\n",
" vertical-align: top;\n",
" }\n",
"\n",
" .dataframe thead th {\n",
" text-align: right;\n",
" }\n",
"</style>\n",
"<table border=\"1\" class=\"dataframe\">\n",
" <thead>\n",
" <tr style=\"text-align: right;\">\n",
" <th></th>\n",
" <th>What is it?</th>\n",
" <th>Kind of like...</th>\n",
" <th>Decentralized? (P2P?)</th>\n",
" <th>Anonymous? (IP hidden?)</th>\n",
" <th>Confidential? (100% E2EE?)</th>\n",
" <th>Data robustness?</th>\n",
" <th>Identity verification?</th>\n",
" <th>Requires invitation/server?</th>\n",
" <th>DM users (E2EE)</th>\n",
" <th>Group chat (E2EE)</th>\n",
" <th>Post to world</th>\n",
" <th>Post to friends/ties</th>\n",
" <th>Symmetric ties (friends)</th>\n",
" <th>Asymmetric ties (followers)</th>\n",
" <th>Like posts</th>\n",
" <th>Repost posts</th>\n",
" </tr>\n",
" </thead>\n",
" <tbody>\n",
" <tr>\n",
" <th>Comrad</th>\n",
4 years ago
" <td>*Social network*</td>\n",
" <td>*Twitter*</td>\n",
" <td>❌ *No (central server on Tor)*</td>\n",
" <td>✔️ *Yes (everything routed via Tor)*</td>\n",
" <td>✔️ *Yes (100% E2EE)*</td>\n",
" <td>⭕ *Minimal server (deleted ASAP)*</td>\n",
" <td>✔️ *Yes (central public key repository)*</td>\n",
" <td>✔️ *No (works like twitter)*</td>\n",
" <td>✔️</td>\n",
" <td>❌?</td>\n",
" <td>✔️</td>\n",
" <td>✔️</td>\n",
" <td>✔️</td>\n",
" <td>✔️</td>\n",
" <td>✔️?</td>\n",
" <td>❌</td>\n",
" </tr>\n",
" <tr>\n",
" <th>SecureScuttlebutt</th>\n",
" <td>Social network</td>\n",
" <td>Twitter / Facebook</td>\n",
" <td>✔️ Fully (P2P)</td>\n",
" <td>❌ No (P2P reveals IP; friend networks public)</td>\n",
" <td>⭕ Partly (private E2EE, public unencrypted)</td>\n",
" <td>✔️ Distributed across friend networks?</td>\n",
" <td>✔️ Yes? (federated key exchange?)</td>\n",
" <td>❌ Yes (need initial pub)</td>\n",
" <td>✔️</td>\n",
" <td>❌?</td>\n",
" <td>❌</td>\n",
" <td>✔️</td>\n",
" <td>✔️</td>\n",
" <td>✔️</td>\n",
" <td>✔️</td>\n",
" <td>❌?</td>\n",
" </tr>\n",
" <tr>\n",
" <th>Diaspora</th>\n",
" <td>Social network</td>\n",
" <td>Twitter</td>\n",
" <td>⭕ Halfway (federated)</td>\n",
" <td>⭕ No (unless via Tor Browser)</td>\n",
" <td>❌ No (unencrypted?)</td>\n",
" <td>✔️</td>\n",
" <td>?</td>\n",
" <td>❌ Yes (need 'pod' server)</td>\n",
" <td>❌?</td>\n",
" <td>❌?</td>\n",
" <td>❌?</td>\n",
" <td>✔️</td>\n",
" <td>❌</td>\n",
" <td>✔️</td>\n",
" <td>✔️</td>\n",
" <td>✔️?</td>\n",
" </tr>\n",
" <tr>\n",
" <th>Mastodon</th>\n",
" <td>Social network</td>\n",
" <td>Twitter</td>\n",
" <td>⭕ Halfway (federated)</td>\n",
" <td>⭕ No (unless via Tor Browser)</td>\n",
" <td>❌ No (unencrypted?)</td>\n",
" <td>✔️</td>\n",
" <td>?</td>\n",
" <td>❌ Yes (need 'instance' server)</td>\n",
" <td>❌?</td>\n",
" <td>❌?</td>\n",
" <td>❌?</td>\n",
" <td>✔️</td>\n",
" <td>❌</td>\n",
" <td>✔️</td>\n",
" <td>✔️</td>\n",
" <td>✔️?</td>\n",
" </tr>\n",
" <tr>\n",
" <th>Matrix</th>\n",
" <td>Co-working space</td>\n",
" <td>Slack</td>\n",
" <td>⭕ Halfway (federated)</td>\n",
" <td>❌ No?</td>\n",
" <td>✔️ Yes? (100% E2EE)</td>\n",
" <td>?</td>\n",
" <td>✔️ Yes (?)</td>\n",
" <td>❌ Yes (invited channels only?)</td>\n",
" <td>✔️</td>\n",
" <td>✔️</td>\n",
" <td>❌?</td>\n",
" <td>✔️</td>\n",
" <td>✔️</td>\n",
" <td>❌</td>\n",
" <td>❌?</td>\n",
" <td>❌?</td>\n",
" </tr>\n",
" <tr>\n",
" <th>BriarMessenger</th>\n",
" <td>Messenger</td>\n",
" <td>WhatsApp</td>\n",
" <td>✔️ Fully (P2P)</td>\n",
" <td>✔️ Yes? (Tor)</td>\n",
" <td>✔️ Yes (100% E2EE)</td>\n",
" <td>❌ None (needs 24/7 listener)</td>\n",
" <td>⭕ Partly (public keys traded IRL)</td>\n",
" <td>❌ Yes (need initial contact?)</td>\n",
" <td>✔️</td>\n",
" <td>✔️</td>\n",
" <td>❌?</td>\n",
" <td>✔️</td>\n",
" <td>✔️</td>\n",
" <td>❌</td>\n",
" <td>❌?</td>\n",
" <td>❌?</td>\n",
" </tr>\n",
" <tr>\n",
" <th>CabalChat</th>\n",
" <td>Private chatrooms</td>\n",
" <td>IRC</td>\n",
" <td>✔️ Fully (P2P)</td>\n",
" <td>❌ No (P2P reveals IP)</td>\n",
" <td>⭕ Mostly (shared key, not E2EE)</td>\n",
" <td>✔️ Distributed Hash Table</td>\n",
" <td>❌ No (?)</td>\n",
" <td>✔️ Not really (public chat is open)</td>\n",
" <td>?</td>\n",
" <td>✔️</td>\n",
" <td>❌?</td>\n",
" <td>✔️</td>\n",
" <td>❌</td>\n",
" <td>❌</td>\n",
" <td>❌</td>\n",
" <td>❌</td>\n",
" </tr>\n",
" <tr>\n",
" <th>Signal</th>\n",
" <td>Messenger</td>\n",
" <td>WhatsApp</td>\n",
" <td>❌ No?</td>\n",
" <td>❌ No</td>\n",
" <td>✔️ Yes (E2EE, and audited)</td>\n",
" <td>?</td>\n",
" <td>?</td>\n",
" <td>✔️</td>\n",
" <td>✔️</td>\n",
" <td>✔️</td>\n",
" <td>❌</td>\n",
" <td>❌</td>\n",
" <td>✔️</td>\n",
" <td>❌</td>\n",
" <td>❌</td>\n",
" <td>❌</td>\n",
" </tr>\n",
" </tbody>\n",
"</table>\n",
"</div>"
],
"text/plain": [
" What is it? Kind of like... \\\n",
"Comrad *Social network* *Twitter* \n",
4 years ago
"SecureScuttlebutt Social network Twitter / Facebook \n",
"Diaspora Social network Twitter \n",
"Mastodon Social network Twitter \n",
"Matrix Co-working space Slack \n",
"BriarMessenger Messenger WhatsApp \n",
"CabalChat Private chatrooms IRC \n",
"Signal Messenger WhatsApp \n",
"\n",
" Decentralized? (P2P?) \\\n",
"Comrad ❌ *No (central server on Tor)* \n",
4 years ago
"SecureScuttlebutt ✔️ Fully (P2P) \n",
"Diaspora ⭕ Halfway (federated) \n",
"Mastodon ⭕ Halfway (federated) \n",
"Matrix ⭕ Halfway (federated) \n",
"BriarMessenger ✔️ Fully (P2P) \n",
"CabalChat ✔️ Fully (P2P) \n",
"Signal ❌ No? \n",
"\n",
" Anonymous? (IP hidden?) \\\n",
"Comrad ✔️ *Yes (everything routed via Tor)* \n",
4 years ago
"SecureScuttlebutt ❌ No (P2P reveals IP; friend networks public) \n",
"Diaspora ⭕ No (unless via Tor Browser) \n",
"Mastodon ⭕ No (unless via Tor Browser) \n",
"Matrix ❌ No? \n",
"BriarMessenger ✔️ Yes? (Tor) \n",
"CabalChat ❌ No (P2P reveals IP) \n",
"Signal ❌ No \n",
"\n",
" Confidential? (100% E2EE?) \\\n",
"Comrad ✔️ *Yes (100% E2EE)* \n",
4 years ago
"SecureScuttlebutt ⭕ Partly (private E2EE, public unencrypted) \n",
"Diaspora ❌ No (unencrypted?) \n",
"Mastodon ❌ No (unencrypted?) \n",
"Matrix ✔️ Yes? (100% E2EE) \n",
"BriarMessenger ✔️ Yes (100% E2EE) \n",
"CabalChat ⭕ Mostly (shared key, not E2EE) \n",
"Signal ✔️ Yes (E2EE, and audited) \n",
"\n",
" Data robustness? \\\n",
"Comrad ⭕ *Minimal server (deleted ASAP)* \n",
4 years ago
"SecureScuttlebutt ✔️ Distributed across friend networks? \n",
"Diaspora ✔️ \n",
"Mastodon ✔️ \n",
"Matrix ? \n",
"BriarMessenger ❌ None (needs 24/7 listener) \n",
"CabalChat ✔️ Distributed Hash Table \n",
"Signal ? \n",
"\n",
" Identity verification? \\\n",
"Comrad ✔️ *Yes (central public key repository)* \n",
4 years ago
"SecureScuttlebutt ✔️ Yes? (federated key exchange?) \n",
"Diaspora ? \n",
"Mastodon ? \n",
"Matrix ✔️ Yes (?) \n",
"BriarMessenger ⭕ Partly (public keys traded IRL) \n",
"CabalChat ❌ No (?) \n",
"Signal ? \n",
"\n",
" Requires invitation/server? DM users (E2EE) \\\n",
"Comrad ✔️ *No (works like twitter)* ✔️ \n",
4 years ago
"SecureScuttlebutt ❌ Yes (need initial pub) ✔️ \n",
"Diaspora ❌ Yes (need 'pod' server) ❌? \n",
"Mastodon ❌ Yes (need 'instance' server) ❌? \n",
"Matrix ❌ Yes (invited channels only?) ✔️ \n",
"BriarMessenger ❌ Yes (need initial contact?) ✔️ \n",
"CabalChat ✔️ Not really (public chat is open) ? \n",
"Signal ✔️ ✔️ \n",
"\n",
" Group chat (E2EE) Post to world Post to friends/ties \\\n",
"Comrad ❌? ✔️ ✔️ \n",
4 years ago
"SecureScuttlebutt ❌? ❌ ✔️ \n",
"Diaspora ❌? ❌? ✔️ \n",
"Mastodon ❌? ❌? ✔️ \n",
"Matrix ✔️ ❌? ✔️ \n",
"BriarMessenger ✔️ ❌? ✔️ \n",
"CabalChat ✔️ ❌? ✔️ \n",
"Signal ✔️ ❌ ❌ \n",
"\n",
" Symmetric ties (friends) Asymmetric ties (followers) \\\n",
"Comrad ✔️ ✔️ \n",
4 years ago
"SecureScuttlebutt ✔️ ✔️ \n",
"Diaspora ❌ ✔️ \n",
"Mastodon ❌ ✔️ \n",
"Matrix ✔️ ❌ \n",
"BriarMessenger ✔️ ❌ \n",
"CabalChat ❌ ❌ \n",
"Signal ✔️ ❌ \n",
"\n",
" Like posts Repost posts \n",
"Comrad ✔️? ❌ \n",
4 years ago
"SecureScuttlebutt ✔️ ❌? \n",
"Diaspora ✔️ ✔️? \n",
"Mastodon ✔️ ✔️? \n",
"Matrix ❌? ❌? \n",
"BriarMessenger ❌? ❌? \n",
"CabalChat ❌ ❌ \n",
"Signal ❌ ❌ "
]
},
"execution_count": 9,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"df_safe = pd.DataFrame(df)\n",
"df_safe.index = [x.split('[')[1].split(']')[0].replace(' ','') for x in index_orig]\n",
"df_safe"
]
},
{
"cell_type": "code",
"execution_count": 10,
"metadata": {},
"outputs": [],
"source": [
"df.columns = [\n",
" #''.join(x for x in col.split('(')[0] if x.isalpha())\n",
" col\n",
" for col in cols_orig\n",
"]"
]
},
{
"cell_type": "code",
"execution_count": 11,
"metadata": {},
"outputs": [
{
"data": {
"text/html": [
"<div>\n",
"<style scoped>\n",
" .dataframe tbody tr th:only-of-type {\n",
" vertical-align: middle;\n",
" }\n",
"\n",
" .dataframe tbody tr th {\n",
" vertical-align: top;\n",
" }\n",
"\n",
" .dataframe thead th {\n",
" text-align: right;\n",
" }\n",
"</style>\n",
"<table border=\"1\" class=\"dataframe\">\n",
" <thead>\n",
" <tr style=\"text-align: right;\">\n",
" <th></th>\n",
" <th>What is it?</th>\n",
" <th>Kind of like...</th>\n",
" <th>Decentralized? (P2P?)</th>\n",
" <th>Anonymous? (IP hidden?)</th>\n",
" <th>Confidential? (100% E2EE?)</th>\n",
" <th>Data robustness?</th>\n",
" <th>Identity verification?</th>\n",
" <th>Requires invitation/server?</th>\n",
" <th>DM users (E2EE)</th>\n",
" <th>Group chat (E2EE)</th>\n",
" <th>Post to world</th>\n",
" <th>Post to friends/ties</th>\n",
" <th>Symmetric ties (friends)</th>\n",
" <th>Asymmetric ties (followers)</th>\n",
" <th>Like posts</th>\n",
" <th>Repost posts</th>\n",
" </tr>\n",
" </thead>\n",
" <tbody>\n",
" <tr>\n",
" <th>Comrad</th>\n",
4 years ago
" <td>*Social network*</td>\n",
" <td>*Twitter*</td>\n",
" <td>❌ *No (central server on Tor)*</td>\n",
" <td>✔️ *Yes (everything routed via Tor)*</td>\n",
" <td>✔️ *Yes (100% E2EE)*</td>\n",
" <td>⭕ *Minimal server (deleted ASAP)*</td>\n",
" <td>✔️ *Yes (central public key repository)*</td>\n",
" <td>✔️ *No (works like twitter)*</td>\n",
" <td>✔️</td>\n",
" <td>❌?</td>\n",
" <td>✔️</td>\n",
" <td>✔️</td>\n",
" <td>✔️</td>\n",
" <td>✔️</td>\n",
" <td>✔️?</td>\n",
" <td>❌</td>\n",
" </tr>\n",
" <tr>\n",
" <th>SecureScuttlebutt</th>\n",
" <td>Social network</td>\n",
" <td>Twitter / Facebook</td>\n",
" <td>✔️ Fully (P2P)</td>\n",
" <td>❌ No (P2P reveals IP; friend networks public)</td>\n",
" <td>⭕ Partly (private E2EE, public unencrypted)</td>\n",
" <td>✔️ Distributed across friend networks?</td>\n",
" <td>✔️ Yes? (federated key exchange?)</td>\n",
" <td>❌ Yes (need initial pub)</td>\n",
" <td>✔️</td>\n",
" <td>❌?</td>\n",
" <td>❌</td>\n",
" <td>✔️</td>\n",
" <td>✔️</td>\n",
" <td>✔️</td>\n",
" <td>✔️</td>\n",
" <td>❌?</td>\n",
" </tr>\n",
" <tr>\n",
" <th>Diaspora</th>\n",
" <td>Social network</td>\n",
" <td>Twitter</td>\n",
" <td>⭕ Halfway (federated)</td>\n",
" <td>⭕ No (unless via Tor Browser)</td>\n",
" <td>❌ No (unencrypted?)</td>\n",
" <td>✔️</td>\n",
" <td>?</td>\n",
" <td>❌ Yes (need 'pod' server)</td>\n",
" <td>❌?</td>\n",
" <td>❌?</td>\n",
" <td>❌?</td>\n",
" <td>✔️</td>\n",
" <td>❌</td>\n",
" <td>✔️</td>\n",
" <td>✔️</td>\n",
" <td>✔️?</td>\n",
" </tr>\n",
" <tr>\n",
" <th>Mastodon</th>\n",
" <td>Social network</td>\n",
" <td>Twitter</td>\n",
" <td>⭕ Halfway (federated)</td>\n",
" <td>⭕ No (unless via Tor Browser)</td>\n",
" <td>❌ No (unencrypted?)</td>\n",
" <td>✔️</td>\n",
" <td>?</td>\n",
" <td>❌ Yes (need 'instance' server)</td>\n",
" <td>❌?</td>\n",
" <td>❌?</td>\n",
" <td>❌?</td>\n",
" <td>✔️</td>\n",
" <td>❌</td>\n",
" <td>✔️</td>\n",
" <td>✔️</td>\n",
" <td>✔️?</td>\n",
" </tr>\n",
" <tr>\n",
" <th>Matrix</th>\n",
" <td>Co-working space</td>\n",
" <td>Slack</td>\n",
" <td>⭕ Halfway (federated)</td>\n",
" <td>❌ No?</td>\n",
" <td>✔️ Yes? (100% E2EE)</td>\n",
" <td>?</td>\n",
" <td>✔️ Yes (?)</td>\n",
" <td>❌ Yes (invited channels only?)</td>\n",
" <td>✔️</td>\n",
" <td>✔️</td>\n",
" <td>❌?</td>\n",
" <td>✔️</td>\n",
" <td>✔️</td>\n",
" <td>❌</td>\n",
" <td>❌?</td>\n",
" <td>❌?</td>\n",
" </tr>\n",
" <tr>\n",
" <th>BriarMessenger</th>\n",
" <td>Messenger</td>\n",
" <td>WhatsApp</td>\n",
" <td>✔️ Fully (P2P)</td>\n",
" <td>✔️ Yes? (Tor)</td>\n",
" <td>✔️ Yes (100% E2EE)</td>\n",
" <td>❌ None (needs 24/7 listener)</td>\n",
" <td>⭕ Partly (public keys traded IRL)</td>\n",
" <td>❌ Yes (need initial contact?)</td>\n",
" <td>✔️</td>\n",
" <td>✔️</td>\n",
" <td>❌?</td>\n",
" <td>✔️</td>\n",
" <td>✔️</td>\n",
" <td>❌</td>\n",
" <td>❌?</td>\n",
" <td>❌?</td>\n",
" </tr>\n",
" <tr>\n",
" <th>CabalChat</th>\n",
" <td>Private chatrooms</td>\n",
" <td>IRC</td>\n",
" <td>✔️ Fully (P2P)</td>\n",
" <td>❌ No (P2P reveals IP)</td>\n",
" <td>⭕ Mostly (shared key, not E2EE)</td>\n",
" <td>✔️ Distributed Hash Table</td>\n",
" <td>❌ No (?)</td>\n",
" <td>✔️ Not really (public chat is open)</td>\n",
" <td>?</td>\n",
" <td>✔️</td>\n",
" <td>❌?</td>\n",
" <td>✔️</td>\n",
" <td>❌</td>\n",
" <td>❌</td>\n",
" <td>❌</td>\n",
" <td>❌</td>\n",
" </tr>\n",
" <tr>\n",
" <th>Signal</th>\n",
" <td>Messenger</td>\n",
" <td>WhatsApp</td>\n",
" <td>❌ No?</td>\n",
" <td>❌ No</td>\n",
" <td>✔️ Yes (E2EE, and audited)</td>\n",
" <td>?</td>\n",
" <td>?</td>\n",
" <td>✔️</td>\n",
" <td>✔️</td>\n",
" <td>✔️</td>\n",
" <td>❌</td>\n",
" <td>❌</td>\n",
" <td>✔️</td>\n",
" <td>❌</td>\n",
" <td>❌</td>\n",
" <td>❌</td>\n",
" </tr>\n",
" </tbody>\n",
"</table>\n",
"</div>"
],
"text/plain": [
" What is it? Kind of like... \\\n",
"Comrad *Social network* *Twitter* \n",
4 years ago
"SecureScuttlebutt Social network Twitter / Facebook \n",
"Diaspora Social network Twitter \n",
"Mastodon Social network Twitter \n",
"Matrix Co-working space Slack \n",
"BriarMessenger Messenger WhatsApp \n",
"CabalChat Private chatrooms IRC \n",
"Signal Messenger WhatsApp \n",
"\n",
" Decentralized? (P2P?) \\\n",
"Comrad ❌ *No (central server on Tor)* \n",
4 years ago
"SecureScuttlebutt ✔️ Fully (P2P) \n",
"Diaspora ⭕ Halfway (federated) \n",
"Mastodon ⭕ Halfway (federated) \n",
"Matrix ⭕ Halfway (federated) \n",
"BriarMessenger ✔️ Fully (P2P) \n",
"CabalChat ✔️ Fully (P2P) \n",
"Signal ❌ No? \n",
"\n",
" Anonymous? (IP hidden?) \\\n",
"Comrad ✔️ *Yes (everything routed via Tor)* \n",
4 years ago
"SecureScuttlebutt ❌ No (P2P reveals IP; friend networks public) \n",
"Diaspora ⭕ No (unless via Tor Browser) \n",
"Mastodon ⭕ No (unless via Tor Browser) \n",
"Matrix ❌ No? \n",
"BriarMessenger ✔️ Yes? (Tor) \n",
"CabalChat ❌ No (P2P reveals IP) \n",
"Signal ❌ No \n",
"\n",
" Confidential? (100% E2EE?) \\\n",
"Comrad ✔️ *Yes (100% E2EE)* \n",
4 years ago
"SecureScuttlebutt ⭕ Partly (private E2EE, public unencrypted) \n",
"Diaspora ❌ No (unencrypted?) \n",
"Mastodon ❌ No (unencrypted?) \n",
"Matrix ✔️ Yes? (100% E2EE) \n",
"BriarMessenger ✔️ Yes (100% E2EE) \n",
"CabalChat ⭕ Mostly (shared key, not E2EE) \n",
"Signal ✔️ Yes (E2EE, and audited) \n",
"\n",
" Data robustness? \\\n",
"Comrad ⭕ *Minimal server (deleted ASAP)* \n",
4 years ago
"SecureScuttlebutt ✔️ Distributed across friend networks? \n",
"Diaspora ✔️ \n",
"Mastodon ✔️ \n",
"Matrix ? \n",
"BriarMessenger ❌ None (needs 24/7 listener) \n",
"CabalChat ✔️ Distributed Hash Table \n",
"Signal ? \n",
"\n",
" Identity verification? \\\n",
"Comrad ✔️ *Yes (central public key repository)* \n",
4 years ago
"SecureScuttlebutt ✔️ Yes? (federated key exchange?) \n",
"Diaspora ? \n",
"Mastodon ? \n",
"Matrix ✔️ Yes (?) \n",
"BriarMessenger ⭕ Partly (public keys traded IRL) \n",
"CabalChat ❌ No (?) \n",
"Signal ? \n",
"\n",
" Requires invitation/server? DM users (E2EE) \\\n",
"Comrad ✔️ *No (works like twitter)* ✔️ \n",
4 years ago
"SecureScuttlebutt ❌ Yes (need initial pub) ✔️ \n",
"Diaspora ❌ Yes (need 'pod' server) ❌? \n",
"Mastodon ❌ Yes (need 'instance' server) ❌? \n",
"Matrix ❌ Yes (invited channels only?) ✔️ \n",
"BriarMessenger ❌ Yes (need initial contact?) ✔️ \n",
"CabalChat ✔️ Not really (public chat is open) ? \n",
"Signal ✔️ ✔️ \n",
"\n",
" Group chat (E2EE) Post to world Post to friends/ties \\\n",
"Comrad ❌? ✔️ ✔️ \n",
4 years ago
"SecureScuttlebutt ❌? ❌ ✔️ \n",
"Diaspora ❌? ❌? ✔️ \n",
"Mastodon ❌? ❌? ✔️ \n",
"Matrix ✔️ ❌? ✔️ \n",
"BriarMessenger ✔️ ❌? ✔️ \n",
"CabalChat ✔️ ❌? ✔️ \n",
"Signal ✔️ ❌ ❌ \n",
"\n",
" Symmetric ties (friends) Asymmetric ties (followers) \\\n",
"Comrad ✔️ ✔️ \n",
4 years ago
"SecureScuttlebutt ✔️ ✔️ \n",
"Diaspora ❌ ✔️ \n",
"Mastodon ❌ ✔️ \n",
"Matrix ✔️ ❌ \n",
"BriarMessenger ✔️ ❌ \n",
"CabalChat ❌ ❌ \n",
"Signal ✔️ ❌ \n",
"\n",
" Like posts Repost posts \n",
"Comrad ✔️? ❌ \n",
4 years ago
"SecureScuttlebutt ✔️ ❌? \n",
"Diaspora ✔️ ✔️? \n",
"Mastodon ✔️ ✔️? \n",
"Matrix ❌? ❌? \n",
"BriarMessenger ❌? ❌? \n",
"CabalChat ❌ ❌ \n",
"Signal ❌ ❌ "
]
},
"execution_count": 11,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"df"
]
},
{
"cell_type": "code",
"execution_count": 12,
"metadata": {},
"outputs": [],
"source": [
"df_data = df.applymap(transform).drop('What is it?',1).drop('Kind of like...',1)"
]
},
{
"cell_type": "code",
"execution_count": 13,
"metadata": {},
"outputs": [
{
"data": {
"text/html": [
"<div>\n",
"<style scoped>\n",
" .dataframe tbody tr th:only-of-type {\n",
" vertical-align: middle;\n",
" }\n",
"\n",
" .dataframe tbody tr th {\n",
" vertical-align: top;\n",
" }\n",
"\n",
" .dataframe thead th {\n",
" text-align: right;\n",
" }\n",
"</style>\n",
"<table border=\"1\" class=\"dataframe\">\n",
" <thead>\n",
" <tr style=\"text-align: right;\">\n",
" <th></th>\n",
" <th>Decentralized? (P2P?)</th>\n",
" <th>Anonymous? (IP hidden?)</th>\n",
" <th>Confidential? (100% E2EE?)</th>\n",
" <th>Data robustness?</th>\n",
" <th>Identity verification?</th>\n",
" <th>Requires invitation/server?</th>\n",
" <th>DM users (E2EE)</th>\n",
" <th>Group chat (E2EE)</th>\n",
" <th>Post to world</th>\n",
" <th>Post to friends/ties</th>\n",
" <th>Symmetric ties (friends)</th>\n",
" <th>Asymmetric ties (followers)</th>\n",
" <th>Like posts</th>\n",
" <th>Repost posts</th>\n",
" </tr>\n",
" </thead>\n",
" <tbody>\n",
" <tr>\n",
" <th>Comrad</th>\n",
4 years ago
" <td>0</td>\n",
" <td>1</td>\n",
" <td>1</td>\n",
" <td>0</td>\n",
" <td>1</td>\n",
" <td>1</td>\n",
" <td>1</td>\n",
" <td>0</td>\n",
" <td>1</td>\n",
" <td>1</td>\n",
" <td>1</td>\n",
" <td>1</td>\n",
" <td>1</td>\n",
" <td>0</td>\n",
" </tr>\n",
" <tr>\n",
" <th>SecureScuttlebutt</th>\n",
" <td>1</td>\n",
" <td>0</td>\n",
" <td>0</td>\n",
" <td>1</td>\n",
" <td>1</td>\n",
" <td>0</td>\n",
" <td>1</td>\n",
" <td>0</td>\n",
" <td>0</td>\n",
" <td>1</td>\n",
" <td>1</td>\n",
" <td>1</td>\n",
" <td>1</td>\n",
" <td>0</td>\n",
" </tr>\n",
" <tr>\n",
" <th>Diaspora</th>\n",
" <td>0</td>\n",
" <td>0</td>\n",
" <td>0</td>\n",
" <td>1</td>\n",
" <td>0</td>\n",
" <td>0</td>\n",
" <td>0</td>\n",
" <td>0</td>\n",
" <td>0</td>\n",
" <td>1</td>\n",
" <td>0</td>\n",
" <td>1</td>\n",
" <td>1</td>\n",
" <td>1</td>\n",
" </tr>\n",
" <tr>\n",
" <th>Mastodon</th>\n",
" <td>0</td>\n",
" <td>0</td>\n",
" <td>0</td>\n",
" <td>1</td>\n",
" <td>0</td>\n",
" <td>0</td>\n",
" <td>0</td>\n",
" <td>0</td>\n",
" <td>0</td>\n",
" <td>1</td>\n",
" <td>0</td>\n",
" <td>1</td>\n",
" <td>1</td>\n",
" <td>1</td>\n",
" </tr>\n",
" <tr>\n",
" <th>Matrix</th>\n",
" <td>0</td>\n",
" <td>0</td>\n",
" <td>1</td>\n",
" <td>0</td>\n",
" <td>1</td>\n",
" <td>0</td>\n",
" <td>1</td>\n",
" <td>1</td>\n",
" <td>0</td>\n",
" <td>1</td>\n",
" <td>1</td>\n",
" <td>0</td>\n",
" <td>0</td>\n",
" <td>0</td>\n",
" </tr>\n",
" <tr>\n",
" <th>BriarMessenger</th>\n",
" <td>1</td>\n",
" <td>1</td>\n",
" <td>1</td>\n",
" <td>0</td>\n",
" <td>0</td>\n",
" <td>0</td>\n",
" <td>1</td>\n",
" <td>1</td>\n",
" <td>0</td>\n",
" <td>1</td>\n",
" <td>1</td>\n",
" <td>0</td>\n",
" <td>0</td>\n",
" <td>0</td>\n",
" </tr>\n",
" <tr>\n",
" <th>CabalChat</th>\n",
" <td>1</td>\n",
" <td>0</td>\n",
" <td>0</td>\n",
" <td>1</td>\n",
" <td>0</td>\n",
" <td>1</td>\n",
" <td>0</td>\n",
" <td>1</td>\n",
" <td>0</td>\n",
" <td>1</td>\n",
" <td>0</td>\n",
" <td>0</td>\n",
" <td>0</td>\n",
" <td>0</td>\n",
" </tr>\n",
" <tr>\n",
" <th>Signal</th>\n",
" <td>0</td>\n",
" <td>0</td>\n",
" <td>1</td>\n",
" <td>0</td>\n",
" <td>0</td>\n",
" <td>1</td>\n",
" <td>1</td>\n",
" <td>1</td>\n",
" <td>0</td>\n",
" <td>0</td>\n",
" <td>1</td>\n",
" <td>0</td>\n",
" <td>0</td>\n",
" <td>0</td>\n",
" </tr>\n",
" </tbody>\n",
"</table>\n",
"</div>"
],
"text/plain": [
" Decentralized? (P2P?) Anonymous? (IP hidden?) \\\n",
"Comrad 0 1 \n",
4 years ago
"SecureScuttlebutt 1 0 \n",
"Diaspora 0 0 \n",
"Mastodon 0 0 \n",
"Matrix 0 0 \n",
"BriarMessenger 1 1 \n",
"CabalChat 1 0 \n",
"Signal 0 0 \n",
"\n",
" Confidential? (100% E2EE?) Data robustness? \\\n",
"Comrad 1 0 \n",
4 years ago
"SecureScuttlebutt 0 1 \n",
"Diaspora 0 1 \n",
"Mastodon 0 1 \n",
"Matrix 1 0 \n",
"BriarMessenger 1 0 \n",
"CabalChat 0 1 \n",
"Signal 1 0 \n",
"\n",
" Identity verification? Requires invitation/server? \\\n",
"Comrad 1 1 \n",
4 years ago
"SecureScuttlebutt 1 0 \n",
"Diaspora 0 0 \n",
"Mastodon 0 0 \n",
"Matrix 1 0 \n",
"BriarMessenger 0 0 \n",
"CabalChat 0 1 \n",
"Signal 0 1 \n",
"\n",
" DM users (E2EE) Group chat (E2EE) Post to world \\\n",
"Comrad 1 0 1 \n",
4 years ago
"SecureScuttlebutt 1 0 0 \n",
"Diaspora 0 0 0 \n",
"Mastodon 0 0 0 \n",
"Matrix 1 1 0 \n",
"BriarMessenger 1 1 0 \n",
"CabalChat 0 1 0 \n",
"Signal 1 1 0 \n",
"\n",
" Post to friends/ties Symmetric ties (friends) \\\n",
"Comrad 1 1 \n",
4 years ago
"SecureScuttlebutt 1 1 \n",
"Diaspora 1 0 \n",
"Mastodon 1 0 \n",
"Matrix 1 1 \n",
"BriarMessenger 1 1 \n",
"CabalChat 1 0 \n",
"Signal 0 1 \n",
"\n",
" Asymmetric ties (followers) Like posts Repost posts \n",
"Comrad 1 1 0 \n",
4 years ago
"SecureScuttlebutt 1 1 0 \n",
"Diaspora 1 1 1 \n",
"Mastodon 1 1 1 \n",
"Matrix 0 0 0 \n",
"BriarMessenger 0 0 0 \n",
"CabalChat 0 0 0 \n",
"Signal 0 0 0 "
]
},
"execution_count": 13,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"df_data"
]
},
{
"cell_type": "code",
"execution_count": 14,
"metadata": {},
"outputs": [],
"source": [
"from scipy.spatial.distance import squareform, pdist"
]
},
{
"cell_type": "code",
"execution_count": 15,
"metadata": {},
"outputs": [
{
"data": {
"text/plain": [
"array([2.44948974, 3. , 3. , 2.44948974, 2.64575131,\n",
" 3.31662479, 2.64575131, 2.23606798, 2.23606798, 2.44948974,\n",
" 2.64575131, 2.64575131, 3. , 0. , 3. ,\n",
" 3.16227766, 2.44948974, 3.16227766, 3. , 3.16227766,\n",
" 2.44948974, 3.16227766, 1.73205081, 2.64575131, 1.73205081,\n",
" 2.44948974, 2. , 2.44948974])"
]
},
"execution_count": 15,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"pdist(df_data)"
]
},
{
"cell_type": "code",
"execution_count": 16,
"metadata": {},
"outputs": [],
"source": [
"def make_dist(X_dtm,dist_metric='euclidean',standardize=True):\n",
" distmatrix=pdist(X_dtm,metric=dist_metric)\n",
" return pd.DataFrame(squareform(distmatrix), columns=X_dtm.index, index=X_dtm.index)"
]
},
{
"cell_type": "code",
"execution_count": 17,
"metadata": {},
"outputs": [
{
"data": {
"text/html": [
"<div>\n",
"<style scoped>\n",
" .dataframe tbody tr th:only-of-type {\n",
" vertical-align: middle;\n",
" }\n",
"\n",
" .dataframe tbody tr th {\n",
" vertical-align: top;\n",
" }\n",
"\n",
" .dataframe thead th {\n",
" text-align: right;\n",
" }\n",
"</style>\n",
"<table border=\"1\" class=\"dataframe\">\n",
" <thead>\n",
" <tr style=\"text-align: right;\">\n",
" <th></th>\n",
" <th>Comrad</th>\n",
4 years ago
" <th>SecureScuttlebutt</th>\n",
" <th>Diaspora</th>\n",
" <th>Mastodon</th>\n",
" <th>Matrix</th>\n",
" <th>BriarMessenger</th>\n",
" <th>CabalChat</th>\n",
" <th>Signal</th>\n",
" </tr>\n",
" </thead>\n",
" <tbody>\n",
" <tr>\n",
" <th>Comrad</th>\n",
4 years ago
" <td>0.000000</td>\n",
" <td>2.449490</td>\n",
" <td>3.000000</td>\n",
" <td>3.000000</td>\n",
" <td>2.449490</td>\n",
" <td>2.645751</td>\n",
" <td>3.316625</td>\n",
" <td>2.645751</td>\n",
" </tr>\n",
" <tr>\n",
" <th>SecureScuttlebutt</th>\n",
" <td>2.449490</td>\n",
" <td>0.000000</td>\n",
" <td>2.236068</td>\n",
" <td>2.236068</td>\n",
" <td>2.449490</td>\n",
" <td>2.645751</td>\n",
" <td>2.645751</td>\n",
" <td>3.000000</td>\n",
" </tr>\n",
" <tr>\n",
" <th>Diaspora</th>\n",
" <td>3.000000</td>\n",
" <td>2.236068</td>\n",
" <td>0.000000</td>\n",
" <td>0.000000</td>\n",
" <td>3.000000</td>\n",
" <td>3.162278</td>\n",
" <td>2.449490</td>\n",
" <td>3.162278</td>\n",
" </tr>\n",
" <tr>\n",
" <th>Mastodon</th>\n",
" <td>3.000000</td>\n",
" <td>2.236068</td>\n",
" <td>0.000000</td>\n",
" <td>0.000000</td>\n",
" <td>3.000000</td>\n",
" <td>3.162278</td>\n",
" <td>2.449490</td>\n",
" <td>3.162278</td>\n",
" </tr>\n",
" <tr>\n",
" <th>Matrix</th>\n",
" <td>2.449490</td>\n",
" <td>2.449490</td>\n",
" <td>3.000000</td>\n",
" <td>3.000000</td>\n",
" <td>0.000000</td>\n",
" <td>1.732051</td>\n",
" <td>2.645751</td>\n",
" <td>1.732051</td>\n",
" </tr>\n",
" <tr>\n",
" <th>BriarMessenger</th>\n",
" <td>2.645751</td>\n",
" <td>2.645751</td>\n",
" <td>3.162278</td>\n",
" <td>3.162278</td>\n",
" <td>1.732051</td>\n",
" <td>0.000000</td>\n",
" <td>2.449490</td>\n",
" <td>2.000000</td>\n",
" </tr>\n",
" <tr>\n",
" <th>CabalChat</th>\n",
" <td>3.316625</td>\n",
" <td>2.645751</td>\n",
" <td>2.449490</td>\n",
" <td>2.449490</td>\n",
" <td>2.645751</td>\n",
" <td>2.449490</td>\n",
" <td>0.000000</td>\n",
" <td>2.449490</td>\n",
" </tr>\n",
" <tr>\n",
" <th>Signal</th>\n",
" <td>2.645751</td>\n",
" <td>3.000000</td>\n",
" <td>3.162278</td>\n",
" <td>3.162278</td>\n",
" <td>1.732051</td>\n",
" <td>2.000000</td>\n",
" <td>2.449490</td>\n",
" <td>0.000000</td>\n",
" </tr>\n",
" </tbody>\n",
"</table>\n",
"</div>"
],
"text/plain": [
" Comrad SecureScuttlebutt Diaspora Mastodon Matrix \\\n",
"Comrad 0.000000 2.449490 3.000000 3.000000 2.449490 \n",
4 years ago
"SecureScuttlebutt 2.449490 0.000000 2.236068 2.236068 2.449490 \n",
"Diaspora 3.000000 2.236068 0.000000 0.000000 3.000000 \n",
"Mastodon 3.000000 2.236068 0.000000 0.000000 3.000000 \n",
"Matrix 2.449490 2.449490 3.000000 3.000000 0.000000 \n",
"BriarMessenger 2.645751 2.645751 3.162278 3.162278 1.732051 \n",
"CabalChat 3.316625 2.645751 2.449490 2.449490 2.645751 \n",
"Signal 2.645751 3.000000 3.162278 3.162278 1.732051 \n",
"\n",
" BriarMessenger CabalChat Signal \n",
"Comrad 2.645751 3.316625 2.645751 \n",
4 years ago
"SecureScuttlebutt 2.645751 2.645751 3.000000 \n",
"Diaspora 3.162278 2.449490 3.162278 \n",
"Mastodon 3.162278 2.449490 3.162278 \n",
"Matrix 1.732051 2.645751 1.732051 \n",
"BriarMessenger 0.000000 2.449490 2.000000 \n",
"CabalChat 2.449490 0.000000 2.449490 \n",
"Signal 2.000000 2.449490 0.000000 "
]
},
"execution_count": 17,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"df_dist = make_dist(df_data)\n",
"df_dist"
]
},
{
"cell_type": "code",
"execution_count": 18,
"metadata": {},
"outputs": [],
"source": [
"# df_dist['Signal'].sort_values()"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"## Viz"
]
},
{
"cell_type": "code",
"execution_count": 19,
"metadata": {},
"outputs": [],
"source": [
"from scipy.cluster.hierarchy import dendrogram, linkage\n",
"from matplotlib import pyplot as plt"
]
},
{
"cell_type": "code",
"execution_count": 20,
"metadata": {},
"outputs": [
{
"data": {
"text/plain": [
"array([[ 2. , 3. , 0. , 2. ],\n",
" [ 4. , 5. , 1.73205081, 2. ],\n",
" [ 7. , 9. , 2. , 3. ],\n",
" [ 1. , 8. , 2.23606798, 3. ],\n",
" [ 0. , 10. , 2.64575131, 4. ],\n",
" [ 6. , 11. , 2.64575131, 4. ],\n",
" [12. , 13. , 3.31662479, 8. ]])"
]
},
"execution_count": 20,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"# Here it is: in a single line, compute a hierarchical clustering of the DTM\n",
"\n",
"hclust = linkage(df_data,method='complete')\n",
"hclust"
]
},
{
"cell_type": "code",
"execution_count": 21,
"metadata": {},
"outputs": [],
"source": [
"def fancy_dendrogram(*args, **kwargs):\n",
" max_d = kwargs.pop('max_d', None)\n",
" if max_d and 'color_threshold' not in kwargs:\n",
" kwargs['color_threshold'] = max_d\n",
" annotate_above = kwargs.pop('annotate_above', 0)\n",
"\n",
" ddata = dendrogram(*args, **kwargs)\n",
"\n",
" if not kwargs.get('no_plot', False):\n",
" plt.title('Hierarchical Clustering Dendrogram')\n",
" plt.xlabel('sample index or (cluster size)')\n",
" plt.ylabel('distance')\n",
" for i, d, c in zip(ddata['icoord'], ddata['dcoord'], ddata['color_list']):\n",
" x = 0.5 * sum(i[1:3])\n",
" y = d[1]\n",
" if y > annotate_above:\n",
" plt.plot(x, y, 'o', c=c)\n",
" plt.annotate(\"%.3g\" % y, (x, y), xytext=(0, -5),\n",
" textcoords='offset points',\n",
" va='top', ha='center')\n",
" if max_d:\n",
" plt.axhline(y=max_d, c='k')\n",
" return ddata"
]
},
{
"cell_type": "code",
"execution_count": 48,
"metadata": {},
"outputs": [],
"source": [
"def plot_dendrogram(dtm,linkage_method='complete'):\n",
" \n",
" hclust = linkage(dtm,method=linkage_method)\n",
" \n",
" fig, ax = plt.subplots(figsize=(20, 8))\n",
" plt.title('Hierarchical Clustering Dendrogram (truncated)')\n",
" plt.xlabel('sample index')\n",
" plt.ylabel('distance')\n",
" fancy_dendrogram(\n",
" hclust,\n",
" show_leaf_counts=False, # otherwise numbers in brackets are counts\n",
" leaf_rotation=90.,\n",
" leaf_font_size=12.,\n",
" show_contracted=True, # to get a distribution impression in truncated branches\n",
" labels=dtm.index,\n",
" )\n",
" plt.savefig('fig.hclust-apps.png')\n",
" plt.show()"
]
},
{
"cell_type": "code",
"execution_count": 49,
"metadata": {},
"outputs": [
{
"data": {
"image/png": "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
"text/plain": [
"<Figure size 1440x576 with 1 Axes>"
]
},
"metadata": {
"needs_background": "light"
},
"output_type": "display_data"
}
],
"source": [
"plot_dendrogram(df_data)"
]
},
{
"cell_type": "code",
"execution_count": 50,
"metadata": {},
"outputs": [
{
"data": {
"image/png": "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
"text/plain": [
"<Figure size 1440x576 with 1 Axes>"
]
},
"metadata": {
"needs_background": "light"
},
"output_type": "display_data"
}
],
"source": [
"plot_dendrogram(df_data.T)"
]
},
{
"cell_type": "code",
"execution_count": 25,
"metadata": {},
"outputs": [],
"source": [
"\n",
"def tsne(datadf,df_dist=None,n_components=2,resultdf=None):\n",
" if df_dist is None: df_dist=make_dist(datadf)\n",
" m_dist=df_dist.values\n",
" from sklearn.manifold import TSNE\n",
" model = TSNE(n_components=n_components, random_state=0)\n",
" fit = model.fit_transform(m_dist)\n",
" from collections import defaultdict\n",
" newcols=defaultdict(list)\n",
" for i,word in enumerate(datadf.index):\n",
" for ii,xx in enumerate(fit[i]):\n",
" newcols['tsne_V'+str(ii+1)] += [xx]\n",
" if resultdf is None: resultdf=pd.DataFrame(index=datadf.index)\n",
" for k,v in list(newcols.items()): resultdf[k]=v\n",
" return resultdf"
]
},
{
"cell_type": "code",
"execution_count": 26,
"metadata": {},
"outputs": [],
"source": [
"dtm_tsne = tsne(df_dist)"
]
},
{
"cell_type": "code",
"execution_count": 27,
"metadata": {
"scrolled": true
},
"outputs": [
{
"data": {
"text/html": [
"<div>\n",
"<style scoped>\n",
" .dataframe tbody tr th:only-of-type {\n",
" vertical-align: middle;\n",
" }\n",
"\n",
" .dataframe tbody tr th {\n",
" vertical-align: top;\n",
" }\n",
"\n",
" .dataframe thead th {\n",
" text-align: right;\n",
" }\n",
"</style>\n",
"<table border=\"1\" class=\"dataframe\">\n",
" <thead>\n",
" <tr style=\"text-align: right;\">\n",
" <th></th>\n",
" <th>tsne_V1</th>\n",
" <th>tsne_V2</th>\n",
" <th>label</th>\n",
" </tr>\n",
" </thead>\n",
" <tbody>\n",
" <tr>\n",
" <th>Comrad</th>\n",
4 years ago
" <td>-108.958252</td>\n",
" <td>-208.941483</td>\n",
" <td>Comrad</td>\n",
4 years ago
" </tr>\n",
" <tr>\n",
" <th>SecureScuttlebutt</th>\n",
" <td>186.487061</td>\n",
" <td>-98.103249</td>\n",
" <td>SecureScuttlebutt</td>\n",
" </tr>\n",
" <tr>\n",
" <th>Diaspora</th>\n",
" <td>19.245832</td>\n",
" <td>160.858780</td>\n",
" <td>Diaspora</td>\n",
" </tr>\n",
" <tr>\n",
" <th>Mastodon</th>\n",
" <td>170.658829</td>\n",
" <td>75.445076</td>\n",
" <td>Mastodon</td>\n",
" </tr>\n",
" <tr>\n",
" <th>Matrix</th>\n",
" <td>-1.386411</td>\n",
" <td>-35.043739</td>\n",
" <td>Matrix</td>\n",
" </tr>\n",
" <tr>\n",
" <th>BriarMessenger</th>\n",
" <td>-145.800095</td>\n",
" <td>106.944611</td>\n",
" <td>BriarMessenger</td>\n",
" </tr>\n",
" <tr>\n",
" <th>CabalChat</th>\n",
" <td>64.834541</td>\n",
" <td>-221.825272</td>\n",
" <td>CabalChat</td>\n",
" </tr>\n",
" <tr>\n",
" <th>Signal</th>\n",
" <td>-196.906036</td>\n",
" <td>-58.990913</td>\n",
" <td>Signal</td>\n",
" </tr>\n",
" </tbody>\n",
"</table>\n",
"</div>"
],
"text/plain": [
" tsne_V1 tsne_V2 label\n",
"Comrad -108.958252 -208.941483 Comrad\n",
4 years ago
"SecureScuttlebutt 186.487061 -98.103249 SecureScuttlebutt\n",
"Diaspora 19.245832 160.858780 Diaspora\n",
"Mastodon 170.658829 75.445076 Mastodon\n",
"Matrix -1.386411 -35.043739 Matrix\n",
"BriarMessenger -145.800095 106.944611 BriarMessenger\n",
"CabalChat 64.834541 -221.825272 CabalChat\n",
"Signal -196.906036 -58.990913 Signal"
]
},
"execution_count": 27,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"dtm_tsne['label']=dtm_tsne.index\n",
"dtm_tsne"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": []
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": []
},
{
"cell_type": "code",
"execution_count": 44,
"metadata": {},
"outputs": [
{
"data": {
"application/vnd.plotly.v1+json": {
"config": {
"plotlyServerURL": "https://plot.ly"
},
"data": [
{
"hovertemplate": "color=Comrad<br>0=%{x}<br>1=%{y}<br>text=%{text}<extra></extra>",
"legendgroup": "Comrad",
4 years ago
"marker": {
"color": "#636efa",
"symbol": "circle"
},
"mode": "markers+text",
"name": "Comrad",
4 years ago
"orientation": "v",
"showlegend": true,
"text": [
"Comrad"
4 years ago
],
"type": "scatter",
"x": [
-0.5371889532432486
],
"xaxis": "x",
"y": [
1.6690599275270384
],
"yaxis": "y"
},
{
"hovertemplate": "color=SecureScuttlebutt<br>0=%{x}<br>1=%{y}<br>text=%{text}<extra></extra>",
"legendgroup": "SecureScuttlebutt",
"marker": {
"color": "#EF553B",
"symbol": "circle"
},
"mode": "markers+text",
"name": "SecureScuttlebutt",
"orientation": "v",
"showlegend": true,
"text": [
"SecureScuttlebutt"
],
"type": "scatter",
"x": [
0.5595718609453091
],
"xaxis": "x",
"y": [
0.7387372968787214
],
"yaxis": "y"
},
{
"hovertemplate": "color=Diaspora<br>0=%{x}<br>1=%{y}<br>text=%{text}<extra></extra>",
"legendgroup": "Diaspora",
"marker": {
"color": "#00cc96",
"symbol": "circle"
},
"mode": "markers+text",
"name": "Diaspora",
"orientation": "v",
"showlegend": true,
"text": [
"Diaspora"
],
"type": "scatter",
"x": [
1.6860059881786202
],
"xaxis": "x",
"y": [
-0.06589452477227059
],
"yaxis": "y"
},
{
"hovertemplate": "color=Mastodon<br>0=%{x}<br>1=%{y}<br>text=%{text}<extra></extra>",
"legendgroup": "Mastodon",
"marker": {
"color": "#ab63fa",
"symbol": "circle"
},
"mode": "markers+text",
"name": "Mastodon",
"orientation": "v",
"showlegend": true,
"text": [
"Mastodon"
],
"type": "scatter",
"x": [
1.6860059881786196
],
"xaxis": "x",
"y": [
-0.06589452477227072
],
"yaxis": "y"
},
{
"hovertemplate": "color=Matrix<br>0=%{x}<br>1=%{y}<br>text=%{text}<extra></extra>",
"legendgroup": "Matrix",
"marker": {
"color": "#FFA15A",
"symbol": "circle"
},
"mode": "markers+text",
"name": "Matrix",
"orientation": "v",
"showlegend": true,
"text": [
"Matrix"
],
"type": "scatter",
"x": [
-1.1227200411100027
],
"xaxis": "x",
"y": [
0.03413532817677556
],
"yaxis": "y"
},
{
"hovertemplate": "color=BriarMessenger<br>0=%{x}<br>1=%{y}<br>text=%{text}<extra></extra>",
"legendgroup": "BriarMessenger",
"marker": {
"color": "#19d3f3",
"symbol": "circle"
},
"mode": "markers+text",
"name": "BriarMessenger",
"orientation": "v",
"showlegend": true,
"text": [
"BriarMessenger"
],
"type": "scatter",
"x": [
-1.223569121311721
],
"xaxis": "x",
"y": [
-0.33510554193784764
],
"yaxis": "y"
},
{
"hovertemplate": "color=CabalChat<br>0=%{x}<br>1=%{y}<br>text=%{text}<extra></extra>",
"legendgroup": "CabalChat",
"marker": {
"color": "#FF6692",
"symbol": "circle"
},
"mode": "markers+text",
"name": "CabalChat",
"orientation": "v",
"showlegend": true,
"text": [
"CabalChat"
],
"type": "scatter",
"x": [
0.2393460935661281
],
"xaxis": "x",
"y": [
-1.446848658722153
],
"yaxis": "y"
},
{
"hovertemplate": "color=Signal<br>0=%{x}<br>1=%{y}<br>text=%{text}<extra></extra>",
"legendgroup": "Signal",
"marker": {
"color": "#B6E880",
"symbol": "circle"
},
"mode": "markers+text",
"name": "Signal",
"orientation": "v",
"showlegend": true,
"text": [
"Signal"
],
"type": "scatter",
"x": [
-1.2874518152037042
],
"xaxis": "x",
"y": [
-0.5281893023779932
],
"yaxis": "y"
}
],
"layout": {
"annotations": [
{
"ax": 0,
"ay": 0,
"font": {
"size": 16
},
"text": "Decentralized? (P2P?)",
"x": -0.14679498781322306,
"xanchor": "center",
"y": -0.4900741959686681,
"yanchor": "bottom"
},
{
"ax": 0,
"ay": 0,
"font": {
"size": 16
},
"text": "Anonymous? (IP hidden?)",
"x": -0.6086653712596354,
"xanchor": "center",
"y": 0.626654553436534,
"yanchor": "bottom"
},
{
"ax": 0,
"ay": 0,
"font": {
"size": 16
},
"text": "Confidential? (100% E2EE?)",
"x": -1.4418225033622292,
"xanchor": "center",
"y": 0.39456178030931677,
"yanchor": "bottom"
},
{
"ax": 0,
"ay": 0,
"font": {
"size": 16
},
"text": "Data robustness?",
"x": 1.4418225033622298,
"xanchor": "center",
"y": -0.3945617803093167,
"yanchor": "bottom"
},
{
"ax": 0,
"ay": 0,
"font": {
"size": 16
},
"text": "Identity verification?",
"x": -0.3803686148000669,
"xanchor": "center",
"y": 1.1471517840430911,
"yanchor": "bottom"
},
{
"ax": 0,
"ay": 0,
"font": {
"size": 16
},
"text": "Requires invitation/server?",
"x": -0.5480105335232615,
"xanchor": "center",
"y": -0.14373994348049215,
"yanchor": "bottom"
},
{
"ax": 0,
"ay": 0,
"font": {
"size": 16
},
"text": "DM users (E2EE)",
"x": -1.2483876303886634,
"xanchor": "center",
"y": 0.7415999518416786,
"yanchor": "bottom"
},
{
"ax": 0,
"ay": 0,
"font": {
"size": 16
},
"text": "Group chat (E2EE)",
"x": -1.1733869928893845,
"xanchor": "center",
"y": -1.0692051406282475,
"yanchor": "bottom"
},
{
"ax": 0,
"ay": 0,
"font": {
"size": 16
},
"text": "Post to world",
"x": -0.18569746655571534,
"xanchor": "center",
"y": 0.7840777876983394,
"yanchor": "bottom"
},
{
"ax": 0,
"ay": 0,
"font": {
"size": 16
},
"text": "Post to friends/ties",
"x": 0.4450511108846764,
"xanchor": "center",
"y": 0.24812859793960695,
"yanchor": "bottom"
},
{
"ax": 0,
"ay": 0,
"font": {
"size": 16
},
"text": "Symmetric ties (friends)",
"x": -1.2483876303886636,
"xanchor": "center",
"y": 0.7415999518416786,
"yanchor": "bottom"
},
{
"ax": 0,
"ay": 0,
"font": {
"size": 16
},
"text": "Asymmetric ties (followers)",
"x": 1.1733869928893845,
"xanchor": "center",
"y": 1.0692051406282475,
"yanchor": "bottom"
},
{
"ax": 0,
"ay": 0,
"font": {
"size": 16
},
"text": "Like posts",
"x": 1.1733869928893845,
"xanchor": "center",
"y": 1.0692051406282475,
"yanchor": "bottom"
},
{
"ax": 0,
"ay": 0,
"font": {
"size": 16
},
"text": "Repost posts",
"x": 1.1656495864715333,
"xanchor": "center",
"y": -0.06191081860245404,
"yanchor": "bottom"
}
],
"font": {
"family": "Courier New, monospace",
"size": 22
},
"height": 1000,
"legend": {
"title": {
"text": "color"
},
"tracegroupgap": 0
},
"shapes": [
{
"type": "line",
"x0": 0,
"x1": -0.14679498781322306,
"y0": 0,
"y1": -0.4900741959686681
},
{
"type": "line",
"x0": 0,
"x1": -0.6086653712596354,
"y0": 0,
"y1": 0.626654553436534
},
{
"type": "line",
"x0": 0,
"x1": -1.4418225033622292,
"y0": 0,
"y1": 0.39456178030931677
},
{
"type": "line",
"x0": 0,
"x1": 1.4418225033622298,
"y0": 0,
"y1": -0.3945617803093167
},
{
"type": "line",
"x0": 0,
"x1": -0.3803686148000669,
"y0": 0,
"y1": 1.1471517840430911
},
{
"type": "line",
"x0": 0,
"x1": -0.5480105335232615,
"y0": 0,
"y1": -0.14373994348049215
},
{
"type": "line",
"x0": 0,
"x1": -1.2483876303886634,
"y0": 0,
"y1": 0.7415999518416786
},
{
"type": "line",
"x0": 0,
"x1": -1.1733869928893845,
"y0": 0,
"y1": -1.0692051406282475
},
{
"type": "line",
"x0": 0,
"x1": -0.18569746655571534,
"y0": 0,
"y1": 0.7840777876983394
},
{
"type": "line",
"x0": 0,
"x1": 0.4450511108846764,
"y0": 0,
"y1": 0.24812859793960695
},
{
"type": "line",
"x0": 0,
"x1": -1.2483876303886636,
"y0": 0,
"y1": 0.7415999518416786
},
{
"type": "line",
"x0": 0,
"x1": 1.1733869928893845,
"y0": 0,
"y1": 1.0692051406282475
},
{
"type": "line",
"x0": 0,
"x1": 1.1733869928893845,
"y0": 0,
"y1": 1.0692051406282475
},
{
"type": "line",
"x0": 0,
"x1": 1.1656495864715333,
"y0": 0,
"y1": -0.06191081860245404
}
],
"template": {
"data": {
"bar": [
{
"error_x": {
"color": "#2a3f5f"
},
"error_y": {
"color": "#2a3f5f"
},
"marker": {
"line": {
"color": "#E5ECF6",
"width": 0.5
}
},
"type": "bar"
}
],
"barpolar": [
{
"marker": {
"line": {
"color": "#E5ECF6",
"width": 0.5
}
},
"type": "barpolar"
}
],
"carpet": [
{
"aaxis": {
"endlinecolor": "#2a3f5f",
"gridcolor": "white",
"linecolor": "white",
"minorgridcolor": "white",
"startlinecolor": "#2a3f5f"
},
"baxis": {
"endlinecolor": "#2a3f5f",
"gridcolor": "white",
"linecolor": "white",
"minorgridcolor": "white",
"startlinecolor": "#2a3f5f"
},
"type": "carpet"
}
],
"choropleth": [
{
"colorbar": {
"outlinewidth": 0,
"ticks": ""
},
"type": "choropleth"
}
],
"contour": [
{
"colorbar": {
"outlinewidth": 0,
"ticks": ""
},
"colorscale": [
[
0,
"#0d0887"
],
[
0.1111111111111111,
"#46039f"
],
[
0.2222222222222222,
"#7201a8"
],
[
0.3333333333333333,
"#9c179e"
],
[
0.4444444444444444,
"#bd3786"
],
[
0.5555555555555556,
"#d8576b"
],
[
0.6666666666666666,
"#ed7953"
],
[
0.7777777777777778,
"#fb9f3a"
],
[
0.8888888888888888,
"#fdca26"
],
[
1,
"#f0f921"
]
],
"type": "contour"
}
],
"contourcarpet": [
{
"colorbar": {
"outlinewidth": 0,
"ticks": ""
},
"type": "contourcarpet"
}
],
"heatmap": [
{
"colorbar": {
"outlinewidth": 0,
"ticks": ""
},
"colorscale": [
[
0,
"#0d0887"
],
[
0.1111111111111111,
"#46039f"
],
[
0.2222222222222222,
"#7201a8"
],
[
0.3333333333333333,
"#9c179e"
],
[
0.4444444444444444,
"#bd3786"
],
[
0.5555555555555556,
"#d8576b"
],
[
0.6666666666666666,
"#ed7953"
],
[
0.7777777777777778,
"#fb9f3a"
],
[
0.8888888888888888,
"#fdca26"
],
[
1,
"#f0f921"
]
],
"type": "heatmap"
}
],
"heatmapgl": [
{
"colorbar": {
"outlinewidth": 0,
"ticks": ""
},
"colorscale": [
[
0,
"#0d0887"
],
[
0.1111111111111111,
"#46039f"
],
[
0.2222222222222222,
"#7201a8"
],
[
0.3333333333333333,
"#9c179e"
],
[
0.4444444444444444,
"#bd3786"
],
[
0.5555555555555556,
"#d8576b"
],
[
0.6666666666666666,
"#ed7953"
],
[
0.7777777777777778,
"#fb9f3a"
],
[
0.8888888888888888,
"#fdca26"
],
[
1,
"#f0f921"
]
],
"type": "heatmapgl"
}
],
"histogram": [
{
"marker": {
"colorbar": {
"outlinewidth": 0,
"ticks": ""
}
},
"type": "histogram"
}
],
"histogram2d": [
{
"colorbar": {
"outlinewidth": 0,
"ticks": ""
},
"colorscale": [
[
0,
"#0d0887"
],
[
0.1111111111111111,
"#46039f"
],
[
0.2222222222222222,
"#7201a8"
],
[
0.3333333333333333,
"#9c179e"
],
[
0.4444444444444444,
"#bd3786"
],
[
0.5555555555555556,
"#d8576b"
],
[
0.6666666666666666,
"#ed7953"
],
[
0.7777777777777778,
"#fb9f3a"
],
[
0.8888888888888888,
"#fdca26"
],
[
1,
"#f0f921"
]
],
"type": "histogram2d"
}
],
"histogram2dcontour": [
{
"colorbar": {
"outlinewidth": 0,
"ticks": ""
},
"colorscale": [
[
0,
"#0d0887"
],
[
0.1111111111111111,
"#46039f"
],
[
0.2222222222222222,
"#7201a8"
],
[
0.3333333333333333,
"#9c179e"
],
[
0.4444444444444444,
"#bd3786"
],
[
0.5555555555555556,
"#d8576b"
],
[
0.6666666666666666,
"#ed7953"
],
[
0.7777777777777778,
"#fb9f3a"
],
[
0.8888888888888888,
"#fdca26"
],
[
1,
"#f0f921"
]
],
"type": "histogram2dcontour"
}
],
"mesh3d": [
{
"colorbar": {
"outlinewidth": 0,
"ticks": ""
},
"type": "mesh3d"
}
],
"parcoords": [
{
"line": {
"colorbar": {
"outlinewidth": 0,
"ticks": ""
}
},
"type": "parcoords"
}
],
"pie": [
{
"automargin": true,
"type": "pie"
}
],
"scatter": [
{
"marker": {
"colorbar": {
"outlinewidth": 0,
"ticks": ""
}
},
"type": "scatter"
}
],
"scatter3d": [
{
"line": {
"colorbar": {
"outlinewidth": 0,
"ticks": ""
}
},
"marker": {
"colorbar": {
"outlinewidth": 0,
"ticks": ""
}
},
"type": "scatter3d"
}
],
"scattercarpet": [
{
"marker": {
"colorbar": {
"outlinewidth": 0,
"ticks": ""
}
},
"type": "scattercarpet"
}
],
"scattergeo": [
{
"marker": {
"colorbar": {
"outlinewidth": 0,
"ticks": ""
}
},
"type": "scattergeo"
}
],
"scattergl": [
{
"marker": {
"colorbar": {
"outlinewidth": 0,
"ticks": ""
}
},
"type": "scattergl"
}
],
"scattermapbox": [
{
"marker": {
"colorbar": {
"outlinewidth": 0,
"ticks": ""
}
},
"type": "scattermapbox"
}
],
"scatterpolar": [
{
"marker": {
"colorbar": {
"outlinewidth": 0,
"ticks": ""
}
},
"type": "scatterpolar"
}
],
"scatterpolargl": [
{
"marker": {
"colorbar": {
"outlinewidth": 0,
"ticks": ""
}
},
"type": "scatterpolargl"
}
],
"scatterternary": [
{
"marker": {
"colorbar": {
"outlinewidth": 0,
"ticks": ""
}
},
"type": "scatterternary"
}
],
"surface": [
{
"colorbar": {
"outlinewidth": 0,
"ticks": ""
},
"colorscale": [
[
0,
"#0d0887"
],
[
0.1111111111111111,
"#46039f"
],
[
0.2222222222222222,
"#7201a8"
],
[
0.3333333333333333,
"#9c179e"
],
[
0.4444444444444444,
"#bd3786"
],
[
0.5555555555555556,
"#d8576b"
],
[
0.6666666666666666,
"#ed7953"
],
[
0.7777777777777778,
"#fb9f3a"
],
[
0.8888888888888888,
"#fdca26"
],
[
1,
"#f0f921"
]
],
"type": "surface"
}
],
"table": [
{
"cells": {
"fill": {
"color": "#EBF0F8"
},
"line": {
"color": "white"
}
},
"header": {
"fill": {
"color": "#C8D4E3"
},
"line": {
"color": "white"
}
},
"type": "table"
}
]
},
"layout": {
"annotationdefaults": {
"arrowcolor": "#2a3f5f",
"arrowhead": 0,
"arrowwidth": 1
},
"coloraxis": {
"colorbar": {
"outlinewidth": 0,
"ticks": ""
}
},
"colorscale": {
"diverging": [
[
0,
"#8e0152"
],
[
0.1,
"#c51b7d"
],
[
0.2,
"#de77ae"
],
[
0.3,
"#f1b6da"
],
[
0.4,
"#fde0ef"
],
[
0.5,
"#f7f7f7"
],
[
0.6,
"#e6f5d0"
],
[
0.7,
"#b8e186"
],
[
0.8,
"#7fbc41"
],
[
0.9,
"#4d9221"
],
[
1,
"#276419"
]
],
"sequential": [
[
0,
"#0d0887"
],
[
0.1111111111111111,
"#46039f"
],
[
0.2222222222222222,
"#7201a8"
],
[
0.3333333333333333,
"#9c179e"
],
[
0.4444444444444444,
"#bd3786"
],
[
0.5555555555555556,
"#d8576b"
],
[
0.6666666666666666,
"#ed7953"
],
[
0.7777777777777778,
"#fb9f3a"
],
[
0.8888888888888888,
"#fdca26"
],
[
1,
"#f0f921"
]
],
"sequentialminus": [
[
0,
"#0d0887"
],
[
0.1111111111111111,
"#46039f"
],
[
0.2222222222222222,
"#7201a8"
],
[
0.3333333333333333,
"#9c179e"
],
[
0.4444444444444444,
"#bd3786"
],
[
0.5555555555555556,
"#d8576b"
],
[
0.6666666666666666,
"#ed7953"
],
[
0.7777777777777778,
"#fb9f3a"
],
[
0.8888888888888888,
"#fdca26"
],
[
1,
"#f0f921"
]
]
},
"colorway": [
"#636efa",
"#EF553B",
"#00cc96",
"#ab63fa",
"#FFA15A",
"#19d3f3",
"#FF6692",
"#B6E880",
"#FF97FF",
"#FECB52"
],
"font": {
"color": "#2a3f5f"
},
"geo": {
"bgcolor": "white",
"lakecolor": "white",
"landcolor": "#E5ECF6",
"showlakes": true,
"showland": true,
"subunitcolor": "white"
},
"hoverlabel": {
"align": "left"
},
"hovermode": "closest",
"mapbox": {
"style": "light"
},
"paper_bgcolor": "white",
"plot_bgcolor": "#E5ECF6",
"polar": {
"angularaxis": {
"gridcolor": "white",
"linecolor": "white",
"ticks": ""
},
"bgcolor": "#E5ECF6",
"radialaxis": {
"gridcolor": "white",
"linecolor": "white",
"ticks": ""
}
},
"scene": {
"xaxis": {
"backgroundcolor": "#E5ECF6",
"gridcolor": "white",
"gridwidth": 2,
"linecolor": "white",
"showbackground": true,
"ticks": "",
"zerolinecolor": "white"
},
"yaxis": {
"backgroundcolor": "#E5ECF6",
"gridcolor": "white",
"gridwidth": 2,
"linecolor": "white",
"showbackground": true,
"ticks": "",
"zerolinecolor": "white"
},
"zaxis": {
"backgroundcolor": "#E5ECF6",
"gridcolor": "white",
"gridwidth": 2,
"linecolor": "white",
"showbackground": true,
"ticks": "",
"zerolinecolor": "white"
}
},
"shapedefaults": {
"line": {
"color": "#2a3f5f"
}
},
"ternary": {
"aaxis": {
"gridcolor": "white",
"linecolor": "white",
"ticks": ""
},
"baxis": {
"gridcolor": "white",
"linecolor": "white",
"ticks": ""
},
"bgcolor": "#E5ECF6",
"caxis": {
"gridcolor": "white",
"linecolor": "white",
"ticks": ""
}
},
"title": {
"x": 0.05
},
"xaxis": {
"automargin": true,
"gridcolor": "white",
"linecolor": "white",
"ticks": "",
"title": {
"standoff": 15
},
"zerolinecolor": "white",
"zerolinewidth": 2
},
"yaxis": {
"automargin": true,
"gridcolor": "white",
"linecolor": "white",
"ticks": "",
"title": {
"standoff": 15
},
"zerolinecolor": "white",
"zerolinewidth": 2
}
}
},
"title": {
"text": "Landscape of alternative social media"
},
"width": 1200,
"xaxis": {
"anchor": "y",
"domain": [
0,
1
],
"title": {
"text": "PCA Component 1 (Explains 45% of variance in the data)"
}
},
"yaxis": {
"anchor": "x",
"domain": [
0,
1
],
"title": {
"text": "PCA Component 2 (Explains 24% of variance in the data)"
}
}
}
},
"text/html": [
"<div> <div id=\"67a74372-0e27-416f-8b7e-aedf09e76872\" class=\"plotly-graph-div\" style=\"height:1000px; width:1200px;\"></div> <script type=\"text/javascript\"> require([\"plotly\"], function(Plotly) { window.PLOTLYENV=window.PLOTLYENV || {}; if (document.getElementById(\"67a74372-0e27-416f-8b7e-aedf09e76872\")) { Plotly.newPlot( \"67a74372-0e27-416f-8b7e-aedf09e76872\", [{\"hovertemplate\": \"color=Comrad<br>0=%{x}<br>1=%{y}<br>text=%{text}<extra></extra>\", \"legendgroup\": \"Comrad\", \"marker\": {\"color\": \"#636efa\", \"symbol\": \"circle\"}, \"mode\": \"markers+text\", \"name\": \"Comrad\", \"orientation\": \"v\", \"showlegend\": true, \"text\": [\"Comrad\"], \"type\": \"scatter\", \"x\": [-0.5371889532432486], \"xaxis\": \"x\", \"y\": [1.6690599275270384], \"yaxis\": \"y\"}, {\"hovertemplate\": \"color=SecureScuttlebutt<br>0=%{x}<br>1=%{y}<br>text=%{text}<extra></extra>\", \"legendgroup\": \"SecureScuttlebutt\", \"marker\": {\"color\": \"#EF553B\", \"symbol\": \"circle\"}, \"mode\": \"markers+text\", \"name\": \"SecureScuttlebutt\", \"orientation\": \"v\", \"showlegend\": true, \"text\": [\"SecureScuttlebutt\"], \"type\": \"scatter\", \"x\": [0.5595718609453091], \"xaxis\": \"x\", \"y\": [0.7387372968787214], \"yaxis\": \"y\"}, {\"hovertemplate\": \"color=Diaspora<br>0=%{x}<br>1=%{y}<br>text=%{text}<extra></extra>\", \"legendgroup\": \"Diaspora\", \"marker\": {\"color\": \"#00cc96\", \"symbol\": \"circle\"}, \"mode\": \"markers+text\", \"name\": \"Diaspora\", \"orientation\": \"v\", \"showlegend\": true, \"text\": [\"Diaspora\"], \"type\": \"scatter\", \"x\": [1.6860059881786202], \"xaxis\": \"x\", \"y\": [-0.06589452477227059], \"yaxis\": \"y\"}, {\"hovertemplate\": \"color=Mastodon<br>0=%{x}<br>1=%{y}<br>text=%{text}<extra></extra>\", \"legendgroup\": \"Mastodon\", \"marker\": {\"color\": \"#ab63fa\", \"symbol\": \"circle\"}, \"mode\": \"markers+text\", \"name\": \"Mastodon\", \"orientation\": \"v\", \"showlegend\": true, \"text\": [\"Mastodon\"], \"type\": \"scatter\", \"x\": [1.6860059881786196], \"xaxis\": \"x\", \"y\": [-0.06589452477227072], \"yaxis\": \"y\"}, {\"hovertemplate\": \"color=Matrix<br>0=%{x}<br>1=%{y}<br>text=%{text}<extra></extra>\", \"legendgroup\": \"Matrix\", \"marker\": {\"color\": \"#FFA15A\", \"symbol\": \"circle\"}, \"mode\": \"markers+text\", \"name\": \"Matrix\", \"orientation\": \"v\", \"showlegend\": true, \"text\": [\"Matrix\"], \"type\": \"scatter\", \"x\": [-1.1227200411100027], \"xaxis\": \"x\", \"y\": [0.03413532817677556], \"yaxis\": \"y\"}, {\"hovertemplate\": \"color=BriarMessenger<br>0=%{x}<br>1=%{y}<br>text=%{text}<extra></extra>\", \"legendgroup\": \"BriarMessenger\", \"marker\": {\"color\": \"#19d3f3\", \"symbol\": \"circle\"}, \"mode\": \"markers+text\", \"name\": \"BriarMessenger\", \"orientation\": \"v\", \"showlegend\": true, \"text\": [\"BriarMessenger\"], \"type\": \"scatter\", \"x\": [-1.223569121311721], \"xaxis\": \"x\", \"y\": [-0.33510554193784764], \"yaxis\": \"y\"}, {\"hovertemplate\": \"color=CabalChat<br>0=%{x}<br>1=%{y}<br>text=%{text}<extra></extra>\", \"legendgroup\": \"CabalChat\", \"marker\": {\"color\": \"#FF6692\", \"symbol\": \"circle\"}, \"mode\": \"markers+text\", \"name\": \"CabalChat\", \"orientation\": \"v\", \"showlegend\": true, \"text\": [\"CabalChat\"], \"type\": \"scatter\", \"x\": [0.2393460935661281], \"xaxis\": \"x\", \"y\": [-1.446848658722153], \"yaxis\": \"y\"}, {\"hovertemplate\": \"color=Signal<br>0=%{x}<br>1=%{y}<br>text=%{text}<extra></extra>\", \"legendgroup\": \"Signal\", \"marker\": {\"color\": \"#B6E880\", \"symbol\": \"circle\"}, \"mode\": \"markers+text\", \"name\": \"Signal\", \"orientation\": \"v\", \"showlegend\": true, \"text\": [\"Signal\"], \"type\": \"scatter\", \"x\": [-1.2874518152037042], \"xaxis\": \"x\", \"y\": [-0.5281893023779932], \"yaxis\": \"y\"}], {\"annotations\": [{\"ax\": 0, \"ay\": 0, \"font\": {\"s
4 years ago
" \n",
"var gd = document.getElementById('67a74372-0e27-416f-8b7e-aedf09e76872');\n",
"var x = new MutationObserver(function (mutations, observer) {{\n",
" var display = window.getComputedStyle(gd).display;\n",
" if (!display || display === 'none') {{\n",
" console.log([gd, 'removed!']);\n",
" Plotly.purge(gd);\n",
" observer.disconnect();\n",
" }}\n",
"}});\n",
"\n",
"// Listen for the removal of the full notebook cells\n",
"var notebookContainer = gd.closest('#notebook-container');\n",
"if (notebookContainer) {{\n",
" x.observe(notebookContainer, {childList: true});\n",
"}}\n",
"\n",
"// Listen for the clearing of the current output cell\n",
"var outputEl = gd.closest('.output');\n",
"if (outputEl) {{\n",
" x.observe(outputEl, {childList: true});\n",
"}}\n",
"\n",
" }) }; }); </script> </div>"
]
},
"metadata": {},
"output_type": "display_data"
}
],
"source": [
"import plotly.express as px\n",
"from sklearn.decomposition import PCA\n",
"from sklearn.preprocessing import StandardScaler\n",
"import numpy as np\n",
"\n",
"features = df_data.columns\n",
"pca = PCA(n_components=2)\n",
"components = pca.fit_transform(df_data)\n",
"\n",
"loadings = pca.components_.T * np.sqrt(pca.explained_variance_)\n",
"total_var = pca.explained_variance_ratio_.sum() * 100\n",
"x_var = pca.explained_variance_ratio_[0] * 100\n",
"y_var = pca.explained_variance_ratio_[1] * 100\n",
"# print(pca.explained_variance_ratio_)\n",
"\n",
"fig = px.scatter(\n",
" components, \n",
" x=0,\n",
" y=1,\n",
" color=df.index,\n",
" text=df.index,\n",
" height=1000,\n",
" width=1200,\n",
" title=f'Landscape of alternative social media',\n",
")\n",
"fig.update_layout(\n",
" font=dict(\n",
" family=\"Courier New, monospace\",\n",
" size=22,\n",
" ),\n",
" xaxis_title=f'PCA Component 1 (Explains {x_var:.0f}% of variance in the data)',\n",
" yaxis_title=f'PCA Component 2 (Explains {y_var:.0f}% of variance in the data)',\n",
")\n",
"for i, feature in enumerate(features):\n",
" fig.add_shape(\n",
" type='line',\n",
" x0=0, y0=0,\n",
" x1=loadings[i, 0]*3,\n",
" y1=loadings[i, 1]*3\n",
" )\n",
" fig.add_annotation(\n",
" x=loadings[i, 0]*3,\n",
" y=loadings[i, 1]*3,\n",
" ax=0, ay=0,\n",
" xanchor=\"center\",\n",
" yanchor=\"bottom\",\n",
" text=feature,\n",
" font=dict(size=16)\n",
" )\n",
"fig.show()\n",
"fig.write_image('fig.landscape-alt-soc-media.png')"
]
},
{
"cell_type": "code",
"execution_count": 42,
"metadata": {},
"outputs": [],
"source": [
"# !pip install -U kaleido\n",
"# !pip install psutil"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": []
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": []
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": []
}
],
"metadata": {
"kernelspec": {
"display_name": "Python 3",
"language": "python",
"name": "python3"
},
"language_info": {
"codemirror_mode": {
"name": "ipython",
"version": 3
},
"file_extension": ".py",
"mimetype": "text/x-python",
"name": "python",
"nbconvert_exporter": "python",
"pygments_lexer": "ipython3",
"version": "3.7.7"
}
},
"nbformat": 4,
"nbformat_minor": 4
}