【2022年度】化学メーカーの企業分析(キャッシュフロー)

化学メーカーの企業分析シリーズの一環としてキャッシュフローをグラフにしました。

ちょっと字が小さくて見づらいかもしれませんが、結構面白い比較が出来ました。

信越は利益の割には投資も控えめだったり、富士フイルムは大きめの投資をしていたりとかなり会社間で差がありますね。

DICは手持ち現金より大きい投資が発生してますが何事でしょう。色々と調査がはかどりそうです。

ちなみに先期末残高に今期のCFを足すと今期末残高がちょっとずれるんですがこれはなんでなんでしょう?

キャッシュフロー

これを作るためのコードはこちら

chemstat.hatenablog.com

【matplotlib】ウォーターフォールチャートを作りたい【python】

最近キャッシュフロー計算書を眺めていて、各社のキャッシュフローウォーターフォールチャートで作りたくなった。

またも非常に長いコードになったが一応求めていた仕上がりにはなったと思う。

これを作るために2週間くらいかかってしまった・・・。これでようやく企業間の比較が出来る・・・

 

 

import numpy as np
import pandas as pd
import matplotlib.pyplot as plt
import japanize_matplotlib
import matplotlib.patheffects as patheffects

##設定値
#文字サイズ設定
s_text_s = 12#文字サイズ小
s_text_m = 15#文字サイズ大

#色設定
color_r = "#dd3333"#赤色
color_b = "#0077bb"#青色
color_gr = "#aaaaaa"#グレー
color_gr2 = "#555555"#濃いグレー

#グラフ設定
fig_x = 10#グラフ横幅
fig_y = 5#グラフ縦幅
font = 'Meiryo'

#棒グラフ設定
bar_w = 0.15#棒グラフ幅
space = 1.2#棒グラフ間スペース
label_offset = 80#データラベルのオフセット 

#線の太さ
w_spine = 1#グラフの枠線
w_plot = 1#棒グラフを繋ぐ線の太さ

#y軸の設定
y_ticks = [0,1000,2000]#y軸の補助目盛位置
y_ticks_l = [0,1000,2000]#y軸の補助目盛ラベル

##関数定義
#ラベルを縦書きにするコード
def tategaki(labels):
    new_labels = []
    for n in labels:
        n2 = '\n'.join(n.replace("ー", "|"))#"-"を"|"に置換して、一文字ごとに"\n"を挟む
        new_labels.append(n2)
    return new_labels

##入力データ
data = {
    '先期末残高': [1000, 500],
    '営業CF': [500, -300],
    '投資CF': [300, -100],
    '財務CF': [-200, 200],
    '今期末残高': [1600, 300]
}

index = ['A社', 'B社']

df = pd.DataFrame(data, index=index)#元データのDataFrame
ind = np.arange(len(df.columns)) #要素の数

#棒グラフの下側のy座標
bottom_data = {
    '先期末残高': 0,
    '営業CF': df['先期末残高'],
    '投資CF': df['先期末残高'] + df['営業CF'],
    '財務CF': df['先期末残高'] + df['営業CF'] + df['投資CF'],
    '今期末残高': 0
    
}
index = ['A社', 'B社']
bottom_df = pd.DataFrame(bottom_data, index=index)

#棒グラフの上側のy座標
top_data = {
    '先期末残高': df['先期末残高'],
    '営業CF': df['先期末残高'] + df['営業CF'],
    '投資CF': df['先期末残高'] + df['営業CF'] + df['投資CF'],
    '財務CF': df['先期末残高'] + df['営業CF'] + df['投資CF'] + df['財務CF'],
    '今期末残高': df['今期末残高']
    
}
index = ['A社', 'B社']
top_df = pd.DataFrame(top_data, index=index)

#棒グラフのx座標を格納したDataFrame
bar_x_df = pd.DataFrame(index=df.index, columns=df.columns)
for i in range(len(bar_x_df)):
    for j in range(len(bar_x_df.columns)):
        bar_x_df.iloc[i, j] = i + (j -2) * bar_w * space
        
#棒グラフの色を格納したDataFrame
colors_df = df.applymap(lambda x: color_b if x >= 0 else color_r)#データがプラスなら青、マイナスなら赤
colors_df.iloc[:, [0]] = color_gr  #先期末残高は濃いグレー
colors_df.iloc[:, [-1]] = color_gr2  #今期末残高は濃いグレー

#データラベルのオフセットを格納したDataFrame
offset_df = df.applymap(lambda x: 1 if x >= 0 else -1) * label_offset

##グラフの描画
fig = plt.figure(figsize=(fig_x,fig_y), facecolor="white")#グラフの作成
ax1 = fig.add_subplot(111)#subplotの作成
plt.rcParams['font.family'] = font#フォント指定

