Plotting sympy.Max yields TypeError - python

I am trying to generate a 3-dimensional plot for a function involving sympy.Max, but I am getting a type-error.
Minimum example:
import sympy
u, v = sympy.symbols("u v", positive=True)
f = sympy.Max(0, u*v - 0.5)
my_plot = sympy.plotting.plot3d(f, (u, 0, 1), (v, 0, 1), show=False, legend=True)
my_plot.show()
The code runs fine if I remove the -0.5 for example, so it really seems to be about taking the maximum. Any ideas how to fix this?
Full stack trace:
Traceback (most recent call last):
File "/Users/marcusrockel/Documents/projects/copulas_in_systemic_risk/venv/lib/python3.9/site-packages/sympy/plotting/experimental_lambdify.py", line 131, in __call__
results = self.vector_func(*temp_args)
File "/Users/marcusrockel/Documents/projects/copulas_in_systemic_risk/venv/lib/python3.9/site-packages/sympy/plotting/experimental_lambdify.py", line 272, in __call__
return self.lambda_func(*args, **kwargs)
File "<string>", line 1, in <lambda>
File "<__array_function__ internals>", line 180, in amax
File "/Users/marcusrockel/Documents/projects/copulas_in_systemic_risk/venv/lib/python3.9/site-packages/numpy/core/fromnumeric.py", line 2793, in amax
return _wrapreduction(a, np.maximum, 'max', axis, None, out,
File "/Users/marcusrockel/Documents/projects/copulas_in_systemic_risk/venv/lib/python3.9/site-packages/numpy/core/fromnumeric.py", line 86, in _wrapreduction
return ufunc.reduce(obj, axis, dtype, out, **passkwargs)
TypeError: only integer scalar arrays can be converted to a scalar index
I am using Python 3.9 and sympy 1.11.1.

That's unfortunate: it is a limitation of the current plotting module, which is using experimental_lambdify which is quite old.
Two solutions:
you lambdify your expression, and manually plot it with matplotlib.
from sympy import *
import numpy as np
import matplotlib.pyplot as plt
u, v = symbols("u v", positive=True)
expr = Max(0, u*v - 0.5)
f = np.vectorize(lambdify([u, v], expr))
uu, vv = np.mgrid[0:1:50j, 0:1:50j]
zz = f(uu, vv)
fig = plt.figure()
ax = fig.add_subplot(projection="3d")
ax.plot_surface(uu, vv, zz)
ax.set_xlabel("u")
ax.set_ylabel("v")
plt.show()
take a look at this plotting module, which uses lambdify and it is able to plot it:
from sympy import *
from spb import *
u, v = symbols("u v", positive=True)
expr = Max(0, u*v - 0.5)
plot3d(expr, (u, 0, 1), (v, 0, 1))

Related

"Could not broadcast input array" in system of stiff odes inside a loop

I'm trying to solve a system of stiff odes which describes a catalytic heterogeneous reaction. I want to solve this equations for different temperatures, so I'm using a for loop.
import scipy as sc
from scipy.integrate import odeint, solve_ivp
import numpy as np
import matplotlib.pyplot as plt
T=np.array([250,300,350,400,450,500])
for y in T:
y=T
def f(t,x,T=y,tfirst=True):
FA,FB,FC,FD,FE,FF=x
e=2.711828
R=8.314
Tm=723.15
A1=5.5
A2=0.686
A3=1.58
A4=2.6
A5=0.787
E1=90500
E2=165000
E3=150000
E4=139000
E5=132000
SB=-215
HB=-45600
SD=-42
HD=-128000
DH1=-105000
DH2=-1428000
DH3=-862000
DH4=-1323000
DH5=-757000
k1=e**(A1-(E1/R)*((1/T)-(1/Tm)))
k2=e**(A2-(E2/R)*((1/T)-(1/Tm)))
k3=e**(A3-(E3/R)*((1/T)-(1/Tm)))
k4=e**(A4-(E4/R)*((1/T)-(1/Tm)))
k5=e**(A5-(E5/R)*((1/T)-(1/Tm)))
KB=6.54e-12
KD=1.19
m2=0.922
m3=0.906
m4=1.23
m5=0.905
Patm=0.8*101325
FT=178.47
PA=(FA/FT)*Patm
PB=(FB/FT)*Patm
PC=(FC/FT)*Patm
PD=(FD/FT)*Patm
PE=(FE/FT)*Patm
PF=(FF/FT)*Patm
Tast=1/(1+((KB*PB)**0.5)+(KD*PD))
TB=((KB*PB)**0.5)*Tast
TD=KD*PD*Tast
r1=(k1/1000)*TB*PA #mol
r2=(k2/1000)*(TB**m2)*PA
r3=(k3/1000)*(TB**m3)*PA
r4=(k4/1000)*(TB**m4)*PC
r5=(k5/1000)*(TB**m5)*PC
rA=-r1-r2-r3
rB=-r1-7*r2-5*r3-6*r4-4*r5
rC=r1-r4-r5
rD=r1+3*r2+3*r3+2*r4+2*r5
rE=2*r2+2*r4
rF=2*r3+2*r5
FAdot=rA
FBdot=rB
FCdot=rC
FDdot=rD
FEdot=rE
FFdot=rF
return [FAdot,FBdot,FCdot,FDdot,FEdot,FFdot]
x0=(5,5,0,0,0,0)
t0=0
t1=40
soln=solve_ivp(f,(t0,t1),x0,method="Radau",args=(T,))
print(soln.y)
I get the following error:
c:\Users\Axel Flores\Documents\Escuela\Proyectos\Python\import scipy as sc.py:51: RuntimeWarning: invalid value encountered in sqrt
Tast=1/(1+((KB*PB)**0.5)+(KD*PD))
c:\Users\Axel Flores\Documents\Escuela\Proyectos\Python\import scipy as sc.py:52: RuntimeWarning: invalid value encountered in sqrt
TB=((KB*PB)**0.5)*Tast
Traceback (most recent call last):
File "c:\Users\Axel Flores\Documents\Escuela\Proyectos\Python\import scipy as sc.py", line 75, in <module>
soln=solve_ivp(f,(t0,t1),x0,method="Radau",args=(T,))
File "C:\Users\Axel Flores\AppData\Local\Programs\Python\Python310\lib\site-packages\scipy\integrate\_ivp\ivp.py", line 546, in solve_ivp
solver = method(fun, t0, y0, tf, vectorized=vectorized, **options)
File "C:\Users\Axel Flores\AppData\Local\Programs\Python\Python310\lib\site-packages\scipy\integrate\_ivp\radau.py", line 310, in __init__
self.jac, self.J = self._validate_jac(jac, jac_sparsity)
File "C:\Users\Axel Flores\AppData\Local\Programs\Python\Python310\lib\site-packages\scipy\integrate\_ivp\radau.py", line 356, in _validate_jac
J = jac_wrapped(t0, y0, self.f)
File "C:\Users\Axel Flores\AppData\Local\Programs\Python\Python310\lib\site-packages\scipy\integrate\_ivp\radau.py", line 352, in jac_wrapped
J, self.jac_factor = num_jac(self.fun_vectorized, t, y, f,
File "C:\Users\Axel Flores\AppData\Local\Programs\Python\Python310\lib\site-packages\scipy\integrate\_ivp\common.py", line 316, in num_jac
return _dense_num_jac(fun, t, y, f, h, factor, y_scale)
File "C:\Users\Axel Flores\AppData\Local\Programs\Python\Python310\lib\site-packages\scipy\integrate\_ivp\common.py", line 326, in _dense_num_jac
f_new = fun(t, y[:, None] + h_vecs)
File "C:\Users\Axel Flores\AppData\Local\Programs\Python\Python310\lib\site-packages\scipy\integrate\_ivp\base.py", line 133, in fun_vectorized
f[:, i] = self._fun(t, yi)
ValueError: could not broadcast input array from shape (6,6) into shape (6,)
PS C:\Users\Axel Flores>
Anyone could help?
I believe the error is related to the for loop. But everything that I've tried hasn't worked.
Take a hard look on the effect of
for y in T:
y=T
def f(t,x,T=y,tfirst=True):
and how that introduces the extra dimension of size 6.

matplotlib triplot and tricontourf

I'm attempting to plot a 2D dataset having unstructured coordinates in matplotlib using tricontourf. I'm able to generate a plot of the 'mesh' with triplot, however when I use the same Triangulation object for tricontourf, I get an error (see below). What am I missing? Example:
#!/usr/bin/env python3
# -*- coding: utf-8 -*-
import numpy as np
import matplotlib as mpl
import matplotlib.pyplot as plt
def lower(x):
return 2 + 1*x
def upper(x):
return 60 + 4*x
ni = 10
nj = 12
x = np.linspace(1,15,ni)
## make a trapezoid
xy = np.zeros((ni,nj,2),dtype=np.float32)
for i in range(len(x)):
y = np.linspace(lower(x[i]),upper(x[i]),nj)
xy[i,:,0] = x[i]
xy[i,:,1] = y
## add noise
xy += -0.1 + 0.2*np.random.rand(ni,nj,2)
## make tris 'indices list'
xi, yi = np.meshgrid(range(ni), range(nj), indexing='xy')
inds_list = np.stack((xi,yi), axis=2)
inds_list = np.reshape(inds_list, (ni*nj,2), order='C')
inds_list = np.ravel_multi_index((inds_list[:,0],inds_list[:,1]), (ni,nj), order='C')
inds_list = np.reshape(inds_list, (ni,nj), order='F')
tris = np.zeros((2*(ni-1)*(nj-1),3), dtype=np.int64)
ci=0
for i in range(ni-1):
for j in range(nj-1):
tris[ci,0] = inds_list[i+1, j+1]
tris[ci,1] = inds_list[i, j+1]
tris[ci,2] = inds_list[i, j ]
ci+=1
tris[ci,0] = inds_list[i, j ]
tris[ci,1] = inds_list[i+1, j ]
tris[ci,2] = inds_list[i+1, j+1]
ci+=1
triangulation = mpl.tri.Triangulation(x=xy[:,:,0].ravel(), y=xy[:,:,1].ravel(), triangles=tris)
fig1 = plt.figure(figsize=(4, 4/(16/9)), dpi=300)
ax1 = plt.gca()
ax1.triplot(triangulation, lw=0.5)
#ax1.tricontourf(triangulation)
fig1.tight_layout(pad=0.25)
plt.show()
...produces
however, uncommenting the line with ax1.tricontourf
throws the error:
Traceback (most recent call last):
File "test.py", line 54, in <module>
ax1.tricontourf(triangulation)
File "C:\Users\steve\AppData\Roaming\Python\Python38\site-packages\matplotlib\tri\tricontour.py", line 307, in tricontourf
return TriContourSet(ax, *args, **kwargs)
File "C:\Users\steve\AppData\Roaming\Python\Python38\site-packages\matplotlib\tri\tricontour.py", line 29, in __init__
super().__init__(ax, *args, **kwargs)
File "C:\Users\steve\AppData\Roaming\Python\Python38\site-packages\matplotlib\contour.py", line 812, in __init__
kwargs = self._process_args(*args, **kwargs)
File "C:\Users\steve\AppData\Roaming\Python\Python38\site-packages\matplotlib\tri\tricontour.py", line 45, in _process_args
tri, z = self._contour_args(args, kwargs)
File "C:\Users\steve\AppData\Roaming\Python\Python38\site-packages\matplotlib\tri\tricontour.py", line 60, in _contour_args
z = np.ma.asarray(args[0])
IndexError: list index out of range
I am using:
Python version: 3.8.9
matplotlib version: 3.5.1
I would say you need to provide the array of values to contour, e.g.:
x= xy[:,:,0].ravel()
z= np.random.rand(x.shape[0])
ax1.tricontourf(triangulation, z)

Only size-1 arrays can be converted to Python scalars: Integrate.quad Vs Integrate.quadrature

I'm trying to calculate an integral. When I use the function scipy.integrate.quad the code works perfectly. However, when I use scipy.integrate.quadrature (I need to use this or the fixed.quad methods) it returns "only size-1 arrays can be converted to Python scalars" error. What should I do?
My code
import cmath as c
import math as m
import numpy as np
import scipy as sp
import os
import csv
import time
import scipy.integrate as integrate
from scipy import special
k = 0.1
def solnum(x, chi, y):
Bk = ((2*abs(k))**(3/2))*((1+(1.5*abs(k))))*(m.gamma((1/(2*abs(k)))+(3/4))/m.gamma((1/(2*abs(k)))-(3/4)))
C = (chi/(2*m.sqrt(m.pi)))
R1 = (1/(1+(y**2)))
R2 = (((k**2)*(-((chi**2)*((x-y)**2))/4))-(m.sqrt(1+((k**2)*(-((chi**2)*((x-y)**2))/4)**2))))/(k**2 - 1)
R3 = ((((m.sqrt(1+((k**2)*(-((chi**2)*((x-y)**2))/4)**2)))) + ((k*(-((chi**2)*((x-y)**2))/4))))**(1/k))
sn = (C*Bk*R1*R2*R3)
return sn
def g(x, chi):
f1 = lambda y: solnum(x, chi, y)
f2 = integrate.quadrature(f1,-200,200)
return f2[0]
print(g(0.,0.05)) #for instance
The error message:
Traceback (most recent call last):
File "c:/Users/pwadmin/Google Drive/Pós-Doc/Py2/Completão/cacete de agulha.py", line 34, in <module>
print(g(0.,0.05))
File "c:/Users/pwadmin/Google Drive/Pós-Doc/Py2/Completão/cacete de agulha.py", line 32, in g
f2 = integrate.quadrature(f1,-200,200)
File "C:\ProgramData\Anaconda3\lib\site-packages\scipy\integrate\_quadrature.py", line 238, in quadrature
newval = fixed_quad(vfunc, a, b, (), n)[0]
File "C:\ProgramData\Anaconda3\lib\site-packages\scipy\integrate\_quadrature.py", line 119, in fixed_quad
return (b-a)/2.0 * np.sum(w*func(y, *args), axis=-1), None
File "C:\ProgramData\Anaconda3\lib\site-packages\scipy\integrate\_quadrature.py", line 149, in vfunc
return func(x, *args)
File "c:/Users/pwadmin/Google Drive/Pós-Doc/Py2/Completão/cacete de agulha.py", line 31, in <lambda>
f1 = lambda y: solnum(y, x, chi)
File "c:/Users/pwadmin/Google Drive/Pós-Doc/Py2/Completão/cacete de agulha.py", line 22, in solnum
R2 = (((k**2)*(-((chi**2)*((x-y)**2))/4))-(m.sqrt(1+((k**2)*(-((chi**2)*((x-y)**2))/4)**2))))/(k**2 - 1)
TypeError: only size-1 arrays can be converted to Python scalars

Using Polyfit to create 3rd degree polynomial with dynamic CSV's

What the data look like although I may end up with more than just three columns:
TotalArea,Pressure,Intensity
12054.2,-0.067,39.579
11980.2,-0.061,41.011
11948,-0.055,42.08
11889.5,-0.04,45.732
11863.6,-0.03,50.573
My goal: I would like to take this CSV file and create A polynomial that will fit the column labeled Intensity and TotalArea.
My code (omitting anything I believe to be purely decorative):
Graph = pd.read_csv("C:Data.csv")
Pl = Graph.dropna()
Bottom = Pl["TotalArea"]
Right = Pl["Intensity"]
arr = Pl.values
x = Bottom
y2 = Right
fig = plt.figure()
ax1 = fig.add_subplot(1, 1, 1)
xx = arr[:, [0]]
b = xx.ravel()
print(b)
yy = arr[:, [2]]
c = xx.ravel()
y3 = np.polyfit(b, c, 3)
ax2 = ax1.twinx()
ax2.plot(x, y2, color = "r", label='Intensity /Area')
plt.show()
My error: (has to do with polyfit values)
Traceback (most recent call last):
File "/mnt/WinPartition/Users/tomchi/Documents/Programming/Eclipse/PythonDevFiles/so_test.py", line 47, in <module>
ax2.plot(x, y3)
File "/usr/local/lib/python3.5/dist-packages/matplotlib/__init__.py", line 1855, in inner
return func(ax, *args, **kwargs)
File "/usr/local/lib/python3.5/dist-packages/matplotlib/axes/_axes.py", line 1527, in plot
for line in self._get_lines(*args, **kwargs):
File "/usr/local/lib/python3.5/dist-packages/matplotlib/axes/_base.py", line 406, in _grab_next_args
for seg in self._plot_args(this, kwargs):
File "/usr/local/lib/python3.5/dist-packages/matplotlib/axes/_base.py", line 383, in _plot_args
x, y = self._xy_from_xy(x, y)
File "/usr/local/lib/python3.5/dist-packages/matplotlib/axes/_base.py", line 242, in _xy_from_xy
"have shapes {} and {}".format(x.shape, y.shape))
ValueError: x and y must have same first dimension, but have shapes (310,) and (2,)
So, my question is: What exactly does this mean? Is it due to pandas dataframe? Can I solve this in a quick manner? Can I be of any more assistance?
I realise now that polyfit just gives me the coefficients to my polynomial
[ -2.27230868e-23 2.74362531e-19 1.00000000e+00 -1.90568829e-12]

Unpacking error within numerical integration in python

Here is my code snippet to draw an integral function by NumPy, SciPy and MatPlotLib libraries:
import numpy as np
from scipy.integrate import quad
import matplotlib.pyplot as plt
sigma = 1
def integrand(x,n):
return (n/(2*sigma*np.sqrt(np.pi)))*np.exp(-(n**2*x**2)/(4*sigma**2))
tt = np.linspace(0, 20, 0.01)
nn = np.linspace(1, 100, 1)
T = np.zeros_like([len(tt), len(nn)])
for i,t in enumerate(tt):
for j,n in enumerate(nn):
T[i,j] = quad(integrand, -oo, t, args = (x))
plt.pcolormesh(tt,nn,T)
But there is a ValueError as below about a unpacking-related issue:
Traceback (most recent call last):
File "C:\Program Files\Microsoft Visual Studio 12.0\Common7\IDE\Extensions\Microsoft\Python Tools for Visual Studio\2.1\visualstudio_py_util.py", line 106, in exec_file exec_code(code, file, global_variables)
File "C:\Program Files\Microsoft Visual Studio 12.0\Common7\IDE\Extensions\Microsoft\Python Tools for Visual Studio\2.1\visualstudio_py_util.py", line 82, in exec_code exec(code_obj, global_variables)
File "C:\Users\Matinking\documents\visual studio 2013\Projects\NeuroSimulation\NeuroSimulation\XSundry\test2.py", line 63, in <module>
plt.pcolormesh(tt,nn,T)
File "C:\Python34\lib\site-packages\matplotlib\pyplot.py", line 2946, in pcolormesh
ret = ax.pcolormesh(*args, **kwargs)
File "C:\Python34\lib\site-packages\matplotlib\axes.py", line 7747, in pcolormesh
X, Y, C = self._pcolorargs('pcolormesh', *args, allmatch=allmatch)
File "C:\Python34\lib\site-packages\matplotlib\axes.py", line 7357, in _pcolorargs
numRows, numCols = C.shape
ValueError: need more than 1 value to unpack
Press any key to continue . . .
The issue is seemingly related to the last line of the code, but I can'y figure any solution out for that...
Could you please enlightening me upon this case?
Kind regards
import numpy as np
from scipy.integrate import quad
import matplotlib.pyplot as plt
sigma = 1
def integrand(x, n):
return (n/(2*sigma*np.sqrt(np.pi)))*np.exp(-(n**2*x**2)/(4*sigma**2))
tt = np.linspace(0, 19, 20) # divides range 0 to 19 into 20 equal size portions. Thus, tt = [0, 1, 2, ..., 19]
nn = np.linspace(1, 100, 100) # nn = [1, 2, ..., 100]
T = np.zeros([len(tt), len(nn)])
for i,t in enumerate(tt):
for j,n in enumerate(nn):
T[i, j], _ = quad(integrand, -np.inf, t, args=(n,)) # evaluate integral from -infinity to t, with value of n in the function set to n passed in from here.
x, y = np.mgrid[0:20:1, 1:101:1] # create a mesh/grid for plotting.
plt.pcolormesh(x, y, T) #plot
plt.show()

Categories