I am trying to plot a scatter graph with X, Y and Y2. The main objective is to study the relationship between these three features.
import matplotlib.cm as cm
import matplotlib.pyplot as plt
X = [110, 120, 130, 140, 150]
Y = [0.1, 0.2, 0.3, 0.4, 0.5]
Y2 = [5, 4, 3, 2, 1]
plt.title('X vs Y vs Y2')
plt.xlabel('X')
plt.ylabel('Y')
points1 = plt.scatter(X, Y,
c=Y, cmap="rainbow", alpha=1) #set style options
cbar = plt.colorbar(points1)
cbar.set_label('Y2')
But I got something like this:
The points of the graph show the relationship between X and Y. I want Y2 relation to be shown by using the colorbar labelled at the right side of the y-axis. I expected it to look like this:
Related
Is there a way to make a plane of best fit using matplotlib?
I'm trying to get a smooth curved plane or even just a flat one, but I'm unsure on how to do so.
My points are arranged as shown in the following image:
They are quite smooth, except for a few exceptions, which are mostly clear.
My current code is:
from mpl_toolkits import mplot3d
import matplotlib.pyplot as plt
from sklearn import linear_model
plt.style.use('seaborn-poster')
x = np.array([12.5, 10, 9.5, 7.5, 6])
y = np.array([30, 45, 50, 55, 60, 65])
z = np.array([
[62.13, 55.41, 54.49, 46.46, 42.13],
[67.11, 59.43, 56.39, 52.64, 41.89],
[82.89, 61.13, 57.30, 50.75, 43.02],
[73.31, 60.57, 57.17, 52.64, 41.73],
[78.11, 62.92, 63.40, 58.08, 48.69],
[83.96, 65.19, 60.22, 53.57, 44.22]
])
X, Y = np.meshgrid(x, y)
Z = z
x1, y1, z1 = X.flatten(), Y.flatten(), Z.flatten()
X_data = np.array([x1, y1]).reshape((-1, 2))
Y_data = z1
reg = linear_model.LinearRegression().fit(X_data, Y_data)
a1, a2, c = float(reg.coef_[0]), float(reg.coef_[1]), float(reg.intercept_)
fig = plt.figure(figsize = (9,9))
ax = plt.axes(projection='3d')
ax.grid()
ax.plot_surface(X, Y, z)
ax.scatter(X, Y, z, c = 'r', s = 50)
ax.set_title('Figure 1.21 - Plot of Final results')
ax.set_xlabel('Radius of Ball (mm)', labelpad=20)
ax.set_ylabel('Height from which ball was dropped (cm)', labelpad=20)
ax.set_zlabel('Diameter of ripple (mm)', labelpad=20)
plt.show()
I have the a1, a2 and c values using linear regression but how do I plot them?
Is linear regression going to give the right sort of result for this graph?
I'm quite new to matplotlib, so sorry if this seems obvious.
I would like to create a contourf plot with an imposed maximum value and with everything above that value shaded with the last color of the colorbar. In the example code below, which reproduces my problem in my setup, I would like the colorbar to range between -1 and 1, with an extend arrow indicating that values above 1.0 will be shaded with the last color of the colorbar. However, although I have tried several solutions from various stackexchange discussions, the colorbar ranges between -4 and 4, and there is no extend arrow. Please see the minimum reproducible example below.
# import matplotlib (v 3.1.1)
import matplotlib.colors as colors
import matplotlib.pyplot as plt
import matplotlib.path as mpath
import matplotlib as mpl
# import numpy (v 1.17.2)
import numpy as np
# define grid
lon = np.linspace(start = 0, stop = 359, num = 360)
lat = np.linspace(start = -78, stop = -25, num = 52)
[X,Y] = np.meshgrid(lon, lat)
# generate random gaussian data for example purposes
mean = [0, 0]
cov = [[1, 0], [0, 100]]
zz = np.random.multivariate_normal(mean, cov, (np.size(lon),np.size(lat))).T
Z = zz[0,:,:]
# illutrate the maximum value of Z
np.max(Z)
# create plot
plt.figure(figsize=(10, 12))
# select plotting levels (missing min/max on purpose)
mylevs = [-1.0, -0.5, 0, 0.5, 1.0]
# colormap
cmap_cividis = plt.cm.get_cmap('cividis',len(mylevs))
mycolors = list(cmap_cividis(np.arange(len(mylevs))))
cmap = colors.ListedColormap(mycolors[:-1], "")
# set over-color to last color of list
cmap.set_over(mycolors[-1])
# contour plot: random pattern
C1 = plt.contourf(X, Y, Z, cmap = cmap, vmin=-1.0, vmax=1.0,
norm = colors.BoundaryNorm(mylevs, ncolors=len(mylevs)-1, clip=False))
# create colorbar
cbar = plt.colorbar(C1, orientation="horizontal", extend='max')
cbar.ax.tick_params(labelsize=20)
cbar.set_label('Random field', size='xx-large')
I would like the colorbar to stop at 1.0, with an extend arrow pointing to the right, shaded by the last color of the colorbar. Thanks in advance for any help you can provide.
Link to example image produced by the above code
Does this solve it?
fig,ax = plt.subplots()
mylevs = [-1.0, -0.5, 0, 0.5, 1.0]
C1 = ax.contourf(X, Y, Z, cmap = cmap, vmin=-1.0, vmax=1.0,levels=mylevs,extend='both')
fig.colorbar(C1)
I have a 3d plot of a disk, here is the code:
ri = 100
ra = 300
h=20
# input xy coordinates
xy = np.array([[ri,0],[ra,0],[ra,h],[ri,h],[ri,0]])
# radial component is x values of input
r = xy[:,0]
# angular component is one revolution of 30 steps
phi = np.linspace(0, 2*np.pi, 50)
# create grid
R,Phi = np.meshgrid(r,phi)
# transform to cartesian coordinates
X = R*np.cos(Phi)
Y = R*np.sin(Phi)
# Z values are y values, repeated 30 times
Z = np.tile(xy[:,1],len(Y)).reshape(Y.shape)
fig = plt.figure()
ax = fig.add_subplot(1, 1, 1, projection='3d')
ax.set_zlim(0,200)
ax.plot_surface(X, Y, Z, alpha=0.5, color='grey', rstride=1, cstride=1)
I get this nice plot:
Further I have this plot:
The code is:
import numpy as np
import matplotlib.pyplot as plt
import matplotlib as mpl
arr = np.array([[100, 15],
[114.28, 17],
[128.57, 18],
[142.85, 19],
[157.13, 22],
[171.13, 24],
[185.69, 25],
[199.97, 27],
[214.25, 28],
[228.53, 30],
[242.81, 31],
[257.09, 35],
[271.37, 36],
[288.65, 37],
[300, 38]])
#interpolating between the single values of the arrays
new_x = np.concatenate([np.linspace(arr[i,0],arr[i+1,0], num=50)
for i in range(len(arr)-1)])
new_y = np.interp(new_x, arr[:,0], arr[:,1])
t=np.arange(700)
p = plt.scatter(new_x,new_y,c=t, cmap="jet")
#inserting colorbar
cax, _ = mpl.colorbar.make_axes(plt.gca(), shrink=0.8)
cbar = mpl.colorbar.ColorbarBase(cax, cmap='jet', label='testvalues',
norm=mpl.colors.Normalize(15, 40))
plt.show()
Now my question:
Is there a way to plot this 2d graph into my 3d environment? Further is it possible to create a surface out of this line (points) by rotating them around the middlepoint ? I tried it the same way like I did it with my disk but I failed because I think I need a closed contour ? Here is a picture to understand better what I want:
I'm not sure how you want to include your 2d plot, so here's how you do it as a surface of revolution.
Your new_x corresponds to radial distance, new_y corresponds to height. So we need to generate an array of angles for which to generate the "cone":
from matplotlib import cm
tmp_phi = np.linspace(0,2*np.pi,50)[:,None] # angle data
linesurf_x = new_x*np.cos(tmp_phi)
linesurf_y = new_x*np.sin(tmp_phi)
linesurf_z = np.broadcast_to(new_y, linesurf_x.shape)
linesurf_c = np.broadcast_to(t, linesurf_x.shape) # color according to t
colors = cm.jet(linesurf_c/linesurf_c.max()) # grab actual colors for the surface
ax.plot_surface(linesurf_x, linesurf_y, linesurf_z, facecolors=colors,
rstride=1, cstride=1)
Result:
I have a data set which looks like this:
Intensity = ( [1, 2, 3, 4], [6, 7, 9, 10] )
Xposition = (0.1, 0.2, 0.3, 0.4)
Yposition = (1E^-9, 1.2E^-9)
So, for each Yposition, we have an 1D array stored in Intensity, corresponding to each Xposition.
Now I want to plot Xposition (X-axis), Yposition (Y-axis) and Intensity along Z to generate a 3D plot. How can I do this using matplotlib?
There are nice tutorials on matplotlib page. Looking at two examples and slightly tweaking the code:
import numpy as np
from mpl_toolkits.mplot3d import Axes3D
import matplotlib.pyplot as plt
fig = plt.figure()
ax = fig.add_subplot(111, projection='3d')
x = (0.1,0.2,0.3,0.4)
y = (10**-9, 1.2*10**-9)
x,y = np.meshgrid(x,y)
z = ( [1,2,3,4], [6,7,9,10] )
ax.scatter(x, y, z)
plt.show()
I am trying to overlay a scatter plot onto a contour plot using matplotlib, which contains
plt.contourf(X, Y, XYprof.T, self.nLevels, extent=extentYPY, \
origin = 'lower')
if self.doScatter == True and len(xyScatter['y']) != 0:
plt.scatter(xyScatter['x'], xyScatter['y'], \
s=dSize, c=myColor, marker='.', edgecolor='none')
plt.xlim(-xLimHist, xLimHist)
plt.ylim(-yLimHist, yLimHist)
plt.xlabel(r'$x$')
plt.ylabel(r'$y$')
What ends up happening is the resulting plots extend to include all of the scatter points, which can exceed the limits for the contour plot. Is there any way to get around this?
I used the following example to try and replicate your problem. If left to default, the range for x and y was -3 to 3. I input the xlim and ylim so the range for both was -2 to 2. It worked.
import numpy as np
import matplotlib.pyplot as plt
from pylab import *
# the random data
x = np.random.randn(1000)
y = np.random.randn(1000)
fig = plt.figure(1, figsize=(5.5,5.5))
X, Y = meshgrid(x, y)
Z1 = bivariate_normal(X, Y, 1.0, 1.0, 0.0, 0.0)
Z2 = bivariate_normal(X, Y, 1.5, 0.5, 1, 1)
Z = 10 * (Z1 - Z2)
origin = 'lower'
CS = contourf(x, y, Z, 10, # [-1, -0.1, 0, 0.1],
cmap=cm.bone,
origin=origin)
title('Nonsense')
xlabel('x-stuff')
ylabel('y-stuff')
# the scatter plot:
axScatter = plt.subplot(111)
axScatter.scatter(x, y)
# set axes range
plt.xlim(-2, 2)
plt.ylim(-2, 2)
show()