I have four one dimensional lists: X1, Y1, X2, Y2.
X1 and Y1 each have 203 data points.
X2 and Y2 each have 1532 data points.
X1 and X2 are at different intervals, but both measure time.
I want to graph Y1 vs Y2.
I can plot just fine once I get the interpolated data, but can't think of how to interpolate data. I've thought and researched this a couple hours, and just can't figure it out. I don't mind a linear interpolation, but just can't figure out a way.
I think this is what you want:
import numpy as np
import matplotlib.pyplot as plt
# first data set
X1 = np.linspace(0,1,203)
Y1 = np.sin(X1)
# second data set
X2 = np.linspace(0, 0.5, 1532)
Y2 = np.cos(X2)
# get interpolated values of Y1 evaluated at X2
Y1_interp = np.interp(X2, X1, Y1)
# plot interpolated Y1 vs Y2
plt.plot(Y1_interp, Y2)
plt.show()
If you use matplotlib, you can just call plot(X1, Y1, 'bo', X2, Y2, 'r+'). Change the formatting as you'd like, but it can cope with different lengths just fine. You can provide more than two without any issue.
Related
I have various length of time series data. Therefore I need to normalize it to be the same length first.
For example data_1 has 200 points with this shape
data_2 has 7000 points with this shape
data_3 has 3000 points
I had checked this. It does not work with my pulse shape. I lost significant information
Question:
How can I upsample to 9000 points and preserve the shape of them?
Looks like numpy's interp function does what you want:
import numpy as np
import matplotlib.pyplot as plt
x1 = np.linspace(0, 1, 10)
y1 = np.sin(2 * np.pi * x1)
x2 = np.linspace(0, 1, 30)
y2 = np.interp(x2, x1, y1)
plt.plot(x1, y1)
plt.plot(x2, y2, '.')
plt.show()
I want to plot the unit sphere x^2 + y^2 + z^2 = 1 & I am trying to use sympy , numpy , and matplotlib for the same.
Below is a code snippet:
x,y = sp.symbols('x y')
def g(x,y):
return sqrt(1-x**2 - y**2)
xrange2 = np.linspace(-1, 1, 100)
yrange2 = np.linspace(-1, 1, 100)
X2, Y2 = np.meshgrid(xrange2, yrange2)
Z2 = g(X2, Y2)
Z2[(1- X2**2 - Y2**2 < 0)] = np.nan
Z2[(1- X2**2 - Y2**2 > 0)] = np.nan
ax.plot_surface(X2, Y2, Z2,cmap='Blues', antialiased=True, edgecolor='black')
I don't wish to use parametric equations for the sphere, but rather plot it using x , y and z.
Currently getting below error:
Z contains NaN values. This may result in rendering artifacts.
From the question it is very unclear which version of sqrt is used. Sympy's sqrt certainly won't work. math.sqrt doesn't work on arrays. Only np.sqrt can work. But then, function g needs to be numpy vectorized.
np.sqrt works on arrays, and gives NaN when operated on negative numbers.
ax.plot_surface doesn't want to draw colormapped faces when some of the Z values are NaN, it only draws plain colors in that case. Note that antialiasing doesn't work for plotting faces, only for edges.
To draw a complete sphere, both Z2 and -Z2 need to be drawn.
Due to the NaNs and an equation that doesn't define evenly distributed points, some artifacts will be present. Also, the surfaces will not completely fill up. See this post to draw a sphere via an angular representation.
from mpl_toolkits.mplot3d import Axes3D
import matplotlib.pyplot as plt
import numpy as np
#np.vectorize
def g(x,y):
return np.sqrt(1-x**2 - y**2)
fig = plt.figure()
ax = fig.gca(projection='3d')
xrange2 = np.linspace(-1, 1, 100)
yrange2 = np.linspace(-1, 1, 100)
X2, Y2 = np.meshgrid(xrange2, yrange2)
Z2 = g(X2, Y2)
ax.plot_surface(X2, Y2, -Z2, color='lightblue', antialiased=True, edgecolor='black')
ax.plot_surface(X2, Y2, Z2, color='lightblue', antialiased=True, edgecolor='black')
plt.show()
PS: Note that you are not really using sympy in the code (def g(x,y) uses its own version of standard Python variables x and y). Also, mixing numpy and sympy doesn't work. This related post handles plotting a surface as parametric surface via sympy. Note that these parametric surfaces only work for 2 variables, in this case x, y and z are defined in function of phi and theta. As far as I am aware, plotting a general 3D equation doesn't work with sympy at the moment.
I have an arbitrary, large number (50-1000) of lists, representing X and Y coordinates, I'd like to plot them in one figure.
The lists are of different length, usually 100-1000 elements each. I get the lists as pairs of x and y coordinates (see example), but could easily convert them to 2xN arrays. They need to be plotted in order, from first to the last element. Each line separately.
Is there a way to pack all my lists to one (or two; x and y) object that matplotlib can read?
This example gives the wanted output but is unhandy when there is a lot of data.
I'm happy for a solution that takes advantage of numpy.
from matplotlib import pyplot as plt
fig, ax = plt.subplots(1,1)
x1 = [1,2,5] # usually much longer and a larger number of lists
y1 = [3,2,4]
x2 = [1,6,5,3]
y2 = [7,6,3,2]
x3 = [4]
y3 = [4]
for x, y, in zip([x1, x2, x3],[y1, y2, y3]):
ax.plot(x,y, 'k.-')
plt.show()
I would prefer something like this:
# f() is the function i need, to formats the data for plotting
X = f(x1, x2, x3)
Y = f(y1, y2, y3)
#... so that I can do some processing of the arrays X, and Y here.
ax.plot(X, Y, 'k.-')
You can use a LineCollection for that. Unfortunately, if you want to have markers in your lines, LineCollection does not support that, so you would need to do some trick like adding a scatter plot on top (see Adding line markers when using LineCollection).
from matplotlib import pyplot as plt
from matplotlib.collections import LineCollection
fig, ax = plt.subplots(1,1)
x1 = [1,2,5]
y1 = [3,2,4]
x2 = [1,6,5,3]
y2 = [7,6,3,2]
x3 = [4]
y3 = [4]
# Add lines
X = [x1, x2, x3]
Y = [y1, y2, y3]
lines = LineCollection((list(zip(x, y)) for x, y in zip(X, Y)),
colors='k', linestyles='-')
ax.add_collection(lines)
# Add markers
ax.scatter([x for xs in X for x in xs], [y for ys in Y for y in ys], c='k', marker='.')
# If you do not use the scatter plot you need to manually autoscale,
# as adding the line collection will not do it for you
ax.autoscale()
plt.show()
If you are working with arrays, you may also do as follows:
import numpy as np
# ...
X = [x1, x2, x3]
Y = [y1, y2, y3]
lines = LineCollection((np.stack([x, y], axis=1) for x, y in zip(X, Y)),
colors='k', linestyles='-')
ax.add_collection(lines)
ax.scatter(np.concatenate(X), np.concatenate(Y), c='k', marker='.')
I'm looking for the correct data structure to use for the following. I want to plot a line between two points, for a multiple set of points.
For example, to plot a line between (-1, 1) and (12, 4) I do this:
import numpy as np
import matplotlib.pyplot as plt
fig, ax = plt.subplots(1,1)
x1 = [-1, 12]
y1 = [1, 4]
ax.plot( x1, y1 )
plt.show()
If I want to plot another line connecting two different points (unrelated to the first set of points) I do this:
x2 = [1, 10]
y2 = [3, 2]
ax.plot( x1, y1, x2, y2 )
plot.show()
How do I extend this? That is, what data structure should I use to represent a growing array of such points [x1, y1, x2, y2, ...] generated by my input data?
I have tried the following,
points = [x1, y1, x2, y2]
ax.plot( points )
But the plot ends up connecting all of the individual lines with lines I do not want.
You are close:
ax.plot(*points)
The asterisk operator * converts an iterable (the list in your case) into a sequence of function parameters.
I'm trying to draw a Taylor series sin(x) graph using python with Jupyter notebook. I created a short function. The graph will appear correctly until y2, but it will fail at y3. It is difficult to draw a graph with a value of x = 2.7 in y3. I don't know how to fix y3.
This is my code:
import numpy as np
import matplotlib.pyplot as plt
import numpy as np
def f(x) :
result = x - x**3/6 + x**5/120
return result
x = np.linspace(0.0, 7.0, 100)
y = np.sin(x)
y2 = x - x**3/6 + x**5/120
y3 = f(2.7)
plt.title("taylor sin graph")
plt.xlim(0, 7+0.2)
plt.ylim(-5, 5+1)
plt.plot(x, y, label='sin(x)')
plt.plot(x, y2, label='x=0')
plt.plot(x, y3, label='x=2.7')
plt.legend()
plt.show()
I want to add y3 here:
After your comment, it got clarified that you do not need a single point but a horizontal line. In that case you can simply input an x-mesh which has the same value 2.7.
To do so, you first define an array containing values 2.7 by using np.ones(100) * 2.7 and then just pass it to the function.
y3 = f(2.7*np.ones(100))
plt.plot(x, y3, label='x=2.7')
For plotting a single point at x=2.7, there are two ways (among possible others).
First option is to just specify the two x-y numbers and plot using a marker as
plt.plot(2.7, y3, 'bo', label='x=2.7')
Second option is to use plt.scatter. s=60 is just to have a big marker.
plt.scatter(2.7, y3, s=60, label='x=2.7')
import numpy as np
import matplotlib.pyplot as plt
import numpy as np
def f(x) :
result = x - x**3/6 + x**5/120
return result
x = np.linspace(0.0, 7.0, 100)
y = np.sin(x)
y2 = x - x**3/6 + x**5/120
y3 = f(2.7)
plt.title("taylor sin graph")
plt.xlim(0, 7+0.2)
plt.ylim(-5, 5+1)
plt.plot(x, y, label='sin(x)')
plt.plot(x, y2, label='x=0')
plt.plot(2.7, y3, label='x=2.7', marker=11)
plt.legend()
plt.show()
You have to add point - not an array in x-axis and scalar on y-axis.
I think
plt.plot([2.7], [y3], '-o', label='x=2.7')
would work. You can't plot(x,y3) when x is a linspace and y3 is just one number.
Also, Taylor approximation of sin function works only in the interval (-pi, pi).