すのふらてっく

すのふらてっく

日々の備忘録

応用情報技術者試験に向けてやる気出す

もう次の応用情報技術者試験まで2か月程度なのに、忙しさにかまけて何もやれていないので、気合を入れる。

とりあえず前回は全然足りなかった。
f:id:snofra:20180208013410j:plain





f:id:snofra:20180208013511j:plain

何故午後問題は結構余裕で行けた(結果に出てないが)ので、午前を何とかしないとダメだということが分かった。

勉強は基本スマホで過去問をひたすら解いていたんだけど、やり方がいまいちだったのかこんな問題あったっけ?みたいな感覚にずっととらわれていた気がする。

今回も基本はスマホでひたすら解き続けるというのでいいけど、たぶん根本理解してなくて、内容というよりも画面の感じで覚えてたんだと思う。

わからない箇所はスクリーンショットなり取って、土日でしっかり調べて押さえておくという習慣をつけよう。

そもそも応用情報技術者試験は自分のベース知識を向上させようというのが根本で、別に受かるために勉強しているわけじゃない。
そこは忘れたらだめだというのを自分に言い聞かす。


まだ落ちるしーとか、今毎日終電で忙しいからーとかいっとったら一生何もできん。

とりあえず明日1問やるところから始める。

matplotlibでラジカツスターズ!のコーナー正解率を分析する

もうひとつのブログ記事でラジカツスターズ!のコーナー正解率を分析するネタをやるので、そのテック部分について書く。

基本はmatplotlibでだらだら書いてるだけ。


ソース

python 3.5
jupiter notebook上での実装


各放送回別の問題数、正解数と、累計正解率のplot

import pandas as pd
import matplotlib.pyplot as plt
import statsmodels.api as sm
import numpy as np
import datetime
%pylab inline --no-import-all

#csvファイルのロード
df = pd.read_csv('xxx/radikatsu_stars_list.csv', index_col=0, parse_dates=[1])
df = df.fillna(0)
radikatsu = df.loc[0:] # todo 正解数の抽出できなかったので加工
on_air = radikatsu.index # 放送回数

series_correct_num = radikatsu['正解数'].astype(int)
series_question_num = radikatsu['出題数'].astype(int)

# 正解数と出題数をそれぞれ累計
list_cumulative_correct = [] # 正解数
list_cumulative_question = [] # 出題数
list_cumulative_correct_rate = [] # 正解率
cumulative_correct = 0
cumulative_question = 0
cumulative_correct_rate = 0
for x, y in zip(series_correct_num, series_question_num):
    cumulative_correct = cumulative_correct + x
    cumulative_question = cumulative_question + y
    cumulative_correct_rate = (cumulative_correct / cumulative_question) * 100
    list_cumulative_correct.append(cumulative_correct)
    list_cumulative_question.append(cumulative_question)
    list_cumulative_correct_rate.append(cumulative_correct_rate)
    
# 累計数をDataFrameにする
cumulative = pd.DataFrame(
    {'01.on_air': on_air,
     '02.question': list_cumulative_question,
     '03.correct': list_cumulative_correct,
     '04.rate': list_cumulative_correct_rate})

cumulative.to_csv("cumulative.csv")

# 線形回帰
mod = sm.OLS(list_cumulative_correct, sm.add_constant(on_air))
res = mod.fit()
a, b= res.params # 相関係数を取得

# 100問正解するまでに何回かかるか
list_on_air_goal = []
num = 0
on_air_goal = 1
while num < 100:
    num = a + b * on_air_goal
    list_on_air_goal.append(on_air_goal)
    on_air_goal = on_air_goal + 1

# 正解数推移
plt.figure(figsize=(20, 10), dpi=100, linewidth = 100)
plt.tick_params(labelsize=18)
plt.plot(on_air, list_cumulative_correct, marker='o', color='lightblue', ms=15) # 放送回ごとの正解数
plt.plot(list_on_air_goal, a + b * np.array(list_on_air_goal), lw=8, alpha=0.5, ls='-', color='#C7243A') # 直線
plt.plot(max(list_on_air_goal), 100, marker='*', color='#B61972', ms=20) # 目標回
plt.yticks( np.arange(0, 120, 10) )
plt.xticks( np.arange(0, 110, 5) )
plt.ylabel('correct answers', fontsize=15)
plt.xlabel('on air', fontsize=15)
plt.savefig('list_on_air_goal.png') # グラフのダウンロード
plt.show()

# 各放送回別の問題数、正解数と、累計正解率
plt.figure(figsize=(20, 10), dpi=100, linewidth = 100)
ax = plt.subplot()
ax.bar(on_air, series_question_num, color='#44A5CB', align="center", label="Question num")
ax.bar(on_air, series_correct_num, color='#EDAD0B', align="center", label="Correct num")
ax.legend(loc=2) # 凡例
plt.xlabel('on air', fontsize=15)
plt.ylabel("Question/Correct num", fontsize=15)
plt.yticks( np.arange(0, max(series_question_num) + 3, 1) )

ax2 = ax.twinx()
plt.plot(on_air, list_cumulative_correct_rate, marker='o', color='#C7243A') # 放送回までの正解率
plt.ylabel("Correct answer rate(Cumulative)", fontsize=15)
plt.savefig('questionCorrectAll.png') # グラフのダウンロード
plt.show()


