線の 1 つが正か負かに関係なく、2 つの曲線の間の領域を異なる色でプロットしたいと考えています。曲線の符号が変わると、領域の不連続な色付けでエッジ効果が得られました。設定interpolate=True
はあまり役に立ちません。エッジ効果は解像度に関連しています (以下の基本的な例では自発的に粗くなっています) - それを強化することは、私が実際に望んでいることではありません。スムーズな移行を行うためのより良い解決策はありますか? ありがとう。
import matplotlib.pyplot as plt
import numpy
plt.figure()
x=numpy.arange(0.,1.05,0.05)
y1=numpy.sin(2*numpy.pi*x)
y2=y1+0.2
y1positive=y1>0
y1negative=y1<=0
plt.plot(x,y1,'r',label='y1')
plt.plot(x,y2,'g',label='y2')
plt.plot(x,x*0,'--k')
plt.fill_between(x,y2,y1,where=y1positive,color='green',alpha=0.5)
plt.fill_between(x,y2,y1,where=y1negative,color='red',alpha=0.5,interpolate=True)
plt.legend()
http://i.stack.imgur.com/9Q9Ff.png
**編集**上記の問題に適切に対処しているpyHazardの回答に基づいていますが、それでも問題が発生します:
改訂されたケース (コードを参照) - 2 つの合計された曲線が同じ符号を持っている場合はそれらの間の領域を埋める必要があり、そうでない場合はそれらの 1 つとゼロの間の領域を埋める必要があります。where=
条件が変化した場合、塗りつぶされた領域は連続している必要があります。小さなマージンを含めることは確かに役立ちますが、問題を完全に解決するわけではありません (塗りつぶされたサーフェスはまだ中断されています)。必要なのは、実際には、幅のない条件であるfill_between
wherey1=0
です...次に、一種の条件where y1-eta<=0<=y1+eta
が必要になるだけですが、愚かにもそこでブロックされています。塗りつぶされた領域を完全に連続にするアイデアはありますか? ありがとう!
plt.figure()
x=numpy.arange(0.,3.05,0.05)
y1=numpy.sin(2*numpy.pi*x)
y2=[2.]*len(y1)
y3=[-2.]*len(y1)
eta=1e-6
y1positive=y1+eta>=0
y1negative=y1-eta<=0
plt.plot(x,x*0,'--k')
plt.plot(x,y1,'.-k',label='y1')
plt.plot(x,y2,'.-g',label='y2')
plt.plot(x,y3,'.-r',label='y3')
plt.fill_between(x,y2+y1,y1,where=y1positive,color='green',alpha=0.5,linewidth=0)
plt.fill_between(x,y2,0,where=y1negative,color='green',alpha=0.5,linewidth=0)
plt.fill_between(x,y3+y1,y1,where=y1negative,color='red',alpha=0.5,linewidth=0)
plt.fill_between(x,y3,0,where=y1positive,color='red',alpha=0.5,linewidth=0)
plt.legend()
わかりやすくするために、元のプロットを次に示します (eta=0.
上記のコードを使用)。緑と赤の領域の垂直方向の中断を除いて、すべて問題ありません。正弦曲線とゼロの間の空白領域は問題ありません。問題のある垂直方向の中断は、塗りつぶされた領域の定義に起因します。サインと水平曲線が同じ符号を持っている場合、または水平曲線とゼロの間で、サインと水平曲線が反対の符号を持っている場合です。そのため、塗りつぶされた領域の条件にスイッチがあり、空白の垂直ゾーンは望ましくないエッジ効果です...
*最終編集* [ソリューション付き]
内で解決策を見つけることができないためfill_between
、1 つの解決策 (pyHazard の回答に基づく) は、塗りつぶされた領域の上限と下限を再計算して、それらが連続していることを確認することです (fill_between
状態が変化しなくなります)。
plt.figure()
x=numpy.arange(0.,3.05,0.05)
y1=numpy.sin(2*numpy.pi*x)
y2=[2.]*len(y1)
y3=[-2.]*len(y1)
y1positive=y1>=0
y1negative=y1<=0
plt.plot(x,x*0,'--k')
plt.plot(x,y1,'.-k',label='y1')
plt.plot(x,y2,'.-g',label='y2')
plt.plot(x,y3,'.-r',label='y3')
#Solution: recalculate the upper and lower limit of filled areas
# to have each of them as one continuous line
y0=[0.]*len(y1)
y1pos=numpy.amax(numpy.vstack((y1,y0)),axis=0.)
y1neg=numpy.amin(numpy.vstack((y1,y0)),axis=0.)
y21=y2+y1pos
y31=y3+y1neg
plt.fill_between(x,y21,y1pos,color='green',alpha=0.5,linewidth=0)
plt.fill_between(x,y31,y1neg,color='red',alpha=0.5,linewidth=0)
plt.legend()