Skip to content


Switch branches/tags

Name already in use

A tag already exists with the provided branch name. Many Git commands accept both tag and branch names, so creating this branch may cause unexpected behavior. Are you sure you want to create this branch?

chat-miner: turn your chats into artwork

PyPI Version License: MIT Code style: black

chat-miner provides lean parsers for every major platform transforming chats into pandas dataframes. Artistic visualizations allow you to explore your data differently and create artwork from your chats.

1. Installation

Latest release including dependencies can be installed via PyPI:

pip install chat-miner

If you're interested in contributing, running the latest source code, or just like to build everything yourself:

git clone
cd chat-miner
pip install -r requirements.txt

2. Exporting chat logs

Have a look at the official tutorials for WhatsApp, Signal, Telegram, or Facebook Messenger to learn how to export chat logs for your platform.

3. Parsing

Following code showcases the WhatsAppParser module. The usage of SignalParser, TelegramJsonParser, and FacebookMessengerParser follows the same pattern.

from chatminer.chatparsers import WhatsAppParser

parser = WhatsAppParser(FILEPATH)

4. Visualizing

import chatminer.visualizations as vis
import matplotlib.pyplot as plt

4.1 Heatmap: Message count per day

fig, ax = plt.subplots(2, 1, figsize=(9, 3))
ax[0] = vis.calendar_heatmap(parser.df, year=2020, cmap='Oranges', ax=ax[0])
ax[1] = vis.calendar_heatmap(parser.df, year=2021, linewidth=0, monthly_border=True, ax=ax[1])

4.2 Sunburst: Message count per daytime

fig, ax = plt.subplots(1, 2, figsize=(7, 3), subplot_kw={'projection': 'polar'})
ax[0] = vis.sunburst(parser.df, highlight_max=True, isolines=[2500, 5000], isolines_relative=False, ax=ax[0])
ax[1] = vis.sunburst(parser.df, highlight_max=False, isolines=[0.5, 1], color='C1', ax=ax[1])

4.3 Wordcloud: Word frequencies

fig, ax = plt.subplots(figsize=(8, 3))
stopwords = ['these', 'are', 'stopwords']
kwargs={"background_color": "white", "width": 800, "height": 300, "max_words": 500}
ax = vis.wordcloud(parser.df, ax=ax, stopwords=stopwords, **kwargs)