radikatsu = df.loc[0:] # todo 正解数の抽出できなかったので加工

DataFrameで正解数を取ろうとしたときに、エラーになってうまく取れず、しょうがなく一旦上記でかわしてからとるようにした。

どうやればうまくとれたのかちょっとよくわからん。


メンバー別の問題数、正解数と、累計正解率のplot

def member_answer(member):

    #担当回チェック
    list_question = [] #問題数
    list_correct = [] #正解数
    list_date = [] #放送年月
    bfr_date = None
    question_num = 0
    answer_num = 0
    len_cur = len(radikatsu) 
    # DataFrameの行単位でループ
    for index, i in enumerate(radikatsu.iterrows()):
        # tupleの値部分の取得
        series_row = i[1]

        target = series_row['公開日'].strftime("%Y-%m")

        # パーソナリティ回だった場合
        if series_row[member] == 1:
            # 同年月だった場合累計
            if target == bfr_date:
                question_num = question_num + series_row['出題数']
                answer_num = answer_num + series_row['正解数']

        # 1行目もしくは年月が切り替わった場合
        if target != bfr_date and bfr_date is not None:
            list_date.append(bfr_date)
            list_question.append(question_num)
            list_correct.append(answer_num)
            # パーソナリティ回だった場合、その年月を設定しなおす。
            if series_row[member] == 1:
                question_num = series_row['出題数']
                answer_num = series_row['正解数']
            else:
                question_num = 0
                answer_num = 0

        bfr_date = target

        # 最終行の追加
        if len_cur == index + 1:
            list_date.append(target)
            list_question.append(question_num)
            list_correct.append(answer_num)

    # 年月別の問題/回答数
    member_correct = pd.DataFrame(
        {'01.year': list_date,
         '02.question': list_question,
         '03.correct': list_correct})
    
    member_correct.to_csv("member_correct" + member + ".csv")
    
    # 問題数/正解数/正解率の最大値の取得
    question_crr = 0
    answer_crr = 0
    for x, y in zip(list_question, list_correct):
        question_crr = question_crr + x
        answer_crr = answer_crr + y
    crr_ans_rate = (answer_crr / question_crr) * 100
   
    # jupiterを日本語対応していないので、適当にタイトルを設定
    if member == "るか":
        title = "Ruka's Question/Correct num"
    elif member == "みき":
        title = "Miki's Question/Correct num"
    elif member == "かな":
        title = "Kana's Question/Correct num"
    elif member == "みほ":
        title = "Miho's Question/Correct num"
    elif member == "ななせ":
        title = "Nanase's Question/Correct num"
    elif member == "せな":
        title = "Sena's Question/Correct num"
    else:
        title = "Rie's Question/Answer num"
        
    # X軸表示用に年月分連番を設定しておく
    serial_no = [index + 1 for index, i in enumerate(list_date)]
    
    # plot
    plt.figure(figsize=(20, 10), dpi=100, linewidth = 100)
    ax = plt.subplot()
    ax.bar(serial_no, list_question, color='#44A5CB', align="center", label="Question num") # 問題数
    ax.bar(serial_no, list_correct, color='#EDAD0B', align="center", label="Correct num") # 正解数
    plt.ylabel("Question/Correct num", fontsize=15)
    ax.legend(loc=2) # 凡例
    plt.title(title, fontsize=15)
    plt.yticks( np.arange(0, 20, 1) )
    plt.xticks(serial_no, list_date, rotation = 90)
    plt.savefig(member + '.png') # グラフのダウンロード
    plt.show()

    return question_crr,  answer_crr,  crr_ans_rate

メンバー7人で同じ処理を使うので定数化。

list_question_cum = []
list_answer_cum = []
list_crr_ans_rate = []

# るか
question_ruka, answer_ruka, rate_ruka = member_answer('るか')
list_question_cum.append(question_ruka)
list_answer_cum.append(answer_ruka)
list_crr_ans_rate.append(rate_ruka)
# みき
question_miki, answer_miki, rate_miki = member_answer('みき')
list_question_cum.append(question_miki)
list_answer_cum.append(answer_miki)
list_crr_ans_rate.append(rate_miki)
# かな
question_kana, answer_kana, rate_kana = member_answer('かな')
list_question_cum.append(question_kana)
list_answer_cum.append(answer_kana)
list_crr_ans_rate.append(rate_kana)
# みほ
question_miho, answer_miho, rate_miho = member_answer('みほ')
list_question_cum.append(question_miho)
list_answer_cum.append(answer_miho)
list_crr_ans_rate.append(rate_miho)
# ななせ
question_nanase, answer_nanase, rate_nanase = member_answer('ななせ')
list_question_cum.append(question_nanase)
list_answer_cum.append(answer_nanase)
list_crr_ans_rate.append(rate_nanase)
# せな
question_sena, answer_sena, rate_sena = member_answer('せな')
list_question_cum.append(question_sena)
list_answer_cum.append(answer_sena)
list_crr_ans_rate.append(rate_sena)
# りえ
question_rie, answer_rie, rate_rie = member_answer('りえ')
list_question_cum.append(question_rie)
list_answer_cum.append(answer_rie)
list_crr_ans_rate.append(rate_rie)

