Last active
February 13, 2018 17:55
-
-
Save nukisashineko/6f6e29664d28510dee5eef1ced78be68 to your computer and use it in GitHub Desktop.
seabornでhueを使いながら、複数のグラフを重ねたかった
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
a sentence |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
##フィッティングに使うもの | |
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() # 少し注意が必要 |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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