Python

ページにアクセスしたログを使って円グラフに表示する方法

今回はログファイルの情報を使ってアクセス数の上位10件を取得して円グラフを表示する為のメモです。

ファイル構造

下記です。

プロジェクト名
       | ----  main.py
       | ---- visitor_ips.txt 

visitor_ips.txtはログの記載があるファイル名です。

記述は全てmain.pyに行います。

visitor_ips.txtの中身

下記みたいな記載がずらーっと並んでいるとします。

222	v-modelについてv-on・v-bindとの違いと使い方	https://newsite-make.com/v-model/	2025-04-20 18:41:38

ライブラリのインストール

下記のコマンドを叩きます。

pip install pandas matplotlib

ライブラリを使う為の記述

下記の記述をします。

import pandas as pd 
import matplotlib.pyplot as plt
import matplotlib

1行目は表を扱う為のライブラリで2行目はグラフ表示の関数を使えるようにして3行目はライブラリの設定の為にあります。

表示する文字のフォントの設定

下記の記述をします。

import pandas as pd
import matplotlib.pyplot as plt
import matplotlib

matplotlib.rcParams['font.family'] = 'Hiragino Sans'         // この行を追加

表データの取得

下記の記述をします。

import pandas as pd
import matplotlib.pyplot as plt
import matplotlib

matplotlib.rcParams['font.family'] = 'Hiragino Sans'


//ここから追加
file_path = "./visitor_ips.txt"
chart = pd.read_csv(file_path, sep='\t', names=['IP', 'Title', 'URL', 'Date'])
//ここまで追加

10行目は「read_csv」関数でCSVやテキストファイルを読み込んで DataFrameに変換します。

引数の意味は下記になります。

  • file_path : ログファイルの場所
  • sep : データの区切り文字を タブ(\t) に指定
  • names : ファイルにヘッダー(列名)がない前提で、自分で列名を定義している。今回はファイルの内容を扱うのでこれができる

namesですがログファイルに下記の記述があったとします。

222	v-modelについてv-on・v-bindとの違いと使い方	https://newsite-make.com/v-model/	2025-04-20 18:41:38

取得するデータは下記になります。

取得するデータの日付の指定

下記の記述をします。

import pandas as pd
import matplotlib.pyplot as plt
import matplotlib

matplotlib.rcParams['font.family'] = 'Hiragino Sans'
file_path = "./visitor_ips.txt"
chart = pd.read_csv(file_path, sep='\t', names=['IP', 'Title', 'URL', 'Date'])


//ここから追加
chart['Date'] = pd.to_datetime(chart['Date'])
start_date = '2025-04-25'
end_date = '2025-04-26'
chart = chart[(chart['Date'] >= start_date) & (chart['Date'] <= end_date)]
//ここまで追加

円グラフの文字化け対策

下記の記述をします。

import pandas as pd
import matplotlib.pyplot as plt
import matplotlib

matplotlib.rcParams['font.family'] = 'Hiragino Sans'
file_path = "./visitor_ips.txt"
chart = pd.read_csv(file_path, sep='\t', names=['IP', 'Title', 'URL', 'Date'])
chart['Date'] = pd.to_datetime(chart['Date'])
start_date = '2025-04-25'
end_date = '2025-04-26'
chart = chart[(chart['Date'] >= start_date) & (chart['Date'] <= end_date)]
chart['Title'] = chart['Title'].str.replace(r'[${}]', '', regex=True)    //この行を追加

「r'[${}]’」は正規表現です。

タイトルの中の「$」・「{」・「}」を対象とするという意味です。

しかしタイトルは「v-modelについてv-on・v-bindとの違いと使い方」になっていて「$」・「{」・「}」を含んでいません。

matplotlibを使うとタイトルの中に自動的に「$」・「{」・「}」を含むようになります。

replaceメソッドでそれを空にしないと文字化けを起こします。

だから追記した記述が必要になります。