# メンバー別の問題数/正解数/正解率
crr_ans_rate = pd.DataFrame(
    {'01.member': ['るか', 'みき', 'かな', 'みほ', 'ななせ', 'せな', 'りえ'],
     '02.question': list_question_cum,
     '03.answer': list_answer_cum,
     '04.correct_rate': list_crr_ans_rate})

crr_ans_rate.to_csv("crr_ans_rate.csv")

appr_member = [1,2,3,4,5,6,7] # X軸の表示用

# plot
plt.figure(figsize=(20, 10), dpi=100, linewidth = 100)
ax = plt.subplot()
ax.bar(appr_member, list_question_cum, color='#44A5CB', align="center", label="Question num") # 問題数
ax.bar(appr_member, list_answer_cum, color='#EDAD0B', align="center", label="Correct num") # 正解数
ax.legend(loc=2) # 凡例
plt.yticks( np.arange(0, max(list_question_cum)+3, 10) )
plt.xticks(appr_member, ['ruka', 'miki', 'kana', 'miho', 'nanase', 'sena', 'rie'], rotation = 90, fontsize=15)
plt.ylabel("Question num", fontsize=15)

ax2 = ax.twinx()
ax2.plot(appr_member, list_crr_ans_rate, linewidth=5, marker='o', markersize=10, color='#C7243A') # 正解率
plt.ylabel("Correct answer rate", fontsize=15)
plt.savefig('Correct answer rate.png') # グラフのダウンロード
plt.show()

matplotlibでアイカツ!のCD売上枚数をグラフにする

もうひとつのブログ記事でアイカツのCD売上枚数から、コンテンツの隆盛について書こうと思っているんだが、ひとまず先にテック部分について書く。

実行時の結果及び分析結果については以下をご参照ください。
snofra.hatenablog.com

snofra.hatenablog.com


作ろうとしたきっかけは、アイカツスターズ!シングル売上枚数について調べたので、何か語るためにグラフにプロットしたろ!って思ったから。
tableauとかBIツールの選択肢もあったけど、pythonの勉強も兼ねてmatplotlibで表示させる。

仕事でも使っていない要素なので、もっとうまくいく方法があれば教えてほしいっす。

時系列データだと、とりま折れ線グラフにしとけばええやろ的な安易さで折れ線にしたんだけど、インパクトには欠けるかなーという印象。
手法をインプットしとかないと、こういう時にテンプレすら分からないということになって恥ずかしい思いするよなー。

恥ずかしい思いしてナンボなので、ソースも公開する。


分析軸

アイカツ!』から『アイカツスターズ!』までの流れを調査したいので、時系列データとしてCDの発売日を軸にする。

調査内容としては以下5点くらい。

  • アイカツ!シリーズのリリース間隔はどのくらいか?
  • ネットの検索数と比較して、「どこでバズって、ネットで盛り上がっているときCDは売れているのか?」
  • アイカツ!シリーズの根底はデータカードダスっつうゲームなので、「ゲームの新しいバージョンがリリースした場合のCDの売れ行きは変わるのか?」
  • ライバルであるプリパラシリーズとの対比。ぶっちゃけ「どこでプリパラに負けたのか」
  • プリパラシリーズとのシングル・アルバムの売り上げ差


CD売上については初週と累計が分かっているので、「初週の売り上げ結果が累計売上もどう影響するのか」ってのもあったけど、次回やる。
ここの観点は回帰分析ですな。統計素人なんでいろいろ勉強してから。


ソース

python 3.5
jupiter notebook上での実装


事前処理

import pandas as pd
import matplotlib.pyplot as plt
import statsmodels.api as sm
import matplotlib.dates as mdates
from dateutil.relativedelta import relativedelta
%pylab inline --no-import-all

# 定数
CLASS = '分類'
SERIES = 'シリーズ'
TITLE = 'タイトル'
SALES_DATE = '発売日'
SALES_CNT = '累計枚数'

SINGLE = 'SG'
ALBUM = 'AL'

AIKATSU_START_DATE = '2012-10-08'
AIKATSU_AKARI_GENE_START_DATE = '2014-10-02'
AIKATSU_STARS_START_DATE = '2016-04-02'
PREPARA_START_DATE = '2014-07-05'
IDOL_TIME_PREPARA_START_DATE = '2017-04-04'

AIKATSU_START_LABEL = 'aikatsu! Start'
AIKATSU_AKARI_GENE_START_LABEL = 'aikatsu!AkariGeneration Start'
AIKATSU_STARS_START_LABEL = 'aikatsuStars! Start'
PREPARA_START_LABEL = 'PriPara Start'
IDOL_TIME_PREPARA_START_LABEL = 'idolTimePrePara Start'

Y_AXIS_LABEL = 'CD sales count'


関数部

def x_axis_label(minday, maxday):
    """
    x軸のラベルをyyyy-mmで取得
    :param minday:ラベルの開始日
           maxday:ラベルの終了日
    :return:開始日から終了日までのyyyy-mm形式のリスト
    
    """
    
    # 開始終了が何年何ヶ月何日差があるかチェック
    delta = relativedelta(maxday, minday)
    # 何ヶ月差が発生しているか(表示の理由から+1ヶ月する)
    month_count = delta.years * 12 + delta.months + 1
    # 開始日から差が発生しているnヶ月分をaddする
    list_date =  [minday + relativedelta(months=i) for i in range(month_count)]

    return [str(date.strftime('%Y')) + '-' + str(date.strftime('%m')) for date in list_date] 

