I have some data I want to plot, x and y is in the same format as this small piece of example code.
import matplotlib.pyplot as plt
y = [1,1,3,4]
x = [1,4,2,3]
plt.plot(x,y,'-o')
plt.show()
This results in quite a weird graph.
What pyplot does is drawing a line from the first point inserted to the second, then to the third etc.
I want it to draw a line from low-x to high-x, but I can seem to find a nice way to do this. I want my line to be like this.
What is the easiest way to achieve this, given my x and y data is in the same format but more complex than this example?
To get the graph as you mentioned, you need to have values in x in sorted order, which you can achieve like this:
z = sorted(zip(x,y))
x=[i[0] for i in z]
y=[i[1] for i in z]
and now using x and y for ploting (not tested).
you can sort your x list with simultaneously changing the y,
import matplotlib.pyplot as plt
y = [1,1,3,4]
x = [1,4,2,3]
for i in range(len(x)):
for k in range( len( x ) - 1, i, -1 ):
if ( x[k] < x[k - 1] ):
x[k-1],x[k]=x[k],x[k-1]
y[k-1],y[k]= y[k],y[k-1]
print x,y
plt.plot(x,y,'-o')
plt.show()
Related
I want to make a self-avoiding 2D random walk in python. Imagine it like the dot is on the square grid and it can only go up, down, left or right but it cannot land twice on the same point. I have an idea how to do it, but my programming skills aren't very good (I'm a beginner) and the code doesn't work.
The end product should look something like this:
enter image description here
My idea was to create two lists: one where I store x and y (i.e. the coordinates I've already been to) and one with the points that are around the point I'm currently at (I marked it as neighbors). I want to create a new variable surviving_neighbors. This would be a list of coordinates of the surrounding points where I have not yet been to (e.g. I am currently at (1,1); I have already been at (0,1) and (1,2) so that my surviving neighbors would be (1,0 ) and (2,1)). I want to get Surviving_neighbors using the difference method: I put neighbors.difference(list of coordinates) and save in a variable what is in the list of neighbors, but not in the list of coordinates I was on. The first problem I have is that I don't have one list with coordinates, but x and y are stored separately. Next, I would use choice(surviving_neighbors) and thus choose new coordinates. This creates another problem: I probably won't be able to call it a trajectory, but I'll have to define it again in terms of x and y...
The teacher suggested that I store x and y as vectors, but I have no idea how to do that.
Code:
from random import choice
import numpy as np
from matplotlib import pyplot as plt
plt.style.use(['science', 'notebook', 'dark background'])
x, y = 0, 0
coordinates = [(x, y)]
for time in range(10):
dx, dy = choice([(0, 1), (-1, 0), (0, 1), (0, -1)])
x, y = x + dx, y + dy
X.append(x)
Y.append(y)
neighbors = [x+1, y
x-1
y
x, y+1
x, y-1]
surviving_neighbors = neighbors.difference(X, Y)
trajectory = choice(surviving_neighbors)
plt.plot()
Hard to know where you are going with this, here is a basic working example;
This is invalid as they don't exist;
plt.style.use(['science', 'notebook', 'dark background'])
Possible values are;
['Solarize_Light2', '_classic_test_patch', '_mpl-gallery',
'_mpl-gallery-nogrid', 'bmh', 'classic', 'dark_background', 'fast',
'fivethirtyeight', 'ggplot', 'grayscale', 'seaborn-v0_8',
'seaborn-v0_8-bright', 'seaborn-v0_8-colorblind', 'seaborn-v0_8-dark',
'seaborn-v0_8-dark-palette', 'seaborn-v0_8-darkgrid',
'seaborn-v0_8-deep', 'seaborn-v0_8-muted', 'seaborn-v0_8-notebook',
'seaborn-v0_8-paper', 'seaborn-v0_8-pastel', 'seaborn-v0_8-poster',
'seaborn-v0_8-talk', 'seaborn-v0_8-ticks', 'seaborn-v0_8-white',
'seaborn-v0_8-whitegrid', 'tableau-colorblind10']
from random import choice
from matplotlib import pyplot as plt
plt.style.use('seaborn-v0_8-darkgrid')
print(plt.style.available)
#2D self-avoiding random walk
def dotty(n):
x, y = 0, 0
path = [(x, y)]
for i in range(n):
# pick the closest point but it must complete without crossing itself
x, y = choice([(x+1, y), (x-1, y), (x, y+1), (x, y-1)])
if (x, y) in path:
return path
path.append((x, y))
return path
# show plot
def show_path(path):
plt.figure(figsize=(10, 10))
# draw points
plt.scatter(*zip(*path), s=5, c='k')
# draw lines in red
plt.plot(*zip(*path), c='r')
plt.show()
# main
if __name__ == '__main__':
path = dotty(100000)
show_path(path)
Output:
I have a following function with takes 2 arguments psi,lam and returns 1 array y.
lam=np.arange(0,1,0.1)
psi=np.deg2rad(np.arange(0,361,1))
def test(psi,lam):
y=[]
for i in range(len(lam)):
sin_psi = np.sin(psi)
cos_psi = np.cos(psi)
sin_beta = lam*sin_psi
cos_beta = np.sqrt(1.0 - sin_beta**2)
ssin_pb = sin_psi*sin_beta
y.append((lam*(cos_psi/cos_beta)**2 - ssin_pb)/cos_beta + cos_psi)
plt.plot(psi,y[i])
return y
I would like the function to return range(len(lam))=10 plots of y on the vertical axis against psi on x axis.
However, it seems to be only plotting the same curve multiple times. Not sure what I am missing?
import matplotlib.pyplot as plt
import numpy as np
lam=np.arange(0,1,0.1)
psi=np.deg2rad(np.arange(0,361,1))
def test(angle,var):
sin_psi = np.sin(psi)
cos_psi = np.cos(psi)
sin_beta = var*sin_psi
cos_beta = np.sqrt(1.0 - sin_beta**2)
ssin_pb = sin_psi*sin_beta
return ((var*(cos_psi/cos_beta)**2 - ssin_pb)/cos_beta + cos_psi)
for i in lam:
plt.plot(psi,test(psi,i))
plt.show()
I moved the variable outside of the function, this way you may also use it for other cases. The only other thing is that you should call plt.show() after you're done drawing.
Your code has several problems the main being that the return function was inside the loop interrupting it after the first iteration. Imitating your code structure as closely as possible, we can rewrite the code as:
import numpy as np
import matplotlib.pyplot as plt
def test(psi,lam):
y=[]
for curr_lam in lam:
sin_psi = np.sin(psi)
cos_psi = np.cos(psi)
sin_beta = curr_lam*sin_psi
cos_beta = np.sqrt(1.0 - sin_beta**2)
ssin_pb = sin_psi*sin_beta
val = (curr_lam * (cos_psi/cos_beta)**2 - ssin_pb)/cos_beta + cos_psi
y.append(val)
plt.plot(psi, val)
plt.show()
return y
lam=np.arange(0, 1, 0.1)
psi=np.deg2rad(np.arange(0,361,1))
y = test(psi, lam)
print(y)
Sample output:
As Johan mentioned in the comments, you should also directly iterate over list/arrays. If you need to combine arrays, use
for x1, x2 in zip(arr1, arr2):
If you absolutely need the index value, use
for i, x in enumerate(arr):
I have defined an array that contains 1000 points, to illustrate, something like this:
x = np.zeros([1000, 2])
for i in range(1001):
x = 'int + [i , i] / 2'
How do I plot the points with plt.scatter()? I have tried with just inserting x, but it doent work.
Thank you in advance!
I think you're trying to do something like this:
import matplotlib.pyplot as plt
x = np.zeros([1000, 2])
for i in range(len(x)):
x[i] = [i/2 , i/2]
plt.scatter(x[:,0],x[:,1])
plt.show()
If anything isn't clear, don't hesitate to ask!
UPDATE:
Using the answer from before, I was able to call the function. Now, I tried to increase the difficulty a step-further.
I understand that using this works:
def sinesum(t, b):
return sum(b*sin(n*t))
for i in range(0, 10, 1):
b = i
n = i
t = i
print(sinesum(i,i))
Although, I want to be able to plot it with:
import matplotlib.pyplot as plt
t = np.linspace(-10, 10, 20)
plt.plot(t, sinesum(i,i))
plt.show
I get nothing, how do I plot with the function output as y?
when I remove (i, i) and include (t, b) I get
x and y must have the same first dimension, but have shapes (20,) and (1,)
I understand that this is because the function only calls a single value, how do I get it so that sinesum(i,i) will return the right amount of dimensions for the plot?
You should calculate every value before plotting it:
res = []
for v in t:
res.append(sinesum(v,b))
plt.plot(t,res)
or using list comprehension:
plt.plot(t, [sinesum(v,b) for v in t])
Did you meen?
def f(x):
return 4*x + 1
for i in range(100):
print(f(i))
So I made my list but after that I don't know how to take out of it my x and y so I can use it later to create a graph
import random
import numpy as np
import matplotlib.pyplot as plt
tabuletson = []
for i in range(0, 10):
x = round(random.uniform(-1000,1000),2)
y = (2*x+1)
tabuletson.append([x,y])
print(tabuletson)
wielomian = np.poly1d(np.polyfit(x,y,3))
linia = np.linspace(-2000,2000,2000)
plt.scatter(x,y)
plt.plot(linia,wielomian(linia))
plt.show()
All you have to do is to add one line of code after and outside your for loop. This command will create two lists containing x and y values. You can use the same variable names x and y.
x, y = zip(*tabuletson)
I think that this is a better way to do what you want according of how plt.scatter and plt.plot work. Hope it works as you want!
import random
import numpy as np
import matplotlib.pyplot as plt
x = []; y = []
for i in range(10):
x.append(round(random.uniform(-1000,1000),2))
y.append(2*x[i]+1)
wielomian = np.poly1d(np.polyfit(x,y,3))
linia = np.linspace(-2000,2000,2000)
plt.scatter(x,y)
plt.plot(linia,wielomian(linia))
plt.show()
The np.polyfit and plt.scatter functions you are using require separate lists of X and Y coordinates.
Try:
import random
import numpy as np
import matplotlib.pyplot as plt
tabuletson_x = []
tabuletson_y = []
for i in range(0, 10):
x = round(random.uniform(-1000,1000),2)
y = (2*x+1)
tabuletson_x.append(x)
tabuletson_y.append(y)
print(tabuletson_x)
print(tabuletson_y)
wielomian = np.poly1d(np.polyfit(tabuletson_x,tabuletson_y,3))
linia = np.linspace(-2000,2000,2000)
plt.scatter(tabuletson_x,tabuletson_y)
plt.plot(linia,wielomian(linia))
plt.show()
Note: referencing x and y after the for cycle will give you the last values from the randomly generated list:
list of x vals: [-8.78, 554.81, -693.22, 955.8, 88.95, 235.55, -108.67, -804.08, 494.65, 754.58]
list of y vals: [-16.56, 1110.62, -1385.44, 1912.6, 178.9, 472.1, -216.34, -1607.16, 990.3, 1510.16]
x: 754.58
y: 1510.16
For more info:
PyPlot Scatter documentation
PolyFit documentation
Your x and y are stored in your list tabuletson. Like this: [[x0,y0], [x1,y1], ..., [x,y]]
So you can, for example, get the value of x1 and y1 with x1 = tabuletson[1][0] and y1 = tabuletson[1][1]
Is that your question ?
tabuletson = np.array(tabuletson)
X, Y = tabuletson[:,0], tabuletson[:,1]
X will have all your xs from list
And, Y will have all your ys from list