I would like to rotate a curve to a pass through a point on a 2D plot but l cant find a way of doing it .
Say l want to rotate
y=np.exp(x)+2 #pass through (x=5,y=6) point
You can subtract value of y(x_0) from y and add desired y.
For example
x = np.arange(10)
y = np.exp(x) + 2
x_ind = 5 #This is not value of x, this is index of desired x
y_desired = 6
y -= y[x[x_ind]] + y_desired
plt.plot(x, y, color='b')
plt.scatter([x[x_ind]], [y_desired], color='r')
plt.show()
Related
I have a mathematical function
y = x^3 + sin(x) which I calculated using the below formular
np.random.seed(10)
x = np.random.random(20)
def calculate(x):
cube_x = np.power(x,3)
sin_x = np.sin(x)
y = cube_x + sin_x
return y
and I created a plot for the above equation
fig = plt.figure(figsize = (14, 8))
##Plot y = x^3 + sin(x)
y = calculate(x)
##plt.plot(x, y, 'b', label = '$x^3$ + $\sin$ $(x)$')
# Add features to our figure
plt.legend()
plt.grid(True, linestyle =':')
plt.xlim([0, 2])
plt.ylim([0, 2])
plt.title("Plot of y = $x^3$ + $\sin$ $(x)$ ")
plt.xlabel('x-axis')
plt.ylabel('y-axis')
# Show plot
plt.show()
I am not sure the above graph is correct. Please I need your assistance to know if I am getting the desired graph for the above function.
You should sort your random array in order to generate the plot correcty. You can use:
x = np.sort(np.random.random(20))
You can also use plt.scatter() instead of plt.plot(), so you don't have to sort the x array.
Like JMA said, you should to sort x first. If you had plotted your original data as a scatter, it would look fine:
However, if you were in a situation where you could not sort your input data prior to evaluating the function y, you can use np.argsort. Say you already have x and y computed and needed to sort x and y based on the order of x alone (e.g. y is not monotonic), you would use the following lines.
idx = np.argsort(x)
x, y = x[idx], y[idx]
and you plot would look like:
How Z is calcutalted in
from matplotlib.pyplot import contour
contour([X, Y,] Z, [levels], **kwargs)
to draw a contour?
I know that Z means: The height values over which the contour is drawn.
But is it drawn by calculating a standard deviation or something like that?
An average between each point I have?
Z represents a quantity dependent on both X and Y axes. If X and Y represent a plane, Z can be thought of as a surface, whose point height depends on the X and Y coordinates of that given point. The contour is a "top view" of that surface, a projection. An example are the contour lines which report the heights of the mountains (Z) as longitude (X) and latitude (Y) change.
The contour function of matplotlib, as you wrote it, plots the values expressed in the Z variable (two-dimensional numpy.ndarray, as X and Y) as they are, without further processing. The relationship between Z and X and Y is defined outside the plot function.
I report an example below which, perhaps it may be useful:
# IMPORT
import numpy as np
import matplotlib.pyplot as pl
# INPUT
N = 100
x_min = 0
x_max = 10
y_min = 0
y_max = 10
z_min = 0
z_max = 50
z_step = 1
red = '#de7677'
# DEFINE MESH GRID
x = np.linspace(x_min, x_max, N)
y = np.linspace(y_min, y_max, N)
XX, YY = np.meshgrid(x, y)
# CALCULATE ZZ AS A FUNCTION OF XX AND YY, FOR ESAMPLE, THEIR SUM
ZZ = YY + XX
# PLOT THE CONTOUR
fig, ax = pl.subplots(figsize = (10, 10))
cont = ax.contour(XX,
YY,
ZZ,
levels = np.arange(z_min, z_max + z_step, z_step),
colors = red)
# SET THE CONTOUR LABELS
pl.clabel(cont, fmt = '%d')
# SET THE X AND Y LABEL
ax.set_xlabel('X')
ax.set_ylabel('Y')
pl.show()
I'm trying to demonstrate a cost function right now and wondering if there's a way to traverse the parabola by adding plot in the same subplot and figure.
def costfuntion(b, a):
# b Value
x = np.linspace(b*(-b), b*(b), 100)
y = (x - a)**2
return y
My Plot Attempt:
plt.plot(costfuntion(20,5))
plt.ylabel("Cost Value");
#b = 'some b value'
plt.plot(b, marker='o', color='b')
What I'm trying to mimic
(Around: 1:13)
Since the y values depend on the a values you need to specify an a for the y lookup. Consider the following:
def costfunction(b, a):
# b Value
x = np.linspace(b*(-b), b*(b), 100)
y = (x - a)**2
return x, y
a = 5
c = costfunction(20, a)
plt.plot(c[0], c[1], linestyle='-', linewidth=1)
plt.ylabel("Cost Value");
b = 100
yb = (b - a)**2 # Find the corresponding y-value
plt.plot(b, yb, marker='o', color='b')
plt.show()
This will give you
You might also note that I modified the costfunction definition to return the x values, otherwise matplotlib will just use whatever values it pleases.
def costfuntion(b, a):
# b Value
x = np.linspace(b*(-b), b*(b), 100)
y = (x - a)**2
return x, y
x, y = costfuntion(20,5)
plt.plot(x, y)
for i in range(0, len(x), 2):
plt.plot(x[i], y[i], marker='o', color='b')
Change the cost function to return both x and y of the function you are plotting and use this information to plot points on the function.
This question already has answers here:
Make contour of scatter
(3 answers)
Closed 5 years ago.
I have 3 lots of data. These are x and y values as well as a temperature value for each xy point. I would like to plot each point and interpolate the area between points to get a continuous surface. The issue I have is specifying the temperature values. I can't get it to work with an equal number of x,y and z (temperature) values and all the examples I can find online use a function of x and y to create z or have z values for every point on an xy grid.
Is there a simple way to do this?
import numpy as np
import matplotlib.pyplot as plt
fig, axs = plt.subplots()
x = np.linspace(0, 1, 100)
y = np.linspace(0,1,100)
X, Y = np.meshgrid(x, y)
#Z = np.sin(X)*np.sin(Y) # want to specify not an equation
Z = np.linspace(1,2,100)
levels = np.linspace(-1, 1, 40)
cs = axs.contourf(X, Y, Z, levels=levels)
fig.colorbar(cs, ax=axs, format="%.2f")
plt.show()
Update:
Here is what I have so far. I still need to work out a good method to fill in the area between points. Does anyone have any ideas?
import numpy as np
import matplotlib.pyplot as plt
fig, axs = plt.subplots()
# create a grid in the correct shape / size
x = np.linspace(0, 1, 3)
y = np.linspace(0,1,3)
X, Y = np.meshgrid(x, y)
# specify and change the relevent areas
y = [1,2,0] # location of point in x direction
x =[2,1,1] #location of point in y direction
z = [40,30,20] #temperature
Z = np.arange(1,10).reshape((3,3))
Z[y,x] = z
levels = np.linspace(0, 40, 40)
cs = axs.contourf(X, Y, Z, levels=levels)
fig.colorbar(cs, ax=axs, format="%.2f")
plt.show()
The reason people use a function of x and y is because your Z value has to be a function of x and y. In your test code Z is 1D but it needs to be 2D to plot the contours.
If you have Z (temperature) values that have the same shape as your x and y coordinates then it should work.
x = np.linspace(0, 1, 100)
y = np.linspace(0,1,100)
X, Y = np.meshgrid(x, y)
#Z = np.sin(X)*np.sin(Y) # want to specify not an equation
Z = np.linspace(1,2,100)
print X.shape
print Z.shape
(100L,100L)
(100L)
The point of the spot marked (comment says "marked spot") is to rotate the existing points in a 3D plot by one spot. Basically I'm moving all points 60 degrees. For some reason when moving the points I am having two points overlap. I have tried changing my if statement, and have messed around with he indices, but have not been successful. The only reason I included the entire function is so you can plot and see the problem I am having. Here it is; let me know if you have any questions:
def transform_3d_trig(a,b,c):
q=2*math.pi/(360)
d=c*q
a2 = a+b
n = 12
sin=math.sin
cos=math.cos
sqrt=math.sqrt
x = []
y = []
z = []
for i in range(n):
if i <= 5:
x.append(a*np.cos(q*(60*(i-1))))
y.append(a*np.sin(q*(60*(i-1))))
z.append(0)
else:
x.append(a2*np.cos(q*(60*(i-1))))
y.append(a2*np.sin(q*(60*(i-1))))
z.append(0)
x_new = x #new lists
y_new = y
z_new = z
for i in range(n):
y_new[i] = y[i]*cos(d)
z_new[i] = y_new[i]*np.tan(d)
# plot points at this stage (before rotation); no overlapping points
fig = plt.figure(figsize=(12,12))
ax3 = fig.add_subplot(211, projection='3d')
bond2 = [x_new[4],x_new[10],y_new[4],y_new[10],z_new[4],z_new[10]]
ax3.plot(bond2[:2],bond2[2:4],bond2[4:6], color='r')
ax3.scatter(x_new, y_new, z_new)
ax3.set_xlabel('\nX')
ax3.set_ylabel('\nY')
ax3.set_zlabel('\nZ')
x_dummy = x_new #dummy variables to not screw up list
y_dummy = y_new
for i in range(n): #marked spot
if (i == 5 or i == 11):
x_new[i] = x_dummy[i-5]
y_new[i] = y_dummy[i-5]
else:
x_new[i] = x_dummy[i+1]
y_new[i] = y_dummy[i+1]
print(x_new[i], y_new[i]) #to track what point are overlapping
# plot points at this stage (after rotation); overlapping points
ax3 = fig.add_subplot(212, projection='3d')
bond2 = [x_new[4],x_new[10],y_new[4],y_new[10],z_new[4],z_new[10]]
ax3.plot(bond2[:2],bond2[2:4],bond2[4:6], color='r')
ax3.scatter(x_new, y_new, z_new)
ax3.set_xlabel('\nX')
ax3.set_ylabel('\nY')
ax3.set_zlabel('\nZ')
plt.show()
return x, y, z, x_new, y_new, z_new
The problem is probably that these lines don't do what you expect:
x_dummy = x_new
y_dummy = y_new
They don't create copies of your arrays but just duplicate the references. As a result you are actually 'screwing up' your original _new arrays when modifying the _dummy 'versions' because they are (references to) the same object.
To achieve the behaviour you are looking for (I assume), you would need to force the actual copy of the data:
x_dummy = x_new.copy()
y_dummy = y_new.copy()