This question already has answers here:
How to plot multiple functions on the same figure, in Matplotlib?
(4 answers)
Closed 1 year ago.
How to build two graphs in one figure from the equations below
y = (x+2)^2
y = sin(x/2)^2
There is my code:
import matplotlib.pyplot as plt
import numpy as np
from math import sin
y = lambda x: sin(x / 2) ** 2
y1 = lambda x: (x + 2) ** 2
fig = plt.subplots()
x = np.linspace(-3, 3, 100)
plt.plot(x, y(x))
plt.plot(x, y1(x))
plt.show()
Use supplots to make 2 Axes in your Figure:
import matplotlib.pyplot as plt
import numpy as np
fig, (ax1,ax2) = plt.subplots(nrows=2)
x = np.linspace(-3, 3, 100)
ax1.plot(x, np.sin(x / 2) ** 2)
ax2.plot(x, (x + 2) ** 2)
Related
X = (6 * np.random.rand(10, 1) - 3)
y_cap = (0.44530754 * X**2)+(1.01366334 * X)+0.13309963
plt.plot(X, y_cap, ls = '--')
I'm solving a polynomial regression problem (degree=2). I got the coefficients of X, X^2, and performed the polynominal regression. And now when I tried to plot using the above code I got these lines instead of a curve. How to solve this?
This happens because your X values are not ordered. Just do this before calculating y_cap:
X = np.sort(X, 0)
Then it will work. Full example:
import numpy as np
import matplotlib.pyplot as plt
X = (6 * np.random.rand(10, 1) - 3)
X = np.sort(X, 0)
y_cap = (0.44530754 * X**2)+(1.01366334 * X)+0.13309963
plt.plot(X, y_cap, ls = '--')
plt.show()
I have 4 arrays x, y, z and T of length n and I want to plot a 3D curve using matplotlib. The (x, y, z) are the points positions and T is the value of each point (which is plotted as color), like the temperature of each point. How can I do it?
Example code:
import numpy as np
from matplotlib import pyplot as plt
fig = plt.figure()
ax = fig.gca(projection='3d')
n = 100
cmap = plt.get_cmap("bwr")
theta = np.linspace(-4 * np.pi, 4 * np.pi, n)
z = np.linspace(-2, 2, n)
r = z**2 + 1
x = r * np.sin(theta)
y = r * np.cos(theta)
T = (2*np.random.rand(n) - 1) # All the values are in [-1, 1]
What I found over the internet:
It's possible to use cmap with scatter like shown in the docs and in this stackoverflow question
ax = plt.gca()
ax.scatter(x, y, z, cmap=cmap, c=T)
The problem is that scatter is a set of points, not a curve.
In this stackoverflow question the solution was divide in n-1 intervals and each interval we use a different color like
t = (T - np.min(T))/(np.max(T)-np.min(T)) # Normalize
for i in range(n-1):
plt.plot(x[i:i+2], y[i:i+2], z[i:i+2], c=cmap(t[i])
The problem is that each segment has only one color, but it should be an gradient. The last value is not even used.
Useful links:
Matplotlib - Colormaps
Matplotlib - Tutorial 3D
This is a case where you probably need to use Line3DCollection. This is the recipe:
create segments from your array of coordinates.
create a Line3DCollection object.
add that collection to the axis.
set the axis limits.
import numpy as np
import matplotlib.pyplot as plt
from mpl_toolkits.mplot3d.art3d import Line3DCollection
from matplotlib.cm import ScalarMappable
from matplotlib.colors import Normalize
def get_segments(x, y, z):
"""Convert lists of coordinates to a list of segments to be used
with Matplotlib's Line3DCollection.
"""
points = np.ma.array((x, y, z)).T.reshape(-1, 1, 3)
return np.ma.concatenate([points[:-1], points[1:]], axis=1)
fig = plt.figure()
ax = fig.add_subplot(projection='3d')
n = 100
cmap = plt.get_cmap("bwr")
theta = np.linspace(-4 * np.pi, 4 * np.pi, n)
z = np.linspace(-2, 2, n)
r = z**2 + 1
x = r * np.sin(theta)
y = r * np.cos(theta)
T = np.cos(theta)
segments = get_segments(x, y, z)
c = Line3DCollection(segments, cmap=cmap, array=T)
ax.add_collection(c)
fig.colorbar(c)
ax.set_xlim(x.min(), x.max())
ax.set_ylim(y.min(), y.max())
ax.set_zlim(z.min(), z.max())
plt.show()
This question already has an answer here:
Matplotlib: automatically modify axis labels
(1 answer)
Closed 3 years ago.
I have following code:
import matplotlib.pyplot as plt
x = [i * 2872155 for i in range(1, 11)]
y = [0.219, 0.402, 0.543, 0.646,0.765, 0.880,1.169, 1.358,1.492,1.611]
plt.plot(x, y)
and the plot is
But I want the y label to be like 0.2s, 0.4s, 0.6s.
How can I do this?
Try this:
import matplotlib.pyplot as plt
import matplotlib.ticker as mticker
x = [i * 2872155 for i in range(1, 11)]
y = [0.219, 0.402, 0.543, 0.646,0.765, 0.880,1.169, 1.358,1.492,1.611]
plt.gca().yaxis.set_major_formatter(mticker.FormatStrFormatter('%.1f s'))
plt.plot(x, y)
plt.show()
Or use:
import matplotlib.pyplot as plt
import matplotlib.ticker as ticker
x = [i * 2872155 for i in range(1, 11)]
y = [0.219, 0.402, 0.543, 0.646,0.765, 0.880,1.169, 1.358,1.492,1.611]
fig, ax = plt.subplots()
ax.plot(x, y)
ax.yaxis.set_major_formatter(ticker.FormatStrFormatter('%.1fs'))
plt.show()
you can use type conversion if you just want to add 's' to y values
x = [i * 2872155 for i in range(1, 11)]
y = [0.219, 0.402, 0.543, 0.646,0.765, 0.880,1.169, 1.358,1.492,1.611]
z = [str(i)+'s' for i in y]
plt.plot(x, z)
plt.show()
This question already has answers here:
How to plot a gradient color line in matplotlib?
(7 answers)
Closed 3 years ago.
So I have a normal scatter plot:
import numpy as np
import matplotlib.pyplot as plt
import random
x = np.random.random_sample((100,))
x = np.sort(x)
y = x + np.sin(np.pi * x)
z = 5 * x
fig = plt.figure()
plot = plt.scatter(x, y, s= 10, c = z, cmap='coolwarm')
fig.colorbar(plot)
plt.grid(True, 'both')
plt.show()
that produces a plot something like this
However, I would really like to add a line to scatter and connect these points. It may sound ridiculous since it is easy to follow the points in given case, but imagine if the data would be more scattered and possibly multiple datasets ...
So my goal is to add a line to the scatter above, but the color of the line should change according to value of 'z', the same way scatter plot does. Is that even possible?
EDIT:
The x, y, z provided above is just random data to explain the problem. In reality, you can imagine the points (x, y) coordinates are given from an experiment meaning in general there is no relation between x, y, z or even if it is, it is NOT known upfront.
You can add another scatterplot using np.linspace() function:
import numpy as np
import matplotlib.pyplot as plt
import random
x = np.random.random_sample((100,))
x = np.sort(x)
y = x + np.sin(np.pi * x)
z = 5 * x
fig = plt.figure()
plot = plt.scatter(x, y, s= 10, c = z, cmap='coolwarm')
fig.colorbar(plot)
plt.grid(True, 'both')
# add another scatterplot
x_line = np.linspace(np.min(x), np.max(x), num=1000)
y_line = x_line + np.sin(np.pi * x_line)
z_line = 5 * x_line
plt.scatter(x_line, y_line, c=z_line, s=0.1, cmap='coolwarm')
plt.show()
I have a function 2*x*arcctg(x) - 1, and i try to plot it in Python:
import os
import matplotlib.pyplot as plt
import numpy as np
x = np.linspace(0, np.pi / 2)
y = 2 * x * np.cos(2 * x) / np.sin(2 * x)
plt.plot(x, y)
plt.axis('tight')
plt.show()
but it's plot smthg like that:
and when i plot it in wolfram it looks:
What am i doing wrong?
The function should be:
2*x*arcctg(x) - 1
But arcctg(x) is not cos(2x)/sin(2x) (the expression you describe in your code). A ctg is the co-tangens, so cos(x)/sin(x). So that means that arcctg(x) is arctan(1/x).
So you can use:
import matplotlib.pyplot as plt
import numpy as np
x = np.linspace(0, np.pi / 2)
y = 2 * x * np.arctan(1/x) - 1
plt.plot(x, y)
plt.axis('tight')
plt.show()
This produces the following plot:
Which matches with the plot in the question.
In case you want to make the plot look more than the one in Wolfram Alpha, you can like #MSeifert says, set the range from -pi/2 to pi/2, like:
import matplotlib.pyplot as plt
import numpy as np
x = np.linspace(-np.pi / 2, np.pi / 2, 1000)
y = 2 * x * np.arctan(1/x) - 1
plt.plot(x, y)
plt.axis('tight')
plt.show()
this then produces: