[Python] Carte thermique de style calendrier (avec affichage des jours fériés)

Objectif de cet article

Créez une carte thermique de style calendrier avec des jours fériés, par exemple:

calendar.png

D'ailleurs, pour les données, la date de publication de l'article de @yaotti acquise à l'aide de l'API Qiita est utilisée comme 1 post = 1 événement.

Méthode de visualisation similaire

Bien qu'elle soit appelée par différents noms, la figure suivante sur GitHub est également simple et bonne.

contributions_graph.png Source: [Afficher les contributions dans le profil d'aide GitHub](https://help.github.com/en/github/setting-up-and-managing-your-github-profile/viewing-contributions-on-your -profile # contributions-calendrier)

En Python, il semble qu'un diagramme similaire puisse être créé avec une bibliothèque appelée `` calmap```.

image02.png

GitHub:martijnvermaat/calmap

De plus, je ne l'ai pas trouvé en Python, mais en R, vous pouvez afficher le calendrier par mois avec la bibliothèque openair. openair:calendarPlot()

image03.png Source: RPubs Plotting with openair

cependant,

Je n'ai rien trouvé qui se soit réuni ...

Commentaire

J'ai donc écrit le code moi-même!

Préparation

Tout d'abord, préparez la bibliothèque.

!pip install jpholiday #Pour obtenir des informations sur les vacances
!pip install japanize_matplotlib #Pour la japonaisisation de plt
import numpy as np
import pandas as pd
import requests
import json
from pandas.io.json import json_normalize
import datetime
import jpholiday

import seaborn as sns
import matplotlib.pyplot as plt
import japanize_matplotlib
import matplotlib.patches as patches #Dessinez un rectangle

Préparation des données

Préparez les données d'événement appropriées. Ici, j'ai récemment essayé d'utiliser l'API Qiita, donc je pense que publier un article Qiita est un événement, et la date de publication Visualiser.

Les données de publication récupérées ont le format suivant. Toutes les autres données sont correctes tant qu'il y a une colonne d'horodatage. Cette fois, les informations d'horodatage sont contenues dans la colonne `` created_at ''. image04.jpg

Tout d'abord, convertissez la valeur contenue sous forme de chaîne de caractères dans la colonne d'horodatage en quelque chose appelé type datetime.datetime`.

le format doit être modifié en conséquence.



```python
df["created_at"] = pd.to_datetime(df["created_at"], format='%Y-%m-%dT%H:%M:%S+09:00')

Ensuite, à partir d'ici, des informations telles que l'année et le mois sont extraites.

df["year"] = df["created_at"].dt.year
df["month"] = df["created_at"].dt.month
df["day"] = df["created_at"].dt.day

De plus, la fonction auto-créée american_calendar récupère le numéro de semaine américain et les informations sur le jour. Cliquez ici pour plus de détails: Get American Week Number

def american_calendar
def american_calendar(year, month, day):
    #Datetime de l'année d'entrée.Créer des données de type de date
    inp = datetime.date(year=year, month=month, day=day)
    #Datetime le premier jour de l'année d'entrée.Créer des données de type de date
    first = datetime.date(year=year, month=1, day=1)

    #Tout d'abord, calculez le jour
    inp_how = (inp.weekday()+1) % 7 #+1 est de changer le jour pour commencer le dimanche
    first_how = (first.weekday()+1)%7
    
    #Moins que,Calcul du numéro de semaine
    #En haut à gauche du calendrier(Premier dimanche)Obtenez la date de
    upper_left = first - datetime.timedelta(days=first_how)

    #Obtenez le numéro de la semaine en calculant la différence du nombre de jours à partir de la date de base
    inp_week = (inp - upper_left).days // 7
    
    return year, inp_week, inp_how
cal = np.array([american_calendar(ymd[0], ymd[1], ymd[2]) for ymd in df.loc[:,["year","month","day"]].values])

df["week"] = cal[:,1]
df["dayofweek"] = cal[:,2]

À ce stade, les données devraient ressembler à ceci:

df.loc[:,["created_at", "year", "month", "day", "week", "dayofweek"]].head()

image06.png

Ici, semaine '' est le numéro de la semaine et jour de la semaine '' est le jour. Notez qu'ici jour de la semaine '' est suivi de 0``` le dimanche, `` 1``` le lundi ...

Agrégation d'événements

Spécifiez ici année '' et utilisez tableau_pivot '' pour filtrer les données et les agréger par date.

year = 2012

idx_name = "week"
col_name = "dayofweek"

tmp_df = df[df["year"]==year]
pv = tmp_df.pivot_table(index=idx_name, columns=col_name, values="body", aggfunc="count") #N'importe quel corps va bien
pv = pd.DataFrame(pv.values, columns=pv.columns.values ,index=pv.index.values)
pv

image07.png

Cette trame de données pv '' n'affiche aucune semaine sans événement et ne peut pas être utilisée telle quelle. Par conséquent, créez à l'avance un bloc de données carré de 54 × 7 mat '' comme un calendrier et formatez-le en y ajoutant des valeurs.

pv.columns = [int(num) for num in pv.columns]
pv.index = [int(num) for num in pv.index]
pv = pv.fillna(0)

mat = pd.DataFrame(index=list(range(54)), columns=list(range(7)))
mat = mat.fillna(0)

mat = mat.add(pv, fill_value=0)
mat = mat.applymap(lambda x: int(x))
mat

image08.png

C'est beau. (En fait, il y a jusqu'à 54 lignes)

