使用python/matplotlib绘制分段定义函数

使用python/matplotlib绘制分段定义函数,python,numpy,matplotlib,plot,scipy,Python,Numpy,Matplotlib,Plot,Scipy,我不熟悉Python和Scipy。目前我正试图在matplotlib中绘制一条p型晶体管传输曲线。它是分段定义的,我正在努力寻找一个好的方法来得到结果曲线。到目前为止,我得到的是: import matplotlib.pyplot as plt import numpy as np from scipy.constants import epsilon_0 V_GS = np.linspace(-15, 10, 100) # V V_th = 1.9 # V V_DS = -10 # V mu

我不熟悉Python和Scipy。目前我正试图在matplotlib中绘制一条p型晶体管传输曲线。它是分段定义的,我正在努力寻找一个好的方法来得到结果曲线。到目前为止,我得到的是:

import matplotlib.pyplot as plt
import numpy as np
from scipy.constants import epsilon_0

V_GS = np.linspace(-15, 10, 100) # V
V_th = 1.9 # V
V_DS = -10 # V
mu_p = 0.1e-4 # m²/Vs
epsilon_r = 7.1
W = 200e-6 # m
L = 10e-6 # m
d = 70e-9 # m
C_G = epsilon_0*epsilon_r/d
beta = -mu_p*C_G*W/L

Ids_cutoff = np.empty(100); Ids_cutoff.fill(-1e-12)
Ids_lin = beta*((V_GS-V_th)*V_DS-V_DS**2/2)
Ids_sat = beta*1/2*(V_GS-V_th)**2

plt.plot(V_GS, Ids_lin, label='lin')
plt.plot(V_GS, Ids_sat, label='sat')
plt.plot(V_GS, Ids_cutoff, label='cutoff')

plt.xlabel('V_GS [V]')
plt.ylabel('I [A]')
plt.legend(loc=0)

plt.show()
这给出了整个V_GS范围内的三条曲线。现在我想定义一下

Ids = Ids_cutoff for V_GS >= V_th
Ids = Ids_lin for V_GS < V_th; V_DS >= V_GS - V_th
Ids = Ids_sat for V_GS < V_th; V_DS < V_GS - V_th
Ids=Ids\u V\u GS>=V\u th
Ids=V_GS=V_GS-V_th
Ids=V_GS
我找到了np.vectorize()的一个例子,但不知怎的,我很难理解如何使用这些数组。我可以创建一个遍历所有值的for循环,但我确信有更有效的方法来实现这一点


除了导出ID的值列表并绘制它与V_GS的对比图外,是否还可以使用matplotlib将三个方程绘制为一条曲线?

是否要根据选择器填充数组
Vds

Vds = np.zeros_like(V_GS)  # for the same shape
Vds[V_GS >= V_th] = Ids_cutoff
Vds[(V_GS < V_th) & (V_DS >= V_GS - V_th)] = Ids_lin
Vds[(V_GS < V_th) & (V_DS < V_GS - V_th)] = Ids_sat
结果:


由于Not数字不是可绘制的,因此不会绘制任何线条。

在阅读了numpy的详细信息后,我终于想出了一种方法:

Ids_cutoff = -1e-12 # instead of creating an array as posted above
# create masks for range of validity for linear and saturation region
is_lin = np.zeros_like(V_GS, dtype=np.bool_)
is_lin[(V_GS < V_th) & (V_DS >= V_GS - V_th)] = 'TRUE'
is_sat = np.zeros_like(V_GS, dtype=np.bool_)
is_sat[(V_GS < V_th) & (V_DS < V_GS - V_th)] = 'TRUE'

# create final array and fill with off-current
Ids = np.zeros_like(V_GS); Ids.fill(Ids_cutoff)
# replace by values for linear and saturation region where valid
Ids = np.where(is_lin, Ids_lin, Ids)
Ids = np.where(is_sat, Ids_sat, Ids)
plt.plot(V_GS, Ids, '*', label='final')
Ids_-cutoff=-1e-12#而不是像上面发布的那样创建数组
#为线性和饱和区域的有效范围创建遮罩
林=np.zeros类似(V\u GS,dtype=np.bool)
林[(V_GS=V_GS-V_th)]是否为“真”
类似于(V_GS,dtype=np.bool)的
_sat[(V_GS
所以我将中间部分改为:我得到的是:Ids[V\u GS>=V\u th]=Ids\u截断值错误:NumPy布尔数组索引分配无法将100个输入值分配给掩码为true的33个输出值为什么Ids\u截断的大小固定为100?只需给它分配一个值,我们就可以根据我们的掩码,将它分配给我们想要的任意多个值。在Ids_截断的情况下,我同意,实际上这就是我所做的,它是有效的。但是Ids_-lin和Ids_-sat也会发生同样的情况,因为它们是基于V_-GS的,V_-GS是一个数组,所以得到的Ids_-sat和Ids_-lin也是长度为100的数组。然后请调整代码,以便获得正确的值数。我不会深入研究你的潜在问题来创建一个有效的解决方案。看见
Ids_cutoff = -1e-12 # instead of creating an array as posted above
# create masks for range of validity for linear and saturation region
is_lin = np.zeros_like(V_GS, dtype=np.bool_)
is_lin[(V_GS < V_th) & (V_DS >= V_GS - V_th)] = 'TRUE'
is_sat = np.zeros_like(V_GS, dtype=np.bool_)
is_sat[(V_GS < V_th) & (V_DS < V_GS - V_th)] = 'TRUE'

# create final array and fill with off-current
Ids = np.zeros_like(V_GS); Ids.fill(Ids_cutoff)
# replace by values for linear and saturation region where valid
Ids = np.where(is_lin, Ids_lin, Ids)
Ids = np.where(is_sat, Ids_sat, Ids)
plt.plot(V_GS, Ids, '*', label='final')