##グラフの描画
for n in df.columns:
    #棒グラフ
    ax1.bar(bar_x_df[n],#x座標
            df[n],#上側y座標
            bottom=bottom_df[n],#下側y座標
            width=bar_w,#太さ
            color=colors_df[n]#色
            )
    

    #データラベル
    for m in np.arange(len(df[n])):
        ax1.text(bar_x_df[n][m],#x座標
                top_df[n][m] + offset_df[n][m],#y座標
                f"{int(df[n][m]):,}",#テキスト
                ha='center', va='center',#水平・垂直の中心位置
                color=colors_df[n][m],#文字色
                fontsize=s_text_s,#文字サイズ
                path_effects=[patheffects.withStroke(linewidth=4, foreground='white', capstyle="round")]#文字外周を白色に
                )
for n in np.arange(len(df.columns)-1):
    #棒グラフを繋ぐ線
    ax1.plot([bar_x_df.iloc[:,n] - bar_w * 0.5,
              bar_x_df.iloc[:,n+1] + bar_w * 0.5],#x座標
              [top_df.iloc[:,n],
              top_df.iloc[:,n]],#y座標
              color=color_gr,#文字色
              linewidth=w_plot#線の太さ
              )
    
##x軸
#x軸ラベルの位置を格納するDataFrame
list_xpos = bar_x_df.values.flatten().tolist()#上段の軸ラベルの座標
list_xpos.extend(np.arange(len(df))+0.000001)#下段の軸ラベルの座標。上段と同じ座標だと上書きされるので少しだけずらす。

list_xlabel_text=list([])#x軸ラベルのテキストを格納するDataFrame
list_xlabel_size=list([])#x軸ラベルのサイズを格納するDataFrame

for n in np.arange(len(df)):
    list_xlabel_text.extend(df.columns)#上段のラベルを追加
    list_xlabel_size.extend([s_text_s]*len(df.columns))#上段の文字サイズを追加
    
list_xlabel_text.extend("\n\n\n"+df.index)#下段のラベルを追加
list_xlabel_size.extend([s_text_m]*len(df.index))#下段の文字サイズを追加

list_xlabel_text = tategaki(list_xlabel_text)#縦書きに変換

#x軸の設定
ax1.tick_params(axis='x', which='both', bottom=False, top=False)#xticksの目盛を消す
ax1.set_xticks(list_xpos)#x軸の補助目盛設定
xticklabels = ax1.set_xticklabels(list_xlabel_text, color=color_gr2)#x軸のラベルの設定

# 各ラベルに個別の文字サイズを適用
for label, size in zip(xticklabels, list_xlabel_size):
    label.set_fontsize(size)

##y軸
ax1.set_yticks(y_ticks, color=color_gr)#y軸の補助目盛設定
ax1.set_yticklabels(y_ticks_l, fontsize=s_text_m, color=color_gr2)#y軸のラベル設定
ax1.grid(axis="y")#補助目盛あり
ax1.tick_params(axis='both', which='both', bottom=False, top=False, left=False, right=False)#yticksの目盛を消す
ax1.yaxis.set_major_formatter(plt.FuncFormatter(lambda x, loc: "{:,}".format(int(x))))#y軸を3桁ごとにカンマを入れる

fig.text(0.09, 0.93, '(百万円)', ha='center', va='center', color=color_gr2 , fontsize= s_text_m)#y軸単位

##枠線を消す
ax1.spines['top'].set_linewidth(0)
ax1.spines['bottom'].set_linewidth(w_spine)#bottomだけは線を引く
ax1.spines['bottom'].set_color(color_gr)#bottomだけは線を引く
ax1.spines['left'].set_linewidth(0)
ax1.spines['right'].set_linewidth(0)

##軸を背面に移動
ax1.set_axisbelow(True)
plt.show()

 

【matplotlib】x軸ラベルのサイズを個別に設定したい【python】

x軸のラベルを、ラベルごとにサイズを変えたくなった。

xticklabelsを変数で指定しておいて、後からfor文で呼び出してサイズをひとつずつ指定するのがいい模様。リストでまとめて指定できるのかと思ってたのですが無理そうです。

 



import matplotlib.pyplot as plt

# サンプルデータ
x = range(5)
y = [1, 2, 3, 4, 5]
labels = ['Label1', 'Label2', 'Label3', 'Label4', 'Label5']
sizes = [10, 12, 14, 16, 18]  # 各ラベルの文字サイズ

# プロット作成
fig, ax = plt.subplots()
ax.plot(x, y)

# x軸のラベルを設定
ax.set_xticks(x)
xticklabels = ax.set_xticklabels(labels)

# 各ラベルに個別の文字サイズを適用
for label, size in zip(xticklabels, sizes):
    label.set_fontsize(size)

plt.show()

【matplotlib】x軸ラベルを二段にしたい【python】

x軸のラベルを二段にしたくなった。調べてみたところ、軸ラベル用の座標を細かく設定し、x軸ラベルに「\n」を入れて下に下げるというやり方が出てきた。

若干スマートではない気もするが一旦これで解決。