Ensuite, préparez la date à afficher sur le calendrier.

mat_date = pd.DataFrame(index=list(range(54)), columns=list(range(7)))
mat_date = mat_date.fillna("")

tmp = datetime.date(year=year, month=1, day=1)

for i in range(366):
    if tmp.year==year:
        y,week,how = american_calendar(tmp.year, tmp.month, tmp.day)
        mat_date.loc[week,how] = str(tmp.month) +"/"+ str(tmp.day)
    tmp+=datetime.timedelta(days=1)
    
lab = mat_date.values
lab

image09.png Vous pouvez créer un tableau 54x7 avec la chaîne de date comme élément, comme indiqué ci-dessus. Les deux premiers éléments étant des lettres vides, cette année débutera mardi.

Visualisation

Enfin, dessinez un calendrier en utilisant sns.heatmap```. Quant à l'affichage des vacances, jpholiday.year_holidays (year) '' contient une liste des jours fériés pour une année spécifique, donc à partir de cette information, patchs.Rectangle '' sera utilisé pour marquer chaque carré rouge un par un. Je dessine.

plt.figure(figsize=(10,30))
ax = sns.heatmap(mat, annot=lab, square=True, fmt="", cmap="Greens", cbar=False, linewidths=0.1, linecolor="silver")
ax.set_xticklabels(["journée","Mois","Feu","eau","bois","Argent","sol"])

for holiday in jpholiday.year_holidays(year):
    tmp = holiday[0]
    y,week,how = american_calendar(tmp.year, tmp.month, tmp.day)

    r = patches.Rectangle(xy=(how, week), width=1, height=1, edgecolor='red', fill=False, linewidth=1)
    ax.add_patch(r)

ax.tick_params(right=False, top=True, labelright=False, labeltop=True)
plt.xlim((-0.1,7.1))
plt.title("Calendar Heatmap (year:{0})".format(year))
plt.show()

image11.jpg

c'est tout!

Liste de codes

Afficher la liste
import numpy as np
import pandas as pd
import requests
import json
from pandas.io.json import json_normalize
import datetime
import jpholiday

import seaborn as sns
import matplotlib.pyplot as plt
import japanize_matplotlib
import matplotlib.patches as patches #Dessinez un rectangle

#Préparation des données
df["created_at"] = pd.to_datetime(df["created_at"], format='%Y-%m-%dT%H:%M:%S+09:00')
df["year"] = df["created_at"].dt.year
df["month"] = df["created_at"].dt.month
df["day"] = df["created_at"].dt.day

cal = np.array([american_calendar(ymd[0], ymd[1], ymd[2]) for ymd in df.loc[:,["year","month","day"]].values])
df["week"] = cal[:,1]
df["dayofweek"] = cal[:,2]

#Agrégation de données
year = 2012
idx_name = "week"
col_name = "dayofweek"

tmp_df = df[df["year"]==year]
pv = tmp_df.pivot_table(index=idx_name, columns=col_name, values="body", aggfunc="count") #N'importe quel corps va bien
pv = pd.DataFrame(pv.values, columns=pv.columns.values ,index=pv.index.values)

#Formatage des données agrégées
pv.columns = [int(num) for num in pv.columns]
pv.index = [int(num) for num in pv.index]
pv = pv.fillna(0)
mat = pd.DataFrame(index=list(range(54)), columns=list(range(7)))
mat = mat.fillna(0)
mat = mat.add(pv, fill_value=0)
mat = mat.applymap(lambda x: int(x))

#Création de l'étiquette de date
mat_date = pd.DataFrame(index=list(range(54)), columns=list(range(7)))
mat_date = mat_date.fillna("")

tmp = datetime.date(year=year, month=1, day=1)

for i in range(366):
    if tmp.year==year:
        y,week,how = american_calendar(tmp.year, tmp.month, tmp.day)
        mat_date.loc[week,how] = str(tmp.month) +"/"+ str(tmp.day)
    tmp+=datetime.timedelta(days=1)

lab = mat_date.values


#Visualisation
plt.figure(figsize=(10,30))
ax = sns.heatmap(mat, annot=lab, square=True, fmt="", cmap="Greens", cbar=False, linewidths=0.1, linecolor="silver")
ax.set_xticklabels(["journée","Mois","Feu","eau","bois","Argent","sol"])

for holiday in jpholiday.year_holidays(year):
    tmp = holiday[0]
    y,week,how = american_calendar(tmp.year, tmp.month, tmp.day)

    r = patches.Rectangle(xy=(how, week), width=1, height=1, edgecolor="red", fill=False, linewidth=1)
    ax.add_patch(r)

ax.tick_params(right=False, top=True, labelright=False, labeltop=True)
plt.xlim((-0.1,7.1))
plt.title("Calendar Heatmap (year:{0})".format(year))
plt.show()

référence

Aide GitHub: Afficher les contributions dans les profils (https://help.github.com/en/github/setting-up-and-managing-your-github-profile/viewing-contributions-on-your- profile # contributions-calendar) GitHub:martijnvermaat/calmap openair:calendarPlot() RPubs:Plotting with openair GitHub: Bibliothèque pour obtenir des vacances japonaises jpholiday stack overflow:How to Add Text plus Value in Python Seaborn Heatmap

Recommended Posts

[Python] Carte thermique de style calendrier (avec affichage des jours fériés)
Simulation COVID-19 avec python (modèle SIR) ~~ avec carte de chaleur préfectorale ~~
Essayez d'afficher la carte google et la carte géographique avec python
Calculer et afficher le poids standard avec python
Afficher Python 3 dans le navigateur avec MAMP
Carte des informations de location sur une carte avec python
[Python] Afficher les éléments de la liste en utilisant des arguments de longueur variable
Carte thermique pour la recherche de grille avec Matplotlib
Comment afficher le japonais python avec lolipop
J'ai fait une carte hexadécimale avec Python
Analyse de conduction thermique bidimensionnelle non stationnaire avec Python
Essayez de dessiner une carte avec python + cartopy 0.18.0
FizzBuzz en Python3
Grattage avec Python
Statistiques avec python
Grattage avec Python
Python avec Go
Afficher de manière interactive des courbes algébriques en Python, Jupyter
Twilio avec Python
Intégrer avec Python
[Écrire sur la carte avec plotly] Visualisation dynamique avec plotly [python]
Jouez avec 2016-Python
AES256 avec python
Testé avec Python
python commence par ()
Folium: Visualisez les données sur une carte avec Python
avec syntaxe (Python)
Affichage des données d'informations de position en Python --Essayez de tracer avec la bibliothèque d'affichage de carte (folium) -
Bingo avec python
Zundokokiyoshi avec python
Visualiser grib2 sur une carte avec python (matplotlib)
Excel avec Python
Micro-ordinateur avec Python
Cast avec python
Il est trop difficile d'afficher le japonais avec le python3 de Vim.
[Python] Comment créer une matrice de corrélation et une carte thermique
Afficher et prendre des images de caméra Web avec Python Kivy [GUI]
Description à afficher avec Python> fonction> Docstrings> help () / .__ doc__
Afficher l'image de la caméra USB avec OpenCV de Python avec Raspeye
Zip, décompressez avec python
Django 1.11 a démarré avec Python3.6
Jugement des nombres premiers avec Python
Python avec eclipse + PyDev.
Grattage en Python (préparation)
Essayez de gratter avec Python.
Apprendre Python avec ChemTHEATER 03
Recherche séquentielle avec Python
"Orienté objet" appris avec python
Exécutez Python avec VBA
Manipuler yaml avec python
Résolvez AtCoder 167 avec python
Communication série avec python
[Python] Utiliser JSON avec Python
Apprendre Python avec ChemTHEATER 05-1
Apprenez Python avec ChemTHEATER
Exécutez prepDE.py avec python3
1.1 Premiers pas avec Python
Collecter des tweets avec Python
Binarisation avec OpenCV / Python
3. 3. Programmation IA avec Python