def release_interval(release_date, titles):
    """
    次のCDリリースすまでにどのくらいの間隔があいているか
    :param release_date:リリース日
                 titles:曲名
    """
    # 何ヶ月スパンで発売されているか
    base = None
    list_release = []
    for index, date in enumerate(release_date):
        # 1行目は比較対象がないので次の行へ
        if index == 0:
            base = date
            continue
        # 開始終了が何年何ヶ月何日差があるかチェック
        delta = relativedelta(date, base)
        # 何ヶ月差が発生しているか
        month_count = delta.years * 12 + delta.months
        # 月を開けずにリリースされているか
        if month_count == 0:
            # 同時発売かどうか
            if delta.days == 0:
                release = '前と同時発売'
            else:
                release = str(delta.days) + '日後'
        else:
            release = '約' + str(month_count) + 'ヶ月後'
        # リストにadd
        list_release.append(release)
        base = date

    # タイトルと合わせる
    for index, title in enumerate(titles):
        if index == 0:
            print('-' + ',' + title)
            continue
        print(list_release[index - 1] + ',' + title)

x_axis_label関数は、グラフにプロットしたときにX軸のラベルに使ってる。

単純に終了日-開始日の差をだして、それをnヶ月離れているかって算出した後に、開始日にn分、月を足しているだけ。

最後にyyyy-mm形式に直しているんだけど、ここループ2回やっているのでもう少しシンプルにならんのかなーとは思ってる。


これを実装するときに詰まったのが、重複値をどうするかっていう点。

最終的にyyyy-mm形式にするんだけど、CDが同月に発売されると当然値が重複する。
それを削除しなきゃいけないんだけど、setを使用すると重複は削除されるんだけどソートが崩れてしまう。

いったんsetにすることで重複要素が自動的に削除されます。

ただしこの方法だと要素の順番が変わることもあるようです。要素の順番を保ちたい場合には、普通にforループを回す形になります。 Python Tips:リストから重複した要素を削除したい - Life with Python

なので、まあ普通にループして中で加工している感じ。


release_interval関数はx_axis_label関数をちょろっと変えただけで基本は変わらない。csv形式になるように加工している。

結果をとりあえずprintしているだけなので、csvに吐き出すならoutputの実装がいるかな。


ファイルのロード抽出

# csvファイルのロード
df_aikatsu_cd = pd.read_csv('xxx/yyy/zz/cd_sales.csv', parse_dates=[2])
df_trend = pd.read_csv('xxx/yyy/zz/multiTimeline.csv', parse_dates=[0])
df_game_release = pd.read_csv('xxx/yyy/zz/game_release.csv', parse_dates=[2])
df_prepara_cd = pd.read_csv('xxx/yyy/zz/cd_sales_prepara.csv', parse_dates=[2])
df_trend_prepara = pd.read_csv('xxx/yyy/zz/multiTimeline_prepara.csv', parse_dates=[0])

# ■アイカツ!シリーズCD売上枚数
# シリーズ売上枚数(サントラ除く)
sales_day_all = df_aikatsu_cd[df_aikatsu_cd[CLASS] != 'ST']
x_sales_day_all = sales_day_all [SALES_DATE].fillna('')
y_sales_count_all = [int(i.replace(',', '')) for i in sales_day_all [SALES_CNT].fillna('0')]
# アイカツ!売上枚数
sales_day_aikatsu = sales_day_all[sales_day_all[SERIES] == 'アイカツ!']
x_sales_day_aikatsu = sales_day_aikatsu [SALES_DATE].fillna('')
y_sales_count_aikatsu = [int(aikatu_cd_num.replace(',', '')) for aikatu_cd_num in sales_day_aikatsu [SALES_CNT].fillna('0')]
title_aikatsu = sales_day_aikatsu[TITLE]
# アイカツスターズ!売上枚数
sales_day_stars = sales_day_all[sales_day_all[SERIES] == 'アイカツスターズ!']
x_sales_day_stars = sales_day_stars [SALES_DATE].fillna('')
y_sales_count_stars = [int(stars_cd_num.replace(',', '')) for stars_cd_num in sales_day_stars [SALES_CNT].fillna('0')]
title_stars = sales_day_stars[TITLE]
# アイカツ! フォトonステージ!!売上枚数
sales_day_photo = sales_day_all[sales_day_all[SERIES] == 'アイカツ! フォトonステージ!!']
x_sales_day_photo = sales_day_photo [SALES_DATE].fillna('')
y_sales_count_photo = [int(photo_cd_num.replace(',', '')) for photo_cd_num in sales_day_photo [SALES_CNT].fillna('0')]
# single売上枚数
sales_day_single = df_aikatsu_cd[df_aikatsu_cd[CLASS] == SINGLE]
x_sales_day_single = sales_day_single [SALES_DATE].fillna('')
y_sales_count_single = [int(i.replace(',', '')) for i in sales_day_single [SALES_CNT].fillna('0')]
# album売上枚数
sales_day_album = df_aikatsu_cd[df_aikatsu_cd[CLASS] == ALBUM]
x_sales_day_album = sales_day_album [SALES_DATE].fillna('')
y_sales_count_album = [int(i.replace(',', '')) for i in sales_day_album [SALES_CNT].fillna('0')]

