在Python中使用matplotlib绘制条件函数

时间:2016-11-22 22:56:40

标签: python if-statement matplotlib plot

我试图创建此算法的线条或散点图,但它给出了错误

  

追踪(最近一次通话):   文件" /Users/itstest/Documents/workspace/Practice/src/PlutoModel.py" ;,第73行,在模块中   plt.plot(xr,P(xr))   文件" /Users/itstest/Documents/workspace/Practice/src/PlutoModel.py" ;,第55行,在P中     如果x> R:   ValueError:"具有多个元素的数组的真值是不明确的。使用a.any()a.all()。"

我已经查找了此错误的可能解决方案,但我认为不适用于我。

import numpy as np
import scipy.integrate as integ
import matplotlib.pyplot as plt

rho = 1860
rhos = 250 #Assuming Nitrogen Ice
rhom = 1000 #Assuming Water
rhoc = 3500 #Assuming a mix of Olivine and Pyroxene

def rhof(x):
    if x > r:
        return "Point is outside of the planet"
    elif x < r and x > rm:
        return rhos
    elif x < rm and x > rc:
        return rhom
    else:
        return rhoc

r = 1.187e6
rc = 8.5e5 #Hypothesized
rm = 9.37e5 #Estimated based on crustal thickness of 250 km

Ts = 44
B = 0.15
G = 6.67e-11

m = 1.303e22
mc = (4*np.pi*rhoc*rc**3)/3
mm = (4*np.pi*rhom*((rm**3) - (rc**3)))/3
ms = (4*np.pi*rhos*((r**3) - (rm**3)))/3

Ic = 0.4*mc*rc**2
Im = 0.4*mm*rm**2
Is = 0.4*ms*r**2
Itot = Is + Im + Ic

def gi(x):
    if x == r:
        return G*m/r**2
    elif x > r:
        return "Point is outside of the planet"
    elif x > rc and x < rm:
        return (G*mc/rc**2) + (G*mm/((x**2) - (rc**2)))
    elif x > rm and x < r:
        return (G*mc/rc**2) + (G*mm/((rm**2) - (rc**2))) + (G*ms/((x**2) - (rm**2)))
    else:
        return G*((3*rhoc)/4*np.pi*x**3)/x**2   

def Psmb(z):
    return rhos*G*(4.0/3.0)*np.pi*(1/z**2)*(rhom*(rm**3) + rhos*(z - rm**3))
def Pmcb(z):
    return rhom*G*(4.0/3.0)*np.pi*(1/z**2)*(rhoc*(rc**3) + rhom*(z - rc**3))
def P(x):
    if x > r:
        return "The point is outside of the planet"
    elif x == r:
        return 1
    elif x > rm and x < r:
        return (integ.quad(1000*gi(x), x, r))[0]
    elif x == rm:
        return (integ.quad(Psmb, x, r))[0]
    elif x > rc and x < rm:
        return (integ.quad(1000*gi(x), x, rm) + P(rm))[0]
    elif x == rc:
        return (integ.quad(Pmcb, x, rm) + P(rm))[0]
    elif x < rc and x != 0:
        return (integ.quad(1000*gi(x), x, rc) + P(rc))[0]
    else:
        return ((2.0/3.0)*np.pi*G*(rhoc**2)*r**2)

xr = np.linspace(0, 1187000, 1000)
plt.plot(xr, P(xr))

print("Mass = " + str(m) + " kg")
print("Radius = " + str(r) + " m")
print("Density = " + str(rho) + " kg/m^3")
print("Moment of Inertia = " + str(Itot) + " kgm^2")
print("Mean Surface Temperature = " + str(Ts) + " K")
print("Magnetic Field = " + str(B) + " nT")
print("Surface Gravity = " + str(gi(r)) + " m/sec^2")
print("Pressure at Surface = " + str(P(r)) + " Pa")
print("Pressure at Crust-Mantle Boundary = " + str(P(rm)) + " Pa")
print("Pressure at Mantle-Core Boundary = " + str(P(rc)) + " Pa")
print("Pressure at the Center = " + str(P(0)) + " Pa")

有没有办法在不分离每个条件的情况下绘制此函数?

1 个答案:

答案 0 :(得分:0)

Numpy有一个vectorize函数,可能就是你要找的东西。

pFunc = np.vectorize(P)
plt.plot(xr, pFunc(xr))

Vectorize本质上是 for 循环,因此不会加速你的代码。

如果您能够使用Pandas,那么我估计您也可以尝试使用apply功能:

import pandas as pd

xd = pd.Series(xr)

yr = xd.apply(lambda x: P(x))

plt.plot(xr, yr)

我相信您获得该特定错误的原因是因为您的条件实际上是在询问数组xr是否大于特定数字。数组中的一些项目,有些不是,所以结果是模棱两可的。错误消息是询问您是否希望问题是“是任何在xr中大于此数字”或“所有在xr中大于此数字”。

注意:您应该在第一个条件中返回np.nan而不是字符串。此外,函数integ.quad需要可调用的东西作为第一个参数。