【问题标题】:Plotting sectionwise defined function with python/matplotlib使用 python/matplotlib 绘制分段定义的函数
【发布时间】:2015-01-21 10:52:05
【问题描述】:

我是 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

我找到了 np.vectorize() 的示例,但不知何故,我一直在努力理解如何使用这些数组。我可以创建一个遍历所有值的 for 循环,但我很确定有更有效的方法可以做到这一点。

除了导出 Ids 的值列表并将其与 V_GS 进行绘图之外,是否还可以将 matplotlib 的三个方程分段绘制为一条曲线?

【问题讨论】:

    标签: python numpy matplotlib plot scipy


    【解决方案1】:

    你想根据你的选择器填充数组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
    

    通过分段绘制,您的意思是省略一定范围?您可以为此使用 np.nan:

    plt.plot([0,1,2,3,np.nan,10,11], np.arange(7))
    

    结果:

    由于 Not a Number 不可绘制,因此不会画线。

    【讨论】:

    • 所以我把中间部分改为:
    • 我得到的是:Ids[V_GS >= V_th] = Ids_cutoff ValueError: NumPy boolean array indexing assignment cannot assign 100 input values to the 33 output values where the mask is true
    • 为什么Ids_cutoff的大小固定为100?只需为其分配一个值,这样我们就可以根据我们的掩码将其分配给任意数量的值。
    • 在 Ids_cutoff 的情况下,我同意,实际上这就是我所做的并且它有效。但是同样的事情发生在 Ids_lin 和 Ids_sat 因为它们基于 V_GS 这是一个数组,所以生成的 Ids_sat 和 Ids_lin 也是长度为 100 的数组。
    • 那么请调整您的代码,以便您拥有正确数量的值。我不会深入研究您的潜在问题以创建可行的解决方案。见How to create a Minimal, Complete, and Verifiable example
    【解决方案2】:

    在阅读了更多关于 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')
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2022-11-18
      • 2018-05-01
      • 1970-01-01
      • 1970-01-01
      • 2015-10-16
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多