def proc_trend_x(db_list, fc_dict): """ サマリーX (↑支持, ↑不支持 グラフ) """ args = cfg['args'] fig, ax = plt.subplots(figsize=(8, 5)) fig.subplots_adjust(left=0.16, right=0.8, bottom=0.15) # 色指定 cy = 'darkorange' cn = 'skyblue' # 支持率 tim, avg, sdv, num = tven_buf['APP_RATE'].by_column() dda = [dt_fm_sn(a) for a in tim] err = sdv/np.sqrt(num) ax.fill_between(dda, avg-err, avg+err, color=cy, alpha=0.3) ax.plot(dda, avg, color=cy, label='支持(平均)', alpha=1) # 不支持率 tim, avg, sdv, num = tven_buf['NAP_RATE'].by_column() dda = [dt_fm_sn(a) for a in tim] err = sdv/np.sqrt(num) ax.fill_between(dda, avg-err, avg+err, color=cn, alpha=0.3) ax.plot(dda, avg, color=cn, label='不支持(平均)', alpha=1) # 支持率の個別データ (感度補正後) for db in db_list: yy = [a/fc_dict['APP_RATE'][db.label](b) for a,b in zip(db.db['APP_RATE'], db.db['T'])] dd = [dt_fm_sn(a) for a in db.db['T']] ax.plot(dd, yy, db.marker, ms=db.size*0.5, color='orange', alpha=1, label=db.label) # X 軸 ax.xaxis_date() ax.set_xlim(dt_fm_sn(tim[0]), dt_fm_sn(30 + tim[-1])) # ax.set_xlim(datetime(2019,2,1), datetime(2020,4,1)) # 日付埋め込み ★ set_date_tick(ax, (1, 7), '%Y/%m', 30) # Y 軸 ax.set_yticks(range(0, 100, 5)) ax.set_yticks(range(0, 100, 1), minor=True) ax.set_ylim([20, 65]) # タイトル/グリッド ax.set_title('報道 10社の平均') ax.grid(which='both') ax.grid(which='minor', alpha=0.1) # 凡例 ax.legend(loc='upper left', bbox_to_anchor=(1.0, 1.0)) # 注釈 if args.k_days > 0: fig.text(0.19, 0.16, "平均は指数移動平均(時定数 %d 日)"%args.k_days, fontsize=8) #, bbox=bbox) else: fig.text(0.19, 0.16, "平均は日曜前後数日", fontsize=8) #, bbox=bbox) # 図の出力 if args.gout: fig.savefig(os.path.join(args.gout_folder, 'Fig%d_%s.png' % (args.gout_ndx + 1, cfg['gout_date'])))
def proc_yn(pp2, pp3, ppj): """ 支持と不支持の合計のトレンド """ args = cfg['args'] fig, ax = plt.subplots() fig.subplots_adjust(right=0.8, bottom=0.15) ax.set_title('内閣支持率と不支持率の合計', fontsize=15) # ax.set_xlim([datetime(2016,4,1), datetime(2018,10,1)]) for db_list in [ppj, pp2, pp3]: for db in db_list: x = [dt_fm_sn(a) for a in db.db['T']] y = np.array(db.db['APP_RATE']) + np.array(db.db['NAP_RATE']) ax.plot(x, y, db.marker + '-', ms=db.size * 0.5, label=db.label) ax.legend(loc='upper left', bbox_to_anchor=(1.0, 1.0)) ax.grid(True) set_date_tick(ax, (1, 7), '%Y/%m', 30) ax.set_ylabel('支持率 + 不支持率 [%]', fontsize=14) if args.gout: fig.savefig( os.path.join( args.gout_folder, 'Fig%d_%s.png' % (args.gout_ndx + 4, cfg['gout_date'])))
def proc_hilo(): """ HI - LO のトレンド """ fig, axes = plt.subplots(2, 1) fig.subplots_adjust(left=0.16, right=0.86, bottom=0.15) for (ndx, yn) in enumerate(['APP_RATE', 'NAP_RATE']): tim2, avg2, _err, _num = tven_buf['H'][yn].by_column() tim3, avg3, _err, _num = tven_buf['L'][yn].by_column() f2 = interp(tim2, avg2) f3 = interp(tim3, avg3) tmin = max(tim2[0], tim3[0]) tmax = min(tim2[-1], tim3[-1]) t_node = np.arange(tmin, tmax, 1) d_node = [dt_fm_sn(a) for a in t_node] y_node = [f2(t) - f3(t) for t in t_node] axes[ndx].plot(d_node, y_node) axes[ndx].grid(True) axes[ndx].set_ylim(-4, 12) if ndx == 0: set_date_tick(axes[ndx], (1, 4, 7, 10), '%m', 0) else: set_date_tick(axes[ndx], (1, 7), '%Y/%m', 30)
def proc_fc(fc_dict, pp2, pp3, ppj): """ 感度係数 H, L 別 """ fig, axes = plt.subplots(4, 1, figsize=(6, 8)) fig.subplots_adjust(left=0.1, bottom=0.1, right=0.85, top=0.95, hspace=0.3) for j, (yn, db_list) in enumerate([('APP_RATE', pp2), ('NAP_RATE', pp2), ('APP_RATE', pp3), ('NAP_RATE', pp3)]): ax = axes[j] for db in db_list: fc = fc_dict[yn][db.label] t = db.db['T'] d = [dt_fm_sn(a) for a in t] f = [fc(a) for a in t] ax.plot(d, f, label=db.label) ax.set_ylim(0.9, 1.2) ax.grid(True) if (j % 2) == 0: ax.legend(loc='upper left', bbox_to_anchor=(1.0, 1.0)) else: pass if j == 3: set_date_tick(ax, (1, 7), '%Y/%m', 30) else: set_date_tick(ax, (1, 4, 7, 10), '%m', 0)
def proc_trend(): """ サマリー (↑支持, ↓不支持 グラフ) """ args = cfg['args'] fig, ax1 = plt.subplots(figsize=(8, 5)) ax2 = ax1.twinx() fig.subplots_adjust(left=0.16, right=0.8, bottom=0.15) # 色指定 cy = 'darkorange' cy2 = 'orangered' cn = 'skyblue' cn2 = 'darkcyan' # ---< 支持率 >--- tta, ppa_buf, sdv_buf, num_buf = tven_buf['APP_RATE'].by_column() dda = [dt_fm_sn(a) for a in tta] ax = ax1 err = sdv_buf/np.sqrt(num_buf) ax.fill_between(dda, ppa_buf-err, ppa_buf+err, color=cy, linestyle='dashed', alpha=0.3) ax.plot(dda, ppa_buf, color=cy, label='報道10社平均', alpha=1) # Y 軸 ax.set_ylim([0, 100]) ax.tick_params(axis='y', colors=cy2) ax.set_yticks(range(0, 51, 10)) ax.text(datetime(2016, 9, 1), 30, '支持する', color=cy2, fontsize=20) ax.set_ylabel('内閣を支持する [%]', color=cy2, fontsize=14) ax.yaxis.set_label_coords(-0.08, 0.3) # ---< 不支持率 >--- tta, ppa_buf, sdv_buf, num_buf = tven_buf['NAP_RATE'].by_column() dda = [dt_fm_sn(a) for a in tta] ax = ax2 err = sdv_buf/np.sqrt(num_buf) ax.fill_between(dda, ppa_buf-err, ppa_buf+err, color=cn, linestyle='dashed', alpha=0.3) ax.plot(dda, ppa_buf, color=cn, label='報道10社平均', alpha=1) # Y2 軸 ax.set_ylim([100, 0]) ax.tick_params(axis='y', colors=cn2) ax.set_yticks(range(0, 51, 10)) ax.text(datetime(2016, 8, 1), 20, '支持しない', color=cn2, fontsize=20) ax.set_ylabel('内閣を支持しない [%]', color=cn2, fontsize=14) ax.yaxis.set_label_coords(1.08, 0.7) # X 軸 ax = ax1 ax.xaxis_date() ax.set_xlim(dt_fm_sn(tta[0]), dt_fm_sn(30 + tta[-1])) set_date_tick(ax, (1, 7), '%Y/%m', 30) # タイトル/グリッド ax1.set_title('報道 10社の平均') ax1.grid(which='both') ax2.grid(which='both') ax1.grid(which='minor', alpha=0.1) ax2.grid(which='minor', alpha=0.1) # 注釈 # bbox=dict(facecolor='white', edgecolor='none', alpha=0.7) if args.k_days > 0: fig.text(0.19, 0.16, "平均は指数移動平均(時定数 %d 日)"%args.k_days, fontsize=8) #, bbox=bbox) else: fig.text(0.19, 0.16, "平均は日曜前後数日", fontsize=8) #, bbox=bbox) if args.gout: fig.savefig(os.path.join(args.gout_folder, 'Fig%d_%s.png' % (args.gout_ndx + 0, cfg['gout_date'])))
def proc_raw_cal_sdv(fc_dict, axes, k_app_nap, db_list): """ 発表値、補正値、補正値の残差のグラフ """ args = cfg['args'] if args.rainbow: cm = plt.get_cmap('rainbow') def _c(j): return cm(1.0 - j/len(db_list)) else: cm = plt.get_cmap('tab10') def _c(j): return cm(j) tim, val, err, num = tven_buf[k_app_nap].by_column() ax =axes[0] ax.set_ylim(20, 70) ax.set_ylabel('調査結果(発表値) %') for (j, db) in enumerate(db_list): dd = [dt_fm_sn(a) for a in db.db['T']] if db.label != 'SSRC': ax.plot(dd, db.db[k_app_nap], db.marker+'-', ms=db.size*0.5, color=_c(j), label=db.label, alpha=0.5) else: ddvv = [a for a in zip(dd, db.db[k_app_nap]) if a[0] > datetime(2020, 4, 1)] dd, vv = [a for a in zip(*ddvv)] ax.plot(dd, vv, db.marker+'-', ms=db.size*0.5, color=_c(j), label=db.label, alpha=0.5) set_date_tick(ax, (1,4,7,10), '%m', 0) ax.grid(True) ax.legend(loc='upper left', bbox_to_anchor=(1.0, 1.0)) ax =axes[1] ax.set_ylim(20, 70) ax.set_ylabel('感度補正後(曲線は平均値) %') ax.set_ylabel('感度補正後 %') for (j, db) in enumerate(db_list): dd = [dt_fm_sn(a) for a in db.db['T']] vv = [a/fc_dict[k_app_nap][db.label](b) for a, b in zip(db.db[k_app_nap], db.db['T'])] if db.label != 'SSRC': ax.plot(dd, vv, db.marker, ms=db.size*0.5, color=_c(j), label=db.label, alpha=0.5) else: ddvv = [a for a in zip(dd, vv) if a[0] > datetime(2020, 4, 1)] dd, vv = [a for a in zip(*ddvv)] ax.plot(dd, vv, db.marker+'-', ms=db.size*0.5, color=_c(j), label=db.label, alpha=0.5) dd = [dt_fm_sn(a) for a in tim] ee = err/np.sqrt(num) ax.fill_between(dd, val-ee, val+ee, color='blue', alpha=0.1) ax.plot(dd, val,'-', color='blue', lw=1, alpha=1) set_date_tick(ax, (1,4,7,10), '%m', 0) ax.grid(True) ax =axes[2] ax.set_ylim(-8, 8) ax.set_ylabel('感度補正後の残差 %') for (j, db) in enumerate(db_list): vv = [a/fc_dict[k_app_nap][db.label](b) for a, b in zip(db.db[k_app_nap], db.db['T'])] dv, sd = deviation(db.db['T'], vv, interp(tim, val)) dd = [dt_fm_sn(a) for a in db.db['T']] ax.plot(dd, dv, '-', color=_c(j), label=db.label, alpha=0.5) set_date_tick(ax, (1, 7), '%Y/%m', 30) ax.grid(True) ax.legend(loc='upper left', bbox_to_anchor=(1.0, 1.0))
def proc_factor(db_list, k_app_nap, k_title, fc_dict, gn_rel): """ 報道10 社の支持率/不支持率の調査感度の時系列比較 Parameters ---------- db_list, list of DB() k_app_nap, string : 分析データキー ('APP_RATE' or 'NAP_RATE') k_title, string : グラフタイトル fc_dict, - : 他の分析で使っている感度係数補間関数の辞書 gn_rel, : 出力図番の相対 """ args = cfg['args'] # 図の準備 nr = 6 fig, axes = plt.subplots(nr, 2, figsize=(10, 7)) fig.text(0.10, 0.97, k_title, fontsize=16) fig.text(0.60, 0.97, '(オレンジ:3ヵ月移動平均 ブルー:6ヵ月移動平均)', fontsize=12) fig.subplots_adjust(left=0.1, bottom=0.1, right=0.95, top=0.95, wspace=0.25, hspace=0.25) # 分析期間 t0 = sn_fm_dt(_d(cfg['args'].db_begin)) tf = t_max(db_list) # 移動平均の窓幅をいくつか選んで感度のトレンドを描画(調査会社毎) for ndx, m in enumerate([3, 6]): # window size (m-month) tt = np.arange(t0 + 6*30, tf, 7) ff = calc_fact(db_list, k_app_nap, tt, m*30) dd = [dt_fm_sn(a) for a in tt] for j, (f, db) in enumerate(zip(ff, db_list)): c, r = divmod(j, nr) if ndx == 0: axes[r,c].plot(dd, f, color='orange', lw=2, alpha=0.8) else: axes[r,c].plot(dd, f, color='blue') fc = [fc_dict[k_app_nap][db.label](t) for t in tt] axes[r,c].plot(dd, fc, '-', color='green', alpha=0.5) axes[r,c].set_xlim(dd[0], dd[-1]+timedelta(days=30)) # タイトルや軸の設定 db_list_ax = db_list + ['']*(nr*2 - len(db_list)) print('db_list_ax', len(db_list_ax)) for j, db in enumerate(db_list_ax): c, r = divmod(j, nr) axes[r,c].set_xlim(dd[0], dd[-1]+timedelta(days=30)) if db != '': axes[r, c].set_ylabel(db.label) axes[r, c].set_ylim(0.8, 1.3) axes[r, c].grid(which='both') axes[r, c].grid(which='minor', alpha=0.1) if r == (nr - 1): print(r, c) set_date_tick(axes[r,c], (1, 7), '%Y/%m', 30) else: set_date_tick(axes[r,c], (1, 7), '%m', 0) # 調査が実施された日付をプロット if db != '': dd_org = [dt_fm_sn(a) for a in db.db['T']] oo_org = np.ones_like(dd_org) axes[r,c].plot(dd_org, oo_org, 'o', ms=4, alpha=0.2) if args.gout: fig.savefig(os.path.join(args.gout_folder, 'Fig%d_%s.png' % (args.gout_ndx + gn_rel, cfg['gout_date'])))
def proc_raw_cal_sdv(fc_dict, axes, yn, db_list, tim, avg): ax = axes[0] ax.set_ylim(20, 70) ax.set_ylabel('調査結果(発表値) %') for db in db_list: dd = [dt_fm_sn(a) for a in db.db['T']] if db.label != 'SSRC': ax.plot(dd, db.db[yn], db.marker, ms=db.size * 0.5, label=db.label, alpha=0.5) else: ddvv = [ a for a in zip(dd, db.db[yn]) if a[0] > datetime(2020, 4, 1) ] dd, vv = [a for a in zip(*ddvv)] ax.plot(dd, vv, db.marker + '-', ms=db.size * 0.5, label=db.label, alpha=0.5) set_date_tick(ax, (1, 4, 7, 10), '%m', 0) ax.grid(True) ax.legend(loc='upper left', bbox_to_anchor=(1.0, 1.0)) ax = axes[1] ax.set_ylim(20, 70) ax.set_ylabel('感度補正後(線は平均値) %') for db in db_list: dd = [dt_fm_sn(a) for a in db.db['T']] ff = [fc_dict[yn][db.label](t) for t in db.db['T']] vv = [a / b for a, b in zip(db.db[yn], ff)] if db.label != 'SSRC': ax.plot(dd, vv, db.marker, ms=db.size * 0.5, label=db.label, alpha=0.5) else: ddvv = [a for a in zip(dd, vv) if a[0] > datetime(2020, 4, 1)] dd, vv = [a for a in zip(*ddvv)] ax.plot(dd, vv, db.marker + '-', ms=db.size * 0.5, label=db.label, alpha=0.5) dd = [dt_fm_sn(a) for a in tim] ax.plot(dd, avg, '-', color='royalblue', lw=2) #, alpha=0.1) set_date_tick(ax, (1, 4, 7, 10), '%m', 0) ax.grid(True) ax.legend(loc='upper left', bbox_to_anchor=(1.0, 1.0)) ax = axes[2] ax.set_ylim(-8, 8) ax.set_ylabel('感度補正後の残差 %') for db in db_list: vv = [ a / fc_dict[yn][db.label](b) for (a, b) in zip(db.db[yn], db.db['T']) ] ss, sd = deviation(db.db['T'], vv, interp(tim, avg)) dd = [dt_fm_sn(a) for a in db.db['T']] ax.plot(dd, ss, '-', label=db.label, alpha=0.5) set_date_tick(ax, (1, 7), '%Y/%m', 30) ax.grid(True) ax.legend(loc='upper left', bbox_to_anchor=(1.0, 1.0))
def proc_trend(): """ サマリー (↑支持, ↓不支持) + 円グラフ """ args = cfg['args'] flg_jnn = False tt2, app_hi, err_, num_ = tven_buf['H']['APP_RATE'].by_column() tt2, nap_hi, err_, num_ = tven_buf['H']['NAP_RATE'].by_column() tt3, app_lo, err_, num_ = tven_buf['L']['APP_RATE'].by_column() tt3, nap_lo, err_, num_ = tven_buf['L']['NAP_RATE'].by_column() ttj, app_j, err_, num_ = tven_buf['J']['APP_RATE'].by_column() ttj, nap_j, err_, num_ = tven_buf['J']['NAP_RATE'].by_column() dd2 = [dt_fm_sn(a) for a in tt2] dd3 = [dt_fm_sn(a) for a in tt3] ddj = [dt_fm_sn(a) for a in ttj] fig, ax1 = plt.subplots() fig.subplots_adjust(left=0.16, right=0.86, bottom=0.15) # 色指定 cy = 'darkorange' cy2 = 'orangered' cn = 'skyblue' cn2 = 'darkcyan' ax = ax1 ax.fill_between(dd3, 0, app_lo, color=cy, label='グループL', alpha=0.5) ax.plot(dd3, app_lo, lw=1, color=cy, alpha=1.0) if flg_jnn: ax.plot(ddj, app_j, '--', lw=1, color=cy, label='JNN', alpha=1.0) ax.plot(dd2, app_hi, '-', lw=1, color='tomato', label='グループH') # Y 凡例 ax.legend(loc='upper left', bbox_to_anchor=(0.65, 0.25)) # Y 軸 ax.set_ylim([0, 100]) ax.tick_params(axis='y', colors=cy2) ax.set_yticks(range(0, 51, 10)) ax.text(datetime(2016, 9, 1), 22, '支持する', color=cy2, fontsize=20) ax.set_ylabel('内閣を支持する [%]', color=cy2, fontsize=14) ax.yaxis.set_label_coords(-0.08, 0.3) # ---< 不支持率 >--- ax2 = ax1.twinx() ax = ax2 ax.fill_between(dd3, 0, nap_lo, color=cn, label='グループL', alpha=0.5) ax.plot(dd3, nap_lo, lw=1, color=cn, alpha=1.0) if flg_jnn: ax.plot(ddj, nap_j, '--', lw=1, color=cn, label='JNN', alpha=1.0) ax.plot(dd2, nap_hi, '-', lw=1, color='royalblue', label='グループH') # Y2 凡例 (順序を逆転) hh, ll = ax.get_legend_handles_labels() hh, ll = reverse_legend(hh, ll) ax.legend(hh, ll, loc='upper left', bbox_to_anchor=(0.65, 0.9)) # Y2 軸 ax.set_ylim([100, 0]) ax.tick_params(axis='y', colors=cn2) ax.set_yticks(range(0, 51, 10)) ax.text(datetime(2016, 8, 1), 18, '支持しない', color=cn2, fontsize=20) ax.set_ylabel('内閣を支持しない [%]', color=cn2, fontsize=14) ax.yaxis.set_label_coords(1.08, 0.7) # X 軸 ax.xaxis_date() ax.set_xlim(dt_fm_sn(min(tt2[0], tt3[0])), dt_fm_sn(30 + max(tt2[-1], tt3[-1]))) set_date_tick(ax1, (1, 7), '%Y/%m', 30) # タイトル/グリッド ax1.grid(which='both') ax2.grid(which='both') ax1.grid(which='minor', alpha=0.1) ax2.grid(which='minor', alpha=0.1) # 注釈 # bbox=dict(facecolor='white', edgecolor='none', alpha=0.7) fig.text(0.19, 0.23, "グループ H: 読売/日経/共同 の平均", fontsize=8) #, bbox=bbox) fig.text(0.19, 0.19, "グループ L: 毎日/朝日/時事/ANN/NHK の平均", fontsize=8) #, bbox=bbox) if args.k_days > 0: fig.text(0.19, 0.16, "平均は指数移動平均(時定数 %d 日)" % args.k_days, fontsize=8) #, bbox=bbox) else: fig.text(0.19, 0.16, "平均は日曜前後数日", fontsize=8) #, bbox=bbox) if args.gout: fig.savefig( os.path.join( args.gout_folder, 'Fig%d_%s.png' % (args.gout_ndx + 0, cfg['gout_date']))) # ---< 円グラフ >--- fig = plt.figure(figsize=(4, 4)) fig.subplots_adjust(left=0, bottom=0, right=1, top=1) ax = fig.add_subplot(1, 1, 1) n3 = nap_lo[-1] n2 = nap_hi[-1] y3 = app_lo[-1] y2 = app_hi[-1] if n2 < n3: n2 = n3 if y2 < y3: y2 = y3 dd = [n3, n2 - n3, 100 - n2 - y2, y2 - y3, y3] # cc = [cn, 'royalblue', '0.3', 'tomato', cy] # cc = [cn, 'deepskyblue', '0.3', 'orange', cy] cc = [cn, 'royalblue', '0.7', 'tomato', cy] ll = ['支持しない', 'やや', '他', 'やや', '支持する'] ll = ['', 'やや', '他', 'やや', ''] patches, texts = ax.pie(dd, labels=ll, counterclock=False, startangle=90, colors=cc, labeldistance=0.7, textprops={'color': 'white'}, radius=1.23) ax.text(0.6, 0.22, '支持しない', fontsize=20, color='white', horizontalalignment='center') ax.text(-0.6, 0.22, '支持する', fontsize=20, color='white', horizontalalignment='center') for t in texts: t.set_horizontalalignment('center') t.set_size(14) if args.gout: fig.savefig( os.path.join(args.gout_folder, 'Fig%d_%s.png' % (args.gout + 1, cfg['gout_date']))) print('L (3)', y3, n3) print('H (2)', y2, n2)