# ■googleトレンド数(検索ワード:アイカツ)
x_trend_day = df_trend ["週"].fillna('')
y_trend_count = df_trend ["トレンド数"]

# ■DCD(ゲーム)のリリース日
# アイカツ!
x_game_release_day_aikatsu = df_game_release[df_game_release[SERIES] == 'アイカツ!'].リリース日
y_for_disp_aikatsu = [15000 for i in x_game_release_day_aikatsu]
# アイカツスターズ!
x_game_release_day_stars = df_game_release[df_game_release[SERIES] == 'アイカツスターズ!'].リリース日
y_for_disp_stars = [15000 for i in x_game_release_day_stars]

# ■プリパラシリーズCD売上枚数
# シリーズ売上枚数
x_sales_day_prepara = df_prepara_cd [SALES_DATE].fillna('')
y_sales_count_prepara = [int(i.replace(',', '')) for i in df_prepara_cd [SALES_CNT].fillna('0')]
# single売上枚数
sales_day_single_prepara = df_prepara_cd[df_prepara_cd[CLASS] == SINGLE]
x_sales_day_single_prepara = sales_day_single_prepara [SALES_DATE].fillna('')
y_sales_count_single_prepara = [int(i.replace(',', '')) for i in sales_day_single_prepara [SALES_CNT].fillna('0')]
# album売上枚数
sales_day_album_prepara = df_prepara_cd[df_prepara_cd[CLASS] == ALBUM]
x_sales_day_album_prepara = sales_day_album_prepara [SALES_DATE].fillna('')
y_sales_count_album_prepara = [int(i.replace(',', '')) for i in sales_day_album_prepara [SALES_CNT].fillna('0')]

# ■googleトレンド数(検索ワード:プリパラ)
x_trend_day_prepara = df_trend_prepara ["週"].fillna('')
y_trend_count_prepara = df_trend_prepara ["トレンド数"]

pandasのライブラリを使うとめちゃくそ楽なので、つかっている。

parse_datesで日付部分をtimestamp型に変えている。
これいれないと日付抽出のときに型で落ちるので、ロード時に型変換するようにしている。
ちなみにエンコードUTF-8じゃないとロード時に落ちる。取込元データのエンコードは事前にやっておかなきゃいけない。


また、ファイル上ブランクデータが含まれているので、fillna()で穴埋めする。
しないとNaNになるので、事前に処理しとく。


ゲームのリリース日の15000という数値は、Y軸がCDの売上枚数なので、それに合わせてまあ適当に設定。
とりあえず、リリース日だよってマーカーがグラフ上に表示できればいいので。


release_interval関数の呼び出し

# ■CDのリリース間隔のチェック
# アイカツ!
print('アイカツ!')
release_interval(x_sales_day_aikatsu, title_aikatsu)
# アイカツスターズ!
print('アイカツスターズ!')
release_interval(x_sales_day_stars, title_stars)

ここの実行結果はこんな感じ

アイカツ!
-,Signalize!/カレンダーガール/わか・ふうり・すなお・りすこ from STAR☆ANIS
約1ヶ月後,オーディションシングル① First Live!/わか・ふうり・すなお・りすこ・れみ from STAR☆ANIS
約1ヶ月後,オーディションシングル② Second Show!/わか・ふうり・すなお from STAR☆ANIS
28日後,オーディションシングル③ Third Action!/りすこ・すなお・え from STAR☆ANIS
約3ヶ月後,ダイヤモンドハッピー / ヒラリ/ヒトリ/キラリ/STAR☆ANIS
前と同時発売,FOURTH PARTY!/STAR☆ANIS
約3ヶ月後,KIRA☆Power/オリジナルスター☆彡/STAR☆ANIS
約1ヶ月後,COOL MODE/わか・ふうり・ゆな・すなお from STAR☆ANIS
約2ヶ月後,Sexy Style/STAR☆ANIS
約1ヶ月後,Calendar Girls/STAR☆ANIS
21日後,SHINING LINE/Precious/STAR☆ANIS
約1ヶ月後,POP ASSORT/STAR☆ANIS
約2ヶ月後,Cute Look/STAR☆ANIS
28日後,Du-Du-Wa DO IT!!/Good morning my dream/AIKATSU☆STARS!
約1ヶ月後,劇場版 アイカツ! ボーカル集 輝きのエチュード
約1ヶ月後,Shining Star
STAR☆ANIS
14日後,Beautiful Song/AIKATSU☆STARS!
約2ヶ月後,Lovely Party Collection/チュチュ・バレリーナ/AIKATSU☆STARS!
約1ヶ月後,Joyful Dance/AIKATSU☆STARS!
約2ヶ月後,Colorful Smile/AIKATSU☆STARS!
約2ヶ月後,START DASH SENSATION/AIKATSU☆STARS!
約2ヶ月後,Wonderful Tour/AIKATSU☆STARS!
約1ヶ月後,Lovely Party!!/AIKATSU☆STARS!
約15ヶ月後,アイカツ! COMPLETE CD-BOX

