I have a sympy function, I want to plot it and color the area beneath the curve, how can I do it?
Code
import sympy as sy
x = sy.symbols('x')
f = sy.sin(x)
sy.plot(f, (x, 0, sy.pi))
Plot
i have created the same output without using matplotlib directly(sympy already uses sympy)
import sympy as sy
import numpy as np
from sympy.plotting import plot
x = sy.symbols('x')
f = sy.sin(x)
x_array = np.linspace(0, np.pi, 1000)
f_array = sy.lambdify(x, f)(x_array)
plot(f, (x, 0, sy.pi), fill={'x': x_array,'y1':f_array,'color':'green'})
i got the output
You can use plt.fill_between (documentation) but you need to convert your sympy function in a numpy array with sy.lambdify (documentation) before, because plt.fill_between takes in arrays.
Check this code as a reference:
import sympy as sy
import numpy as np
import matplotlib.pyplot as plt
x = sy.symbols('x')
f = sy.sin(x)
x_array = np.linspace(0, np.pi, 1000)
f_array = sy.lambdify(x, f)(x_array)
fig, ax = plt.subplots()
ax.plot(x_array, f_array, color = 'red')
ax.fill_between(x_array, f_array, facecolor = 'red', alpha = 0.3)
plt.show()
Related
I want to adjust colobar scale from my current figure1 to the desired figure2 !!
My colorbar scale range is -1 to 1, but I want it in exponential form and for that I tried levels = np.linspace(-100e-2,100e-2) as well, but it also doesn't give the desired scale2
import xarray as xr
import numpy as np
import matplotlib.pyplot as plt
ds = xr.open_dataset('PL_Era_Tkt.nc')
wp = ds.w.mean(dim=['longitude','latitude']).plot.contourf(x='time',cmap='RdBu',add_colorbar=False,extend='both')
wpcb = plt.colorbar(wp)
wpcb.set_label(label='Pa.s${^{-1}}$',size=13)
plt.gca().invert_yaxis()
plt.title('Vertical Velocity',size=15)
My current scale
My desired scale
Since the data is not presented, I added normalized color bars with the data from the graph sample here. I think the color bar scales will also be in log format with this setup. Please note that the data used is not large, so I have not been able to confirm this.
%matplotlib inline
import matplotlib.pyplot as plt
import matplotlib as mpl
import matplotlib.ticker as ticker
import numpy as np
plt.style.use('seaborn-white')
def f(x, y):
return np.sin(x) ** 10 + np.cos(10 + y * x) * np.cos(x)
x = np.linspace(0, 5, 50)
y = np.linspace(0, 5, 40)
X, Y = np.meshgrid(x, y)
Z = f(X, Y)
fig, ax = plt.subplots()
ax.contourf(X, Y, Z, 20, cmap='RdGy')
cmap = mpl.cm.RdGy
norm = mpl.colors.Normalize(vmin=-1, vmax=1.0)
fig.colorbar(mpl.cm.ScalarMappable(norm=norm, cmap=cmap),
ax=ax, orientation='vertical', label='Some Units', extend='both', ticks=ticker.LogLocator())
plt.show()
Please help with the problem of paraboloid 3d plotting using from the elements in an array.
Below code gives a nice parabolid:
from matplotlib import *
from mpl_toolkits.mplot3d import Axes3D
import matplotlib.pyplot as plt
import numpy as np
from pylab import *
import math
fig = plt.figure()
ax = fig.add_subplot(111, projection='3d')
a=2
t = np.arange(0, 1, 0.01)
th = np.arange(0, 2*pi, 0.01)
t,th = np.meshgrid(r, T)
#Parametrise it
X = r*cos(T)
Y = r*sin(T)
Z = a*r**2
ax.plot_surface(X, Y, Z, alpha=0.9, rstride=10, cstride=10, linewidth=0.5, cmap=cm.summer)
plt.show()
But I want something like this:
th,t,a = symbols('th t a')
rotz=np.matrix([[cos(th),-sin(th),0,0],
[sin(th),cos(th),0,0],
[0,0,1,0],
[0,0,0,1]])
g=np.matrix([t,0,a*(t**2),1])
g=np.transpose(g)
M = rotz*g
print(M)
Now M is a 4x1 matrix with the 1st three elements to parametrize the paraboloid code
[[t*cos(th)]
[t*sin(th)]
[a*t**2]
[1]]
Now I want to use the x=M[0,:],y=M[1,:],z=M[2,:] and replace it in the parabolid code and plot the paraboloid.
I want this way so that I could do some transformation to the matrix as needed.
I'm trying to plot the following multivariable f(x,y)=sqrt(2x-y)
but can't make it work with numpy and matplotlib.
I've been trying by defining function but still cant makee it work
from numpy import exp,arange
from pylab import meshgrid,cm,imshow,contour,clabel,colorbar,axis,title,show
from math import sqrt
# the function that I'm going to plot
def z_func(x,y):
return (sqrt(2*x - y))
X,Y = meshgrid(x, y) # grid of point
Z = z_func(X, Y) # evaluation of the function on the grid
im = imshow(Z,cmap=cm.RdBu) # drawing the function
# adding the Contour lines with labels
cset = contour(Z,arange(-1,1.5,0.2),linewidths=2,cmap=cm.Set2)
clabel(cset,inline=True,fmt='%1.1f',fontsize=10)
colorbar(im) # adding the colobar on the right
# latex fashion title
title('my plot')
show()
You need to have more data in order to plot the entire function.
Look at the following code as a reference
import numpy as np
import math
import matplotlib.pyplot as plt
def z_func(x,y):
return (math.sqrt(2*x - y))
x = [10,20,30,40,50]
y =[2,4,6,8,11]
Z = []
for i in range(len(x)):
Z.append(z_func(x[i],y[i]))
plt.plot(Z)
from mpl_toolkits.mplot3d import Axes3D
import matplotlib.pyplot as plt
from matplotlib import cm
import numpy as np
# the function that I'm going to plot.
# Vectorize so we don't need to loop through
# grid points.
#np.vectorize
def z_func(x, y):
return (np.sqrt(2*x - y))
# define the range where you evaluate
# the function
extent = (0, 10, 0, 10)
x = np.arange(0, 10.1, .1)
y = np.arange(0, 10.1, .1)
# create grid
X, Y = np.meshgrid(x, y)
# evaluate over grid
Z = z_func(X, Y)
# plot contour image
fig = plt.figure()
im = plt.imshow(Z, origin='image', cmap=cm.RdBu, extent=extent)
cset = plt.contour(Z, np.arange(-1,1.5,0.2),linewidths=2,cmap=cm.Set2, extent=extent)
plt.clabel(cset,inline=True, fmt='%1.1f',fontsize=10)
plt.colorbar(im)
plt.show()
I can draw a circle by scatter, which has been shown in the image. But I want to draw them buy a line, because there are many circles in total, I need to link nodes together for a certain circle. Thanks.
I the order of the points is random, you can change X-Y to polar, and sort the data by angle:
create some random order points first:
import pylab as pl
import numpy as np
angle = np.arange(0, np.pi*2, 0.05)
r = 50 + np.random.normal(0, 2, angle.shape)
x = r * np.cos(angle)
y = r * np.sin(angle)
idx = np.random.permutation(angle.shape[0])
x = x[idx]
y = y[idx]
Then use arctan2() to calculate the angle, and sort the data by it:
angle = np.arctan2(x, y)
order = np.argsort(angle)
x = x[order]
y = y[order]
fig, ax = pl.subplots()
ax.set_aspect(1.0)
x2 = np.r_[x, x[0]]
y2 = np.r_[y, y[0]]
ax.plot(x, y, "o")
ax.plot(x2, y2, "r", lw=2)
here is the output:
Here is one way to do it. This answer uses different methods than the linked possible duplicate, so may be worth keeping.
import matplotlib.pyplot as plt
from matplotlib import patches
fig = plt.figure(figsize=plt.figaspect(1.0))
ax = fig.add_subplot(111)
cen = (2.0,1.0); r = 3.0
circle = patches.Circle(cen, r, facecolor='none')
ax.add_patch(circle)
ax.set_xlim(-6.0, 6.0)
ax.set_ylim(-6.0, 6.0)
If all you have are the x and y points, you can use PathPatch. Here's a tutorial
If your data points are already in order, the plot command should work fine. If you're looking to generate a circle from scratch, you can use a parametric equation.
>>> import numpy as np
>>> import matplotlib.pyplot as plt
>>> t = np.linspace(0,2*np.pi, 100)
>>> x = np.cos(t)
>>> y = np.sin(t)
>>> plt.plot(x,y)
I have a .txt file with values
x1 y1 z1
x2 y2 z2
etc.
With my previous little experience I was trying to draw a contourf, with this code
import numpy as np
import matplotlib
from matplotlib import rc
import matplotlib.mlab as ml
from pylab import *
rc('font', family='serif')
rc('font', serif='Times New Roman')
rc('font', size='9')
rc('text', usetex=True)
from matplotlib.mlab import griddata
import matplotlib.pyplot as plt
import numpy.ma as ma
from numpy.random import uniform
from matplotlib.colors import LogNorm
matplotlib.use('pgf')
fig = plt.figure()
data = np.genfromtxt('Velocidad.txt')
matplotlib.rcParams['xtick.direction'] = 'out'
matplotlib.rcParams['ytick.direction'] = 'out'
rc('text', usetex=True)
rc('font', family='serif')
x = data[:,0]
y = data[:,1]
z = data[:,2]
xi = np.linspace(0,3000.0, 400)
yi = np.linspace(0,4.0, 200)
zi = griddata(x,y,z,xi,yi,interp='nn')
CS = plt.contourf(xi,yi,zi,200,cmap=plt.cm.jet,rasterized=True)
plt.colorbar()
plt.xlim(0,3000)
plt.ylim(0,4.0)
plt.ylabel(r'$t$')
plt.xlabel(r'$x$')
plt.title(r' Contour de $v(x,t)$')
plt.savefig("CampoVel.png", dpi=100)
plt.show()
the problem is the output:
When I see this picture and I look at the data (which is here, in this link) and I don't understand those discontinuities in x=750 and x=1875. And those strange vertical lines all over the plot. Looking at the data I would expect something smooth, at least in those positions, but the output obviously isn't. Is this a problem of griddata()? How can I solve it?
I have been told that as my data is regularly spaced on X and Y, I shouldn't use griddata(), but I have looked examples and I can't get the code to work.
If you simply reshape your data after loading it and skip the griddata thing, doing this:
data = data.reshape(81, 201, 3)
x = data[...,0]
y = data[...,1]
z = data[...,2]
CS = plt.contourf(x,y,z,200,cmap=plt.cm.jet,rasterized=True)
plt.colorbar()
plt.show()
You get this: