bash-4.2:~/posts/projects/signatures_plot$ less signatures_counter.html

Automatically generating a plot of signatures of a petition

I'm in a collective that started a petition asking for a referendum about (generative) AI.

We wanted a graphic of the evolution of votes according to time, so I hacked something together.

You can see the result here

Fetching the data

I store the data in a two-column CSV file (the columns are datetime and sigcount). The file is updated via a simple bash script.

The script basically gets the number of votes from the graphql API, then filters the interesting value with jq (a json querying command), and sticks it with the current date and time. Here it is :

[update_signatures_database.sh]

#!/bin/bash

# working path
WPATH="/home/oskar/projects/petition_signatures_count"

# current number of votes from petitions.lecese.fr
nbvotes=$(curl -sSH "Content-Type: application/json" -d '{ "query": "{ initiatives { id title { translations { locale text } } onlineVotes } }" }' "https://petitions.lecese.fr/api" | jq ".data.initiatives.[] | select(.id == \"821\") | .onlineVotes")
# line to write
csvline=$(TZ='Europe/Paris' date '+%Y-%m-%d %H:%M:%S'),$nbvotes

# actualy update the database
echo $csvline >> "$WPATH/database.csv"

Then, I used cron to run this every hour :

*/30 * * * * cd /home/oskar/projects/petition_signatures_count/ ; ./update_signatures_database.sh

plotting the graph

I use plotly to plot the graph because it can easily output html files, and because it really easy to use with pandas (that I use to read the csv).

This code is a simplified version of what I use, you can see the real code in tilde.town, at projects/petition_signatures_count/write_plot.py.

[write_plot.py]

#!env/bin/python3
import plotly.express as px
import pandas as pd

df = pd.read_csv("database.csv")
df.datetime = pd.to_datetime(df.datetime)
df.sort_values(by="datetime")

fig = px.line(df, x="datetime", y="sigcount")

fig.write_html("out/graphique.html")

In order for the graph to update with the data, I simply execute the python code after each update of the databse. That is done by adding the following line at the end of update_signatures_database.sh :

$WPATH/env/bin/python3 $WPATH/write_plot.py

Pretty details

I added display details, such as colors, markers for datapoints, french formatting of the dates, and better display of date and time when the mouse hovers a point.

Here is the full code :

#!env/bin/python3
import plotly.express as px
import pandas as pd


df = pd.read_csv("database.csv")
df.datetime = pd.to_datetime(df.datetime)

# stable (timsort ?), should be better for mostly-sorted data
df.sort_values(by="datetime", kind="stable")

fig = px.line(df, x="datetime", y="sigcount",
              title="Nombre de signatures",
              template="plotly_dark",
              line_shape="linear",
              markers=True,
              )

fig.update_traces(
    marker=dict(size=3, symbol="circle"),
    line=dict(color="#80C800", width=1),
)

fig.update_xaxes(tickformat="%d/%m/%Y")
fig.update_traces(hovertemplate="<b>%{y}</b> signatures<br>Le %{x|%d/%m/%Y<br>À %H:%M:%S}")

fig.write_html("/home/oskar/public_html/posts/projects/signatures_plot/plot.html")