アイカツスターズ!
-,スタートライン!/episode Solo/AIKATSU☆STARS!
28日後,ハルコレ/AIKATSU☆STARS!
約1ヶ月後,ナツコレ/AIKATSU☆STARS!
21日後,劇場版アイカツスターズ! ボーカルシングル
約2ヶ月後,1,2,Sing for You!/So Beautiful Story/AIKATSU☆STARS!
21日後,アキコレ/AIKATSU☆STARS!
約2ヶ月後,フユコレ/AIKATSU☆STARS!
約2ヶ月後,STARDOM!/Bon Bon Voyage!/AIKATSU☆STARS!
約2ヶ月後,Fantastic Ocean/AIKATSU☆STARS!
約3ヶ月後,MUSIC of DREAM!!!/森のひかりのピルエット/AIKATSU☆STARS!!
約1ヶ月後,Endless Sky/AIKATSU☆STARS!


グラフのプロット

ブログ用に4枚縦に出力するようにしている。ついでにグラフも保存している。

# ■グラフのプロット
# X軸のラベルを取得
list_x_axis_label = x_axis_label(min(x_sales_day_all), max(x_sales_day_all))

# ■googleトレンド数とアイカツ!シリーズのCD売上枚数の比較
plt.figure(figsize=(20, 10), dpi=100, linewidth = 100) # 表示サイズ
ax = plt.subplot()
# アイカツ!シリーズのCD売上枚数をplot
ax.plot(x_sales_day_all, 
        y_sales_count_all, 
        linewidth=2, 
        marker='o', 
        color='#DA5019', 
        label='CD sales num')
# アニメの初回放送日
ax.plot(AIKATSU_START_DATE, 
        15000, 
        linewidth=2, 
        marker='x', 
        markersize=15, 
        markeredgewidth=2, 
        color='#BF1E56', 
        label=AIKATSU_START_LABEL)
ax.plot(AIKATSU_AKARI_GENE_START_DATE, 
        15000, 
        linewidth=2, 
        marker='x',
        markersize=15, 
        markeredgewidth=2, 
        color='#EDAD0B', 
        label=AIKATSU_AKARI_GENE_START_LABEL)
ax.plot(AIKATSU_STARS_START_DATE, 
        15000, linewidth=2, 
        marker='x', 
        markersize=15, 
        markeredgewidth=2, 
        color='#D8E212', 
        label=AIKATSU_STARS_START_LABEL)
plt.ylabel(Y_AXIS_LABEL)

# x軸の設定(表示yyyy-mmで1ヶ月単位で表示)
xfmt = mdates.DateFormatter("%y/%m")
xloc = mdates.DayLocator(bymonthday=[1])
ax.xaxis.set_major_locator(xloc)
ax.xaxis.set_major_formatter(xfmt)
ax.set_xticklabels(list_x_axis_label, rotation = 90)# 表示ラベルと傾き
ax.legend(loc=0) # 凡例

# googleトレンド数をplot
ax2 = ax.twinx()
ax2.plot(x_trend_day, 
         y_trend_count, 
         color='#3261AB', 
         label="aikatsu! trend num")
ax2.legend(loc=2) # 凡例
plt.ylabel("trend count")

ax.grid(True)
plt.savefig('CDsales_vs_trend.png') # グラフのダウンロード
plt.show()

# ■各アイカツ!シリーズタイトル別のCD売上枚数と、DCDのリリース日の比較
plt.figure(figsize=(20, 10), dpi=100, linewidth = 100)
ax = plt.subplot()
# 各アイカツ!シリーズタイトル別のCD売上枚数をplot
ax.plot(x_sales_day_aikatsu, 
        y_sales_count_aikatsu, 
        marker='o', 
        label='aikatsu!CD sales num')
ax.plot(x_sales_day_stars, 
        y_sales_count_stars, 
        marker='o', 
        label='aikatsuStars!CD sales num')
ax.plot(x_sales_day_photo, 
        y_sales_count_photo, 
        marker='o', 
        label='aikatsu!Photo_on_stage!!CD sales num')
# DCDのリリース日をplot
ax.plot(x_game_release_day_aikatsu, 
        y_for_disp_aikatsu, 
        linewidth=0, 
        marker='x',
        markersize=15, 
        markeredgewidth=1, 
        color='#23AC0E', 
        label='DCD aikatsu!Release')
ax.plot(x_game_release_day_stars, 
        y_for_disp_stars, 
        linewidth=0, 
        marker='x',
        markersize=15, 
        markeredgewidth=1, 
        color='#EDAD0B', 
        label='DCD aikatsuStars!Release')
plt.ylabel(Y_AXIS_LABEL)

# x軸の設定(表示yyyy-mmで1ヶ月単位で表示)
xfmt = mdates.DateFormatter("%y/%m")
xloc = mdates.DayLocator(bymonthday=[1])
ax.xaxis.set_major_locator(xloc)
ax.xaxis.set_major_formatter(xfmt)
ax.set_xticklabels(list_x_axis_label, rotation = 90)# 表示ラベルと傾き
ax.legend(loc=0) # 凡例