「regex=True」の記述があることで「r'[${}]’」を正規表現として認識するようになります。

上位10件の取得

下記の記述をします。

import pandas as pd
import matplotlib.pyplot as plt
import matplotlib

matplotlib.rcParams['font.family'] = 'Hiragino Sans'
file_path = "./visitor_ips.txt"
chart = pd.read_csv(file_path, sep='\t', names=['IP', 'Title', 'URL', 'Date'])
chart['Date'] = pd.to_datetime(chart['Date'])
start_date = '2025-04-25'
end_date = '2025-04-26'
chart = chart[(chart['Date'] >= start_date) & (chart['Date'] <= end_date)]
chart['Title'] = chart['Title'].str.replace(r'[${}]', '', regex=True)
title_counts = chart['Title'].value_counts().head(10)       //この行を追加

head(10)の10が10件取得するという意味です。

円グラフの生成

下記の記述をします。

import pandas as pd
import matplotlib.pyplot as plt
import matplotlib

matplotlib.rcParams['font.family'] = 'Hiragino Sans'
file_path = "./visitor_ips.txt"
chart = pd.read_csv(file_path, sep='\t', names=['IP', 'Title', 'URL', 'Date'])
chart['Date'] = pd.to_datetime(chart['Date'])
start_date = '2025-04-25'
end_date = '2025-04-26'
chart = chart[(chart['Date'] >= start_date) & (chart['Date'] <= end_date)]
chart['Title'] = chart['Title'].str.replace(r'[${}]', '', regex=True)
title_counts = chart['Title'].value_counts().head(10) 


//ここから追加
fig, ax = plt.subplots(figsize=(10, 10))
title_counts.plot.pie(ax=ax, autopct='%1.1f%%', startangle=90, counterclock=False)
//ここまで追加

17行目でグラフを描画する為のキャンバス(fig)と軸(ax)を用意してグラフのサイズを 横10インチ × 縦10インチ に指定します。

「fig, ax」の並び順は固定です。

18行目は下記の意味になります。

  • ax=ax : どのaxに描くか(右辺のaxは17行目のこと)
  • autopct=’%1.1f%%’ : 割合の小数点1桁まで表示
  • startangle=90 : 円グラフを90度回転(12時スタートに)
  • counterclock=False : 時計回りに表示(デフォルトは反時計回り)

円グラフの表示

下記の記述をします。

import pandas as pd
import matplotlib.pyplot as plt
import matplotlib

matplotlib.rcParams['font.family'] = 'Hiragino Sans'
file_path = "./visitor_ips.txt"
chart = pd.read_csv(file_path, sep='\t', names=['IP', 'Title', 'URL', 'Date'])
chart['Date'] = pd.to_datetime(chart['Date'])
start_date = '2025-04-25'
end_date = '2025-04-26'
chart = chart[(chart['Date'] >= start_date) & (chart['Date'] <= end_date)]
chart['Title'] = chart['Title'].str.replace(r'[${}]', '', regex=True)
title_counts = chart['Title'].value_counts().head(10) 

fig, ax = plt.subplots(figsize=(10, 10))
title_counts.plot.pie(ax=ax, autopct='%1.1f%%', startangle=90, counterclock=False)


//ここから追加
plt.title(f"{start_date}〜{end_date}の記事別アクセス割合(上位10件)", fontsize=14)
plt.ylabel('')
plt.show()
//ここまで追加

20行目は円グラフに表示するタイトルの文言と文字サイズを設定しています。(解説の最後に載せている図の赤枠)

「fontsize=14」が文字サイズです。

21行目はグラフの Y軸ラベル(縦軸の名前)を空にする指定です。

今回はなくても問題ないですが場合によってはY軸にTitleが表示される場合があり、それを防ぐ為に記述しています。

22行目で円グラフを表示します。

下記が最終的な円グラフです。(今回はログが1つしかないですが下記の図は色んなログがいっぱいある状態で円グラフにしています。)