textで足すという方法もあるみたい。

 

import numpy as np
import matplotlib.pyplot as plt

#データ
data1 = [1, 3]
data2 = [2, 4]

#棒グラフの作成
fig = plt.figure(figsize=(4,4))
ax = fig.add_subplot(111)

ind = np.arange(2)#データの位置
width = 0.4 #棒グラフの太さ

ax.bar(ind-width/2, data1, width)#data1の棒グラフ
ax.bar(ind+width/2, data2, width)#data2の棒グラフ

#x軸ラベルの設定
x = list()#x軸ラベル座標を入力するリスト
for i in ind:
    x.extend([i-width/2, i, i+width/2])#[(上段1), (下段), (上段2)]のラベル用の座標を作成。

ax.set_xticks(x)#xの位置にticsを設定
ax.set_xticklabels(('A1','\nA', 'A2', 'B1','\nB', 'B2'),ha='center')#xの位置にラベルを置く。下段は\nで改行する。

plt.show()

 

参考サイト

python - How to add the second line of labels for axes - Stack Overflow

 


【matplotlib】数字がプラスなら青、マイナスなら赤の棒グラフを描きたい【python】

会計関連のグラフを作るときに、プラスとマイナスで色を変えたくなった。

どうやるのかと思って調べてみたところ、それ用のリストを作成するのがいいらしい。

 

import matplotlib.pyplot as plt

# データの例
values = [3, 2, -2.3, 1.2, -0.4]
labels = ['A', 'B', 'C', 'D', 'E']

# 棒グラフを描画する際に、プラスの値は青、マイナスの値は赤にする
colors = ['blue' if x >= 0 else 'red' for x in values]

plt.figure(figsize=(10, 6))
plt.bar(labels, values, color=colors)
plt.show()


データ数とばらつきの関係を直感的に理解したい

実験データは必ずばらつきを含む。ばらつきに対してサンプル間の差が十分ないと有意差かどうかを判定することが出来ない。じゃあばらつきとサンプル間の差はどの程度必要なのかを簡単にシミュレーションしてみた。

まずサンプル間差(difference)と標準偏差sigma)を定義して、以下の条件で正規分になるデータを生成した。

data1:

平均値=1

標準偏差=sigma

data2:

平均値=1+difference

標準偏差=sigma

 

それぞれから一つずつデータを取り出してdata1<data2となっている確率を計算してみた。以下のグラフはdifference=0.1、sigma=0.1とすると76%でdata1<data2となる。

差が0であれば50%なわけだからそれよりはまし、ということになる。

 

じゃあdifferenceとsigmaを色々変えるとどうなるの?というのがこちら。

90%以上の確率で判定したい、と思うと標準偏差がデータの対して半分以下くらいないといけないということが分かる。

 

このsigma/differenceの比率と関係をシミュレーションしてみるとこうなる。sigma/differenceが大きくなるほど完全なランダムである50%に近づいていく。たとえ研究開発用途であっても90%くらいは正しく判定したい、と思うと標準偏差はデータ差に対して半分くらいにはしておきたいという気持ちになる。

最後にn増し実験の効果もシミュレーションしてみる。

繰り返し測定をして平均値をとった際の標準誤差は

SE=\frac{\sigma}{\sqrt{n}}

で表される。例えばsigma/differenceが1だったとしたら、n=1では75%、n=2では85%、n=3では90%程度に判定できる。

実験誤差があるなと思っても、実際どの程度小さくしないといけないのかは手間の問題もあって意外と難しい。量産フェーズだと工程能力指数を出すというセオリーがあるが、研究フェーズだと毎回そんなことをする手間は当然なく適当にn2くらいでお茶を濁す事が多い。

今後は今回の計算を頭に入れてどの程度増やす必要があるかを考えたい。困ったらn増しに尽きる。

 

世の中にはサンプルサイズ設計というものがあって、検知したいサンプル間差と精度を入れると必要な実験数を提示してくれる。この辺はまたおいおいちゃんと勉強したい。

【2022年度】銀行の企業分析(バランスシート、P/L)

自動車メーカーのバランスシートを作った際に「銀行のバランスシートを見ると面白いよ」というコメントを頂きました。

ということで作成してたのがこちら。

 

バランスシート

 

銀行だけ見ているとわかりづらいのでトヨタと並べてみましたが、圧倒的に銀行の資産規模が大きく自己資本比率が低いことが分かります。預貯金が負債として計上されていることでこうなるみたいですね。

銀行の間でいうとゆうちょの貸し出し比率が小さかったり、りそなは大きかったりと特徴あるみたいです。

P/L



バランスシートとPLを一緒にするとこんな感じ。売り上げ規模に対して銀行がどれだけ大きい資産を持っているかが良くわかります。




これを作成しているときに知ったのですが、銀行の財務諸表って他の企業と違うんですね。


これを作るためのコードはこちら

chemstat.hatenablog.com