ax.grid(True)
plt.savefig('CDsales_vs_DCD.png') # グラフのダウンロード
plt.show()

# ■アイカツ!シリーズと、プリパラシリーズのCD売上枚数の比較
plt.figure(figsize=(20, 10), dpi=100, linewidth = 100) # 表示サイズ
ax = plt.subplot()
# アイカツ!シリーズのCD売上枚数をplot
ax.plot(x_sales_day_all, 
        y_sales_count_all, 
        linewidth=2, 
        marker='o', 
        color='#DA5019', 
        label='aikatsu!CD sales num')
# プリパラシリーズのCD売上枚数をplot
ax.plot(x_sales_day_prepara, 
        y_sales_count_prepara, 
        linewidth=2, 
        marker='o', 
        color='#009F8C', 
        label='PriParaCD sales num')
# アニメの初回放送日
ax.plot(AIKATSU_START_DATE, 
        20000, 
        linewidth=2, 
        marker='x', 
        markersize=15, 
        markeredgewidth=2, 
        color='#BF1E56', 
        label=AIKATSU_START_LABEL)
ax.plot(AIKATSU_AKARI_GENE_START_DATE, 
        20000, 
        linewidth=2, 
        marker='x',
        markersize=15, 
        markeredgewidth=2, 
        color='#EDAD0B', 
        label=AIKATSU_AKARI_GENE_START_LABEL)
ax.plot(AIKATSU_STARS_START_DATE, 
        20000, linewidth=2, 
        marker='x', 
        markersize=15, 
        markeredgewidth=2, 
        color='#D8E212', 
        label=AIKATSU_STARS_START_LABEL)
ax.plot(PREPARA_START_DATE, 
        18000, 
        linewidth=2, 
        marker='o', 
        markersize=15, 
        color='#23AC0E', 
        label=PREPARA_START_LABEL)
ax.plot(IDOL_TIME_PREPARA_START_DATE, 
        18000, 
        linewidth=2, 
        marker='o', 
        markersize=15, 
        color='#A4C520', 
        label=IDOL_TIME_PREPARA_START_LABEL)
plt.ylabel(Y_AXIS_LABEL)

# x軸の設定(表示yyyy-mmで1ヶ月単位で表示)
xfmt = mdates.DateFormatter("%y/%m")
xloc = mdates.DayLocator(bymonthday=[1])
ax.xaxis.set_major_locator(xloc)
ax.xaxis.set_major_formatter(xfmt)
ax.set_xticklabels(list_x_axis_label, rotation = 90)# 表示ラベルと傾き
ax.legend(loc=0) # 凡例

# googleトレンド数をplot
ax2 = ax.twinx()
ax2.plot(x_trend_day, 
         y_trend_count, 
         color='#3261AB', 
         label="aikatsu! trend num")
ax2.plot(x_trend_day_prepara, 
         y_trend_count_prepara, 
         color='#C0D860', 
         label="prepara trend num")
ax2.legend(loc=2) # 凡例
plt.ylabel("trend count")

ax.grid(True)
plt.savefig('aikatsu_vs_prepara_all.png') # グラフのダウンロード
plt.show()

# ■アイカツ!シリーズと、プリパラシリーズのCD売上枚数の比較(シングル)
plt.figure(figsize=(20, 10), dpi=100, linewidth = 100) # 表示サイズ
ax = plt.subplot()
# アイカツ!シリーズのCD売上枚数をplot
ax.plot(x_sales_day_single, 
        y_sales_count_single, 
        linewidth=2, 
        marker='o', 
        color='#DA5019', 
        label='aikatsu! series Single')
# プリパラシリーズのCD売上枚数をplot
ax.plot(x_sales_day_single_prepara, 
        y_sales_count_single_prepara, 
        linewidth=2, 
        marker='o', 
        color='#009250', 
        label='Prepara series Single')
# アニメの初回放送日
ax.plot(AIKATSU_AKARI_GENE_START_DATE, 
        14000, 
        linewidth=2, 
        marker='x',
        markersize=15, 
        markeredgewidth=2, 
        color='#EDAD0B', 
        label=AIKATSU_AKARI_GENE_START_LABEL)
ax.plot(AIKATSU_STARS_START_DATE, 
        14000, linewidth=2, 
        marker='x', 
        markersize=15, 
        markeredgewidth=2, 
        color='#D8E212', 
        label=AIKATSU_STARS_START_LABEL)
ax.plot(PREPARA_START_DATE, 
        12000, 
        linewidth=2, 
        marker='o', 
        markersize=15, 
        color='#23AC0E', 
        label=PREPARA_START_LABEL)
ax.plot(IDOL_TIME_PREPARA_START_DATE, 
        12000, 
        linewidth=2, 
        marker='o', 
        markersize=15, 
        color='#A4C520', 
        label=IDOL_TIME_PREPARA_START_LABEL)
plt.ylabel(Y_AXIS_LABEL)

# x軸の設定(表示yyyy-mmで1ヶ月単位で表示)
xfmt = mdates.DateFormatter("%y/%m")
xloc = mdates.DayLocator(bymonthday=[1])
ax.xaxis.set_major_locator(xloc)
ax.xaxis.set_major_formatter(xfmt)
ax.set_xticklabels(list_x_axis_label, rotation = 90)# 表示ラベルと傾き
ax.legend(loc=0) # 凡例

