質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

新規登録して質問してみよう
ただいま回答率
85.35%
Matplotlib

MatplotlibはPythonのおよび、NumPy用のグラフ描画ライブラリです。多くの場合、IPythonと連携して使われます。

Python

Pythonは、コードの読みやすさが特徴的なプログラミング言語の1つです。 強い型付け、動的型付けに対応しており、後方互換性がないバージョン2系とバージョン3系が使用されています。 商用製品の開発にも無料で使用でき、OSだけでなく仮想環境にも対応。Unicodeによる文字列操作をサポートしているため、日本語処理も標準で可能です。

Q&A

解決済

1回答

931閲覧

for文で作ったグラフに余分な直線が出てきたから消したい。

nozomukunn

総合スコア1

Matplotlib

MatplotlibはPythonのおよび、NumPy用のグラフ描画ライブラリです。多くの場合、IPythonと連携して使われます。

Python

Pythonは、コードの読みやすさが特徴的なプログラミング言語の1つです。 強い型付け、動的型付けに対応しており、後方互換性がないバージョン2系とバージョン3系が使用されています。 商用製品の開発にも無料で使用でき、OSだけでなく仮想環境にも対応。Unicodeによる文字列操作をサポートしているため、日本語処理も標準で可能です。

0グッド

0クリップ

投稿2021/02/02 14:00

編集2021/02/02 14:46

前提・実現したいこと

Pythonで変数xに合わせてヘルムホルツの自由エネルギーFを求め、温度毎にプロットしようとしています。
Fを求める過程はできたので、それを関数化し、for文で任意範囲でプロットしようとしました。

関数化はできたと思い、手打ちでt=400,500,,,1100を回すと目標のグラフが得られました。
for文で回すと望まないグラフのように0と1を繋ぐ直線が現れました。この直線を除きたいです。

発生している問題・エラーメッセージ

for文を使うと直線が現れてしまう。

該当のソースコード

Python

1import math 2import matplotlib.pyplot as plt 3 4Ua=3.39416e2 #金属Aの凝集エネルギー 5Ub=2.8842e2 #金属Bの凝集エネルギー 6N=6.02e23 #アボガドロ定数 7z=12 #配位数 8k=1.3806e-23 #ボルツマン定数 9 10vaa=6.1e-20 #金属A-A相互作用エネルギー 11vbb=6.0e-20 #金属B-B相互作用エネルギー 12vab=5.7e-20 #金属A-B相互作用エネルギー 13v=vab-((vaa+vbb)/2) 14 15F=0 #自由エネルギーF 16 17x2=[i/100 for i in range(1,100)] #x座標0.01~0.99を0.01刻み 18 19 20#xli=[] 座標x用のリスト 21#free=[] 自由エネルギーF用のリスト 22 23 24 25#Fを求める 26def free_en(t): 27 #U = - Ua*(1-x) -Ub*x - N*z*v*x(1-x) 28 #S = -N*k*( (x*ln(x)) + ((1-x)*ln(1-x)) ) 29 #F = U + S*t 30 x=0 31 x1=1e-11 32 33 #関数の中でxliとfreeを宣言、に変更 34 xli=[] 35 free=[] 36 37 #x=0だとlogが使えないからx1でFを求める 38 F= -(Ua*(1 - x1)) -(Ub*x1) -(N*z*k*x1*(1-x1)) - N*k*t*(x1*math.log(x1)+(1-x1)*math.log(1-x1)) 39 free.append(F) 40 xli.append(x) 41 x+=0.01 42 43 for j in range(0,99):#x=0.01~0.99までのときのFを求める 44 U= - (Ua*(1 - x2[j])) - (Ub*x2[j]) - (N*z*v*x2[j]*(1-x2[j])) 45 S= N*k*((x2[j]*math.log(x2[j]))+(1-x2[j])*math.log(1-x2[j])) 46 F= U + S*t 47 free.append(F) 48 xli.append(x) 49 x+=0.01 50 51 #x=1だと(1-x)でまたlogに0が入るからx1を使う 52 F= -(Ua*(1 - x1)) -(Ub*x1) -(N*z*k*x1*(1-x1)) - N*k*t*(x1*math.log(x1)+(1-x1)*math.log(1-x1)) 53 free.append(F) 54 xli.append(x) 55 56 return xli, free 57 58 59for l in range(400,1200,100): #400~1100でプロットしたい 60 xli, free = free_en(l) 61 #plt.plot(xli,free) 62 plt.plot(xli,free,label="t={}".format(l))#凡例を加えた 63 plt.legend() 64 65 66

試したこと

なにが原因か分からないため試したことがないです。

free_en(400)
plt.plot(xli,free, label="t=400")
plt.legend()
~~↑これを500,600,700,,1100についてやったら目標のグラフができた。~~~~

for l in range(400,1200,100): #400~1100でプロットしたい
xli, free = free_en(l)
plt.plot(xli, free,label="t={}".format(l))
plt.legend()

頂いた回答に凡例を加えた。

補足情報(FW/ツールのバージョンなど)

目標のグラフ
手打ちでtを変えた。
イメージ説明

望まないグラフ
0~1を繋ぐ直線が出てきた。これがいらない。
温度毎に色を変えたいし凡例も入れたいけれどまず直線を消したい。
イメージ説明

いただいた回答をもとに作成したグラフ。
イメージ説明

気になる質問をクリップする

クリップした質問は、後からいつでもMYページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

guest

回答1

0

ベストアンサー

xlifreeというリストをグローバル変数にして使いまわしているのが、あまりよろしくないです。

その結果、xlifreeの中にはt=400のグラフの一番最後の点(x=1, F=xx)の次に、t=500のグラフの一番最初の点(x=0, F=xx)が入り、これらが直線でつながってしまっているのだと思います。

free_en()の中でxlifreeを宣言し、これを返す関数の形にするとうまくいくと思います。

Python

1def free_en(t): 2 xli=[]#座標x用のリスト 3 free=[]#自由エネルギーF用のリスト 4 5 ...中略... 6 7 free.append(F) 8 xli.append(x) 9 10 return xli, free

Python

1for l in range(400,1200,100): #400~1100でプロットしたい 2 xli, free = free_en(l) 3 plt.plot(xli,free)

投稿2021/02/02 14:23

Amakaze

総合スコア313

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

nozomukunn

2021/02/02 14:35

回答ありがとうございます! ご指摘の通りでした!
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
85.35%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問