【matplotlib】(縦棒+折れ線グラフ)Excelで作るようなデザインのグラフを作りたい【python】

pythonでグラフを作るとき、自分好みのデザインにするのにいつも苦労する。

seabornもおしゃれでいいのだけど、みんなが使いすぎていてpython感が出すぎるので、Excelで作ったみたいなデザインにするにはどうするかを頑張ってみた。

今後自分のメモ用にいくつかのパターンを作ってみたいと思う。

 

今回はこの縦棒グラフと折れ線グラフを作るために色々と条件を調べたのでそのコードをまとめておく。非常に長いコードになってしまったが、このくらい頑張らないと自分好みのグラフにはならないのが難しい所で、Excelの便利さがよくわかる。

import numpy as np
import matplotlib.pyplot as plt
import japanize_matplotlib

#データ
sales = np.array([153, 202, 355, 402])#棒グラフのデータ
profit = np.array([53, 78, 100, 158])#点のデータ
labels = ['Q1', 'Q2', 'Q3', 'Q4']#x軸のラベル

#色
c_yellow = "#EFB60F"#棒グラフの色
c_black = "#333333"#点の色
c_gray = "#777777" #軸の色

#サイズ
label_s1 = 15#軸等の文字サイズ

#グラフサイズ
fig_x = 6
fig_y = 6

fig = plt.figure(figsize=(fig_x,fig_y))#グラフの作成
ax1 = fig.add_subplot(111)#subplotの作成

#フォント指定
plt.rcParams['font.family'] = 'Meiryo'

#縦棒グラフ
bar_w = 0.5 #棒グラフの太さ
ind = np.arange(len(sales)) #要素の数
p1 = ax1.bar(ind, sales, bar_w, label='売上', color=c_yellow)#縦棒グラフ

#x軸
ax1.tick_params(axis='x', which='both', bottom=False, top=False)#xticksの目盛を消す
ax1.set_xticks(ind)
ax1.set_xticklabels(labels, fontsize=label_s1, color=c_gray)#x軸のラベルの設定

#y軸
y_ticks = [0,250,500]#軸ラベルの値
#ax1.set_ylabel('売上', fontsize=label_s1, color=c_gray)#y軸のラベルを加える場合
ax1.set_yticks(y_ticks, color=c_gray )#y軸目盛線の設定
ax1.set_yticklabels(y_ticks, fontsize=label_s1, color=c_gray)#y軸目目盛ラベルの設定
ax1.grid(axis="y")#y軸目盛線をありに

# 売上と利益の比率の折れ線グラフ
#plotグラフ
ax2 = ax1.twinx()#第二軸の設定
plot_s=8#plotの点のサイズ
plot_lw=3#plotの線の太さ
plot_mw=3#plotの枠の太さ
plot_fc="#ffffff"#plotの塗りつぶしの色
ax2.plot(labels, profit, color=c_black, markerfacecolor=plot_fc, markeredgewidth=plot_mw, lw=plot_lw, ms=plot_s, marker='o', label='営業利益')#データ点の設定

#y軸第二軸
y2_ticks = [0,250,500]#軸ラベルの値
#ax2.set_ylabel('営業利益', fontsize=y2label_s, color=y2label_c ,rotation=270, labelpad=20)#y軸のラベルを加える場合
ax2.set_yticks(y2_ticks, color=c_gray )#y軸目盛線の設定
ax2.set_yticklabels(y2_ticks, fontsize=label_s1, color=c_gray)#y軸目目盛ラベルの設定
ax2.grid(axis="y")#y軸目盛線をありに

# 売上の数値を棒グラフの上に表示
for rect in p1:
    height = rect.get_height()
    ax1.text(rect.get_x() + rect.get_width()/2., height + 5,
            '%d' % int(height), ha='center', va='bottom', color=c_yellow, fontweight='bold', fontsize=label_s1)

# 営業利益率の数値を折れ線グラフ上に表示
for i, txt in enumerate(profit):
    ax2.text(i, txt - 50, txt, ha='center', va='bottom', color=c_black, fontweight='bold', fontsize= label_s1)


#凡例
ax1.legend(loc='upper left', fontsize=label_s1, framealpha=1, frameon=False, bbox_to_anchor=(0, 1.1), labelcolor=c_gray)#棒グラフの凡例
ax2.legend(loc='upper left', fontsize=label_s1, framealpha=1, frameon=False, bbox_to_anchor=(0.3, 1.1), labelcolor=c_gray)#plotの凡例

#y軸の単位を加える
fig.text(0.03, 0.93, '(億円)', ha='left', va='center', color=c_gray , fontsize= label_s1)#y軸単位
fig.text(0.90, 0.93, '(億円)', ha='left', va='center', color=c_gray , fontsize= label_s1)#y第二軸単位

#枠線を消す
spine_w = 1
ax1.spines['top'].set_linewidth(0)
ax1.spines['bottom'].set_linewidth(0)
ax1.spines['left'].set_linewidth(0)
ax1.spines['right'].set_linewidth(0)
ax2.spines['top'].set_linewidth(0)
ax2.spines['bottom'].set_linewidth(spine_w)#bottomだけは線を引く
ax2.spines['bottom'].set_color(c_gray)#bottomだけは線を引く
ax2.spines['left'].set_linewidth(0)
ax2.spines['right'].set_linewidth(0)

#yticksの目盛線を消す
ax1.tick_params(axis='both', which='both', bottom=False, top=False, left=False, right=False)#yticksの目盛を消す
ax2.tick_params(axis='both', which='both', bottom=False, top=False, left=False, right=False)#yticksの目盛を消す

plt.show()