ax.grid(True)
plt.savefig('aikatsu_vs_prepara_single.png') # グラフのダウンロード
plt.show()

# ■アイカツ!シリーズと、プリパラシリーズのCD売上枚数の比較(アルバム)
# startが変わるので、X軸のラベルを変更(開始日:アイカツ/終了日:プリパラ)
list_x_axis_label = x_axis_label(min(x_sales_day_album), max(x_sales_day_album_prepara))

plt.figure(figsize=(20, 10), dpi=100, linewidth = 100) # 表示サイズ
ax = plt.subplot()
# アイカツ!シリーズのCD売上枚数をplot
ax.plot(x_sales_day_album, 
        y_sales_count_album, 
        linewidth=2, 
        marker='o', 
        color='#DA5019', 
        label='aikatsu! series Album')
# プリパラシリーズのCD売上枚数をplot
ax.plot(x_sales_day_album_prepara, 
        y_sales_count_album_prepara, 
        linewidth=2, 
        marker='o', 
        color='#009250', 
        label='Prepara series Album')
# アニメの初回放送日
ax.plot(AIKATSU_AKARI_GENE_START_DATE, 
        14000, 
        linewidth=2, 
        marker='x',
        markersize=15, 
        markeredgewidth=2, 
        color='#EDAD0B', 
        label=AIKATSU_AKARI_GENE_START_LABEL)
ax.plot(AIKATSU_STARS_START_DATE, 
        14000, linewidth=2, 
        marker='x', 
        markersize=15, 
        markeredgewidth=2, 
        color='#D8E212', 
        label=AIKATSU_STARS_START_LABEL)
ax.plot(PREPARA_START_DATE, 
        12000, 
        linewidth=2, 
        marker='o', 
        markersize=15, 
        color='#23AC0E', 
        label=PREPARA_START_LABEL)
ax.plot(IDOL_TIME_PREPARA_START_DATE, 
        12000, 
        linewidth=2, 
        marker='o', 
        markersize=15, 
        color='#A4C520', 
        label=IDOL_TIME_PREPARA_START_LABEL)
plt.ylabel(Y_AXIS_LABEL)

# x軸の設定(表示yyyy-mmで1ヶ月単位で表示)
xfmt = mdates.DateFormatter("%y/%m")
xloc = mdates.DayLocator(bymonthday=[1])
ax.xaxis.set_major_locator(xloc)
ax.xaxis.set_major_formatter(xfmt)
ax.set_xticklabels(list_x_axis_label, rotation = 90)# 表示ラベルと傾き
ax.legend(loc=0) # 凡例

ax.grid(True)
plt.savefig('aikatsu_vs_prepara_album.png') # グラフのダウンロード
plt.show()

ここで詰まったのがX軸をどうするかという点。
今は1ヶ月単位で並べているけど、実際のデータはきれいに1ヶ月単位で並んでいるわけじゃない。
ぐちゃぐちゃなのでそこをどうそろえるかってのが難しかった。

1ヶ月単位で設定できないってのでまずつまった。
元データが1ヶ月単位で並んでいないので、グラフのX軸が開始日と終了日くらいしか出ず。

xfmt = mdates.DateFormatter("%y/%m")
xloc = mdates.DayLocator(bymonthday=[1])
ax.xaxis.set_major_locator(xloc)
ax.xaxis.set_major_formatter(xfmt)

ここで、表示形式をyyyy-mmにして、mdates.DayLocator(bymonthday=[1])で1ヶ月単位で並べるってやってなんとか形にはなった。


次に引っかかったのが、2軸にするためにax = plt.subplot()を使用するんだけど、その場合、ラベルの傾きが設定できない。

ax.set_xticklabelsでやるんだってことは分かったんだけど、普通にplotしている表示ラベルを入れるとラベル数が合わなくてって当たり前。

それを何とかするためにx_axis_label関数を作って1ヶ月単位で表示させるようにした感じ。


一つできればあとは増幅させるだけなので、まあどうってことはない。
今回はファイルのIOがかなりシンプルだったのでそこで躓くことが少なかったってのが良かった。
つーかOUTについて全然考えてないだけだったけど。

グラフのプロット

こんな感じになる。 f:id:snofra:20171110141822p:plain

f:id:snofra:20171110141846p:plain

立ち上げる

はてなブログアイカツ!とか遊戯王とか書いていたりするんだけど、 もうひとつのサイトとは別の観点、というか仕事関連について書くものもあっていいのかなと思って立ててみた。

新しく立てたのは、もうひとつのサイトとは観点違うだろうし、技術について書かれても興味ない層だっているだろうなという理由から。 イメージとしては、もうひとつで分析結果と雑感を書いて、こっちで技術について書いていければいいかなと。

とはいえ、もうひとつのサイトは更新滞っているので、そちら側によせても何のインパクトもないかも。 駄目そうならまた考える。

Qiitaアカウントも持っているんだが、あっちはポエム的駄文珍文は載せるのはNGだったりするし、 だからといって両方やるとなると絶対に長続きしないので、1つに集約する。

技術的なところも間違っていることもあるだろうが、今理解したことを素直に書くことにする。