Skip to content

Instantly share code, notes, and snippets.

@nukisashineko
Last active February 13, 2018 17:55
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save nukisashineko/6f6e29664d28510dee5eef1ced78be68 to your computer and use it in GitHub Desktop.
Save nukisashineko/6f6e29664d28510dee5eef1ced78be68 to your computer and use it in GitHub Desktop.
seabornでhueを使いながら、複数のグラフを重ねたかった
##フィッティングに使うもの
from scipy.optimize import curve_fit
import numpy as np
import pandas
## 図示のために使うもの
import seaborn as sns
import matplotlib.pyplot as plt
# 今回のフィッティング関数
def nonlinear_fit(x, a, b):
return b * np.exp(x / (a + x))
# 標準APIになかったので雑に作成
def uniq(seq):
seen = set()
seen_add = seen.add
return [x for x in seq if x not in seen and not seen_add(x)]
# fitting_y という カーブフィッティングによって線形回帰させた時のyの値を追加したdfを返す関数
def add_column_of_fitting_y(df):
y_limits = uniq(np.array(df.loc[:, "y_limit"]))
result = pandas.DataFrame()
# y_limitsごとに線形回帰させて近似関数のyの値を取得する
for i in range(len(y_limits)):
tmp_df = df[df["y_limit"] == y_limits[i]].copy()
param, cov = curve_fit(nonlinear_fit, tmp_df["x"], tmp_df["y"])
tmp_df["fitting_y"] = nonlinear_fit(tmp_df["x"],param[0], param[1])
result = result.append(tmp_df)
return result
# グラフを重ねて表示するための見栄え調整
def adjust_graph_title_etc(fig, ax, result):
# 凡例の位置を外部に変えて、図を縮小して凡例の見切れをなくす。
ax.legend(bbox_to_anchor=(1.05, 1), loc=2, borderaxespad=0.)
fig.subplots_adjust(right=0.8)
# 軸タイトルとかタイトルとかの調整
fig.suptitle('CURVE FITTING')
plt.ylabel('y')
plt.xlabel('x')
x = uniq(result['x'])
xlabels = [x[i] if i % 2 == 0 else '' for i in range(len(x))]
ax.set(xticklabels=xlabels)
return;
# 重ねてグラフを表示する関数
def plot_overlay_graphs():
# フィッティング処理
df = pandas.read_csv("sample_data.csv")
result = add_column_of_fitting_y(df)
# 出力
fig = plt.figure()
ax = sns.pointplot(x="x", y="fitting_y", hue="y_limit", data=result, markers="")
ax.collections.clear() # 「今回の肝」 コレが無いとエラーで落ちる。
sns.pointplot(x="x", y="y", hue="y_limit", data=result, join=False, ax=ax)
adjust_graph_title_etc(fig, ax, result)
plt.show()
# 解説
# hue を入力した際、legendが自動的に作成され、hueから自動生成された配色(※1)が凡例表示用にaxに保存される。
# 次にplotする際にhueが指定されている場合、legendを自動生成しようとする。
# hueから配色が自動生成されるが、これは※1と同じものである。
# 【このエラー落ちは matplotlib ~v2.1.1までの事象となります】
# ここで問題となるのが、axの凡例表示用配色の保存には重複チェックがあり、同じ色を保存しようとすると以下のようなエラーで落ちる。
# File "${HOME}/anaconda3/lib/python3.6/site-packages/matplotlib/legend.py", line 1344, in _in_handles
# if f_h.get_facecolor() != h.get_facecolor():
# ValueError: The truth value of an array with more than one element is ambiguous. Use a.any() or a.all()
# AttributeError(属性エラー)系でエラーである。
# コレを防ぐためには、直前のseabornのplotでaxに保存されてしまった凡例表示用の配色を消去しなければならない。
# 凡例表示用の配色リストは ax.collections (type:list) に保存されているため削除関数clearを利用する
# 同じhue(とpalette)を指定してグラフを重ねようとした場合に、エラー落ちしなくなる。
# 【 matplotlib v2.1.2~ 】
# ax.collections.clear()を利用しなくても、エラー落ちはしなくなりましたが凡例はおかしくなります。
# 無理やりhueを利用したい場合は、やはりax.collections.clear()が必要になります。
# ただし、groupbyを利用してplot関数を回したほうが良いかもしれません。
# 詳細な作業ログはQittaにあります。
# https://qiita.com/nukisashineko/items/c8ec27dfd0fbf61bc8e1
# 2つに分けて出力するグラフの見栄え調整
def adjust_graph_title_etc2(fig, axes, result):
#凡例の調整
axes.flatten()[0] = axes.flatten()[0].legend_.remove()
axes.flatten()[1].legend(bbox_to_anchor=(1.05, 1), loc=2, borderaxespad=0.)
fig.subplots_adjust(right=0.8)
# 軸タイトルとかタイトルとかの調整
x = uniq(result['x'])
xlabels = [(int)(x[i]) if i % 4 == 0 else '' for i in range(len(x))]
axes.flatten()[0].set(xticklabels=xlabels)
axes.flatten()[1].set(xticklabels=xlabels)
return;
# 2つに分けてグラフを出力する
def plot_divided_graphs():
# フィッティング処理
df = pandas.read_csv("sample_data.csv")
result = add_column_of_fitting_y(df)
# 出力
fig, axes = plt.subplots(1, 2, sharey=True)
sns.pointplot(x="x", y="fitting_y", hue="y_limit", data=result, markers="", ax=axes.flatten()[0])
sns.pointplot(x="x", y="y", hue="y_limit", data=result, join=False, ax=axes.flatten()[1])
adjust_graph_title_etc2(fig, axes, result)
plt.show()
if __name__ == '__main__':
plot_divided_graphs() # 簡単にできる
plot_overlay_graphs() # 少し注意が必要
x y y_limit
33.0 1.7083333333333333 2
33.0 2.2929874999999997 3
33.0 2.60314 4
33.0 2.7187666666666663 5
33.0 2.9922 6
33.0 3.1172 7
33.0 3.1797 8
33.0 3.203125 9
33.0 3.203125 10
33.0 3.203125 11
33.0 3.203125 12
33.0 3.203125 13
63.0 1.8248857142857144 2
63.0 2.5 3
63.0 2.9886999999999997 4
63.0 3.30968 5
63.0 3.322575 6
63.0 3.3629 7
63.0 3.375 8
63.0 3.375 9
63.0 3.375 10
63.0 3.375 11
63.0 3.375 12
63.0 3.375 13
96.0 1.8631571428571427 2
96.0 2.5906333333333333 3
96.0 3.1726300000000003 4
96.0 3.5863199999999997 5
96.0 3.91315 6
96.0 4.2 7
96.0 4.400025 8
96.0 4.5 9
96.0 4.52895 10
96.0 4.5394749999999995 11
96.0 4.5394749999999995 12
96.0 4.5394749999999995 13
126.0 1.874 2
126.0 2.6008 3
126.0 3.2560000000000002 4
126.0 3.7119999999999997 5
126.0 4.03 6
126.0 4.21 7
126.0 4.356 8
126.0 4.382 9
126.0 4.4 10
126.0 4.406 11
126.0 4.406 12
126.0 4.406 13
159.0 1.8878857142857142 2
159.0 2.66078 3
159.0 3.3183599999999998 4
159.0 3.7601199999999997 5
159.0 4.155049999999999 6
159.0 4.4541249999999994 7
159.0 4.675625 8
159.0 4.8402 9
159.0 4.9557 10
159.0 5.0268999999999995 11
159.0 5.039575 12
159.0 5.039575 13
189.0 1.8982875 2
189.0 2.6787199999999998 3
189.0 3.3324599999999998 4
189.0 3.93935 5
189.0 4.3843 6
189.0 4.730025 7
189.0 4.972075 8
189.0 5.1210249999999995 9
189.0 5.21275 10
189.0 5.3271250000000006 11
189.0 5.361699999999999 12
189.0 5.367025 13
222.0 1.915342857142857 2
222.0 2.67467 3
222.0 3.2954700000000003 4
222.0 3.85465 5
222.0 4.324675 6
222.0 4.595 7
222.0 4.764725 8
222.0 4.82015 9
222.0 4.865375 10
222.0 4.8744250000000005 11
222.0 4.8744250000000005 12
222.0 4.8744250000000005 13
252.0 1.9088222222222224 2
252.0 2.704 3
252.0 3.4123400000000004 4
252.0 3.9342750000000004 5
252.0 4.38745 6
252.0 4.891425 7
252.0 5.318725 8
252.0 5.564725 9
252.0 5.806774999999999 10
252.0 6.012925 11
252.0 6.118525 12
252.0 6.247025 13
285.0 1.9251875 2
285.0 2.6883999999999997 3
285.0 3.37325 4
285.0 3.976225 5
285.0 4.4023 6
285.0 4.700725 7
285.0 4.874975 8
285.0 4.973599999999999 9
285.0 5.10475 10
285.0 5.206 11
285.0 5.2403249999999995 12
285.0 5.24825 13
315.0 1.92755 2
315.0 2.71785 3
315.0 3.35573 4
315.0 3.9784999999999995 5
315.0 4.410825 6
315.0 4.671175 7
315.0 4.8702250000000005 8
315.0 4.96335 9
315.0 5.032675 10
315.0 5.0438 11
315.0 5.0438 12
315.0 5.0438 13
348.0 1.93695 2
348.0 2.7533100000000004 3
348.0 3.5092200000000005 4
348.0 4.1937999999999995 5
348.0 4.689475 6
348.0 5.086449999999999 7
348.0 5.475524999999999 8
348.0 5.724774999999999 9
348.0 5.893375000000001 10
348.0 6.05475 11
348.0 6.177225 12
348.0 6.24425 13
378.0 1.9310333333333334 2
378.0 2.73979 3
378.0 3.45651 4
378.0 4.100775 5
378.0 4.7281 6
378.0 5.175725 7
378.0 5.456899999999999 8
378.0 5.68435 9
378.0 5.865399999999999 10
378.0 5.958875000000001 11
378.0 6.086875 12
378.0 6.122025 13
411.0 1.91513 2
411.0 2.71975 3
411.0 3.3980399999999995 4
411.0 3.850625 5
411.0 4.32255 6
411.0 4.720125 7
411.0 5.010375 8
411.0 5.228025000000001 9
411.0 5.33475 10
411.0 5.403675 11
411.0 5.4213249999999995 12
411.0 5.426824999999999 13
441.0 1.9343299999999999 2
441.0 2.7829299999999995 3
441.0 3.5184000000000006 4
441.0 4.130125 5
441.0 4.6085 6
441.0 5.076125 7
441.0 5.5108 8
441.0 5.945475000000001 9
441.0 6.243775 10
441.0 6.42785 11
441.0 6.564225 12
441.0 6.6198749999999995 13
474.0 1.9363699999999997 2
474.0 2.7642499999999997 3
474.0 3.5295900000000002 4
474.0 4.2373 5
474.0 4.755275000000001 6
474.0 5.184475 7
474.0 5.5317 8
474.0 5.770099999999999 9
474.0 5.940799999999999 10
474.0 6.058125 11
474.0 6.104675 12
474.0 6.132675 13
504.0 1.934 2
504.0 2.73937 3
504.0 3.4645555555555556 4
504.0 4.045225 5
504.0 4.549225 6
504.0 4.9513 7
504.0 5.30715 8
504.0 5.560625 9
504.0 5.7261500000000005 10
504.0 5.820575 11
504.0 5.8797 12
504.0 5.91005 13
537.0 1.9386300000000003 2
537.0 2.74365 3
537.0 3.51233 4
537.0 4.083024999999999 5
537.0 4.645975 6
537.0 5.069025 7
537.0 5.4235 8
537.0 5.5695 9
537.0 5.737874999999999 10
537.0 5.909525 11
537.0 6.039175 12
537.0 6.098899999999999 13
567.0 1.94558 2
567.0 2.77563 3
567.0 3.53975 4
567.0 4.289325 5
567.0 4.8273 6
567.0 5.2809 7
567.0 5.655474999999999 8
567.0 5.9845749999999995 9
567.0 6.367474999999999 10
567.0 6.659 11
567.0 6.788 12
567.0 6.9461 13
600.0 1.9395222222222221 2
600.0 2.8005 3
600.0 3.608977777777778 4
600.0 4.2983 5
600.0 4.874233333333333 6
600.0 5.345566666666667 7
600.0 5.749033333333333 8
600.0 6.025033333333333 9
600.0 6.268766666666667 10
600.0 6.4669 11
600.0 6.647766666666667 12
600.0 6.770733333333333 13
630.0 1.9491100000000003 2
630.0 2.80096 3
630.0 3.5513600000000003 4
630.0 4.235799999999999 5
630.0 4.7307999999999995 6
630.0 5.1876 7
630.0 5.616833333333333 8
630.0 5.935866666666667 9
630.0 6.194466666666667 10
630.0 6.375733333333334 11
630.0 6.5363 12
630.0 6.670366666666666 13
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment