3D wireframe plot with 2D projections: Spatial organiszation & frequency of projection - python

I'm working on a 3D plot displayed by a wireframe, where 2D plots are projected on the x, y, and z surface, respectively. Below you can find a minimum example.
I have 2 questions:
With contourf, the 2D plots for every x=10, x=20,... or y=10, y=20,... are displayed on the plot walls. Is there a possibility to define for which x or y, respectively, the contour plots are displayed? For example, in case I only want to have the xz contour plot for y = 0.5 mirrored on the wall?
ADDITION: To display what I mean with "2D plots", I changed "contourf" in the code to "contour" and added the resulting plot to this question. Here you can see now the xz lines for different y values, all offset to y=90. What if I do not want to have all the lines, but only two of them for defined y values?
3D_plot_with_2D_contours
As you can see in the minimum example, the 2D contour plot optically covers the wireframe 3D plot. With increasing the transparency with alpha=0.5 I can increase the transparency of the 2D contours to at least see the wireframe, but it is still optically wrong. Is it possible to sort the objects correctly?
import matplotlib.pyplot as plt,numpy as np
import pylab as pl
from mpl_toolkits.mplot3d import axes3d
import matplotlib.pyplot as plt,numpy as np
plt.clf()
fig = plt.figure(1,figsize=(35,17),dpi=600,facecolor='w',edgecolor='k')
fig.set_size_inches(10.5,8)
ax = fig.gca(projection='3d')
X, Y, Z = axes3d.get_test_data(0.05)
Xnew = X + 50
Ynew = Y + 50
cset = ax.contourf(Xnew, Ynew, Z, zdir='z', offset=-100, cmap=plt.cm.coolwarm, alpha=0.5)
cset = ax.contourf(Xnew, Ynew, Z, zdir='x', offset=10, cmap=plt.cm.coolwarm, alpha=0.5)
cset = ax.contourf(Xnew, Ynew, Z, zdir='y', offset=90, cmap=plt.cm.coolwarm, alpha = 0.5)
ax.plot_wireframe(Xnew, Ynew, Z, rstride=5, cstride=5, color='black')
Z=Z-Z.min()
Z=Z/Z.max()
from scipy.ndimage.interpolation import zoom
Xall=zoom(Xnew,5)
Yall=zoom(Ynew,5)
Z=zoom(Z,5)
ax.set_xlim(10, 90)
ax.set_ylim(10, 90)
ax.set_zlim(-100, 100)
ax.tick_params(axis='z', which='major', pad=10)
ax.set_xlabel('X',labelpad=10)
ax.set_ylabel('Y',labelpad=10)
ax.set_zlabel('Z',labelpad=17)
ax.view_init(elev=35., azim=-70)
fig.tight_layout()
plt.show()
ADDITION 2: Here is the actual code I'm working with. However, the original data are hidden in the csv files which are too big to be included in the minimal example. That's why was initially replacing them by the test data. However, maybe the actual code helps nevertheless.
from mpl_toolkits.mplot3d import axes3d
import matplotlib.pyplot as plt,numpy as np
import pylab as pl
from matplotlib.markers import MarkerStyle
import csv
with open("X.csv", 'r') as f:
X = list(csv.reader(f, delimiter=";"))
import numpy as np
X = np.array(X[1:], dtype=np.float)
import csv
with open("Z.csv", 'r') as f:
Z = list(csv.reader(f, delimiter=";"))
import numpy as np
Z = np.array(Z[1:], dtype=np.float)
Y = [[7,7.1,7.2,7.3,7.4,7.5,7.6,7.7,7.8,7.9,8,8.1,8.2,8.3,8.4,8.5,8.6,8.7,8.8,8.9,9]]
Xall = np.repeat(X[:],21,axis=1)
Yall = np.repeat(Y[:],30,axis=0)
from mpl_toolkits.mplot3d import axes3d
import matplotlib.pyplot as plt,numpy as np
plt.clf()
fig = plt.figure(1,figsize=(35,17),dpi=600,facecolor='w',edgecolor='k')
fig.set_size_inches(10.5,8)
ax = fig.gca(projection='3d')
cset = ax.contourf(Xall, Yall, Z, 2, zdir='x', offset=0, cmap=plt.cm.coolwarm, shade = False, edgecolor='none', alpha=0.5)
cset = ax.contourf(Xall, Yall, Z, 2, zdir='y', offset=9, cmap=plt.cm.coolwarm, shade = False, edgecolor='none', alpha=0.5)
ax.plot_wireframe(Xall, Yall, Z, rstride=1, cstride=1, color='black')
Z=Z-Z.min()
Z=Z/Z.max()
from scipy.ndimage.interpolation import zoom
Xall=zoom(Xall,5)
Yall=zoom(Yall,5)
Z=zoom(Z,5)
cset = ax.plot_surface(Xall, Yall, np.zeros_like(Z)-0,facecolors=plt.cm.coolwarm(Z),shade=False,alpha=0.5,linewidth=False)
ax.set_xlim(-0.5, 31)
ax.set_ylim(6.9, 9.1)
ax.set_zlim(0, 500)
labelsx = [item.get_text() for item in ax.get_xticklabels()]
empty_string_labelsx = ['']*len(labelsx)
ax.set_xticklabels(empty_string_labelsx)
labelsy = [item.get_text() for item in ax.get_yticklabels()]
empty_string_labelsy = ['']*len(labelsy)
ax.set_yticklabels(empty_string_labelsy)
labelsz = [item.get_text() for item in ax.get_zticklabels()]
empty_string_labelsz = ['']*len(labelsz)
ax.set_zticklabels(empty_string_labelsz)
import matplotlib.ticker as ticker
ax.xaxis.set_major_locator(ticker.MultipleLocator(5))
ax.xaxis.set_minor_locator(ticker.MultipleLocator(1))
ax.yaxis.set_major_locator(ticker.MultipleLocator(0.5))
ax.yaxis.set_minor_locator(ticker.MultipleLocator(0.25))
ax.zaxis.set_major_locator(ticker.MultipleLocator(100))
ax.zaxis.set_minor_locator(ticker.MultipleLocator(50))
ax.tick_params(axis='z', which='major', pad=10)
ax.set_xlabel('X',labelpad=5,fontsize=15)
ax.set_ylabel('Y',labelpad=5,fontsize=15)
ax.set_zlabel('Z',labelpad=5,fontsize=15)
ax.view_init(elev=35., azim=-70)
fig.tight_layout()
plt.show()

Alternate possible answer.
This code demonstrates
A plot of a surface and its correponding wireframe
The creation of data and its plot of 3d lines (draped on the surface in 1) at specified values of x and y
Projections of the 3d lines (in 2) on to the frame walls
from mpl_toolkits.mplot3d import axes3d
import matplotlib.pyplot as plt
from scipy import interpolate
import numpy as np
# use the test data for plotting
fig = plt.figure(1, figsize=(6,6), facecolor='w', edgecolor='gray')
ax = fig.gca(projection='3d')
X, Y, Z = axes3d.get_test_data(0.1) #get 3d data at appropriate density
# create an interpolating function
# can take a long time if data is too large
f1 = interpolate.interp2d(X, Y, Z, kind='linear')
# in general, one can use a set of other X,Y,Z that cover a surface
# preferably, (X,Y) are in grid arrangement
# make up a new set of 3d data to plot
# ranges of x1, and y1 will be inside (X,Y) of the data obtained above
# related grid, x1g,y1g,z1g will be obtained from meshgrid and the interpolated function
x1 = np.linspace(-15,15,10)
y1 = np.linspace(-15,15,10)
x1g, y1g = np.meshgrid(x1, y1)
z1g = f1(x1, y1) #dont use (x1g, y1g)
# prep data for 3d line on the surface (X,Y,Z) at x=7.5
n = 12
x_pf = 7.5
x5 = x_pf*np.ones(n)
y5 = np.linspace(-15, 15, n)
z5 = f1(x_pf, y5)
# x5,y5,z5 can be used to plot 3d line on the surface (X,Y,Z)
# prep data for 3d line on the surface (X,Y,Z) at y=6
y_pf = 6
x6 = np.linspace(-15, 15, n)
y6 = x_pf*np.ones(n)
z6 = f1(x6, y_pf)
# x6,y6,z6 can be used to plot 3d line on the surface (X,Y,Z)
ax = fig.gca(projection='3d')
ax.plot_surface(x1g, y1g, z1g, alpha=0.25)
ax.plot_wireframe(x1g, y1g, z1g, rstride=2, cstride=2, color='black', zorder=10, alpha=1, lw=0.8)
# 3D lines that follow the surface
ax.plot(x5,y5,z5.flatten(), color='red', lw=4)
ax.plot(x6,y6,z6.flatten(), color='green', lw=4)
# projections of 3d curves
# project red and green lines to the walls
ax.plot(-15*np.ones(len(y5)), y5, z5.flatten(), color='red', lw=4, linestyle=':', alpha=0.6)
ax.plot(x6, 15*np.ones(len(x6)), z6.flatten(), color='green', lw=4, linestyle=':', alpha=0.6)
# projections on other sides (become vertical lines)
# change to if True, to plot these
if False:
ax.plot(x5, 15*np.ones(len(x5)), z5.flatten(), color='red', lw=4, alpha=0.3)
ax.plot(-15*np.ones(len(x6)), y6, z6.flatten(), color='green', lw=4, alpha=0.3)
ax.set_title("Projections of 3D lines")
# set limits
ax.set_xlim(-15, 15.5)
ax.set_ylim(-15.5, 15)
plt.show();

(Answer to question 1) To plot the intersections between the surface and the specified planes (y=-20, and y=20), one need to find what Y[?]=-20 and 20. By inspection, I found that Y[100]=20, Y[20]=-20.
The relevant code to plot the lines of intersection:
# By inspection, Y[100]=20, Y[20]=-20
ax.plot3D(X[100], Y[100], Z[100], color='red', lw=6) # line-1 at y=20
ax.plot3D(X[20], Y[20], Z[20], color='green', lw=6) # line-2 at y=-20
# Project them on Z=-100 plane
ax.plot3D(X[100], Y[100], -100, color='red', lw=3) # projection of Line-1
ax.plot3D(X[20], Y[20], -100, color='green', lw=3) # projection of Line-2
The output plot:
(Answer to question 2) To get better plot with the wireframe standout from the surface plot. The surface plot must be partially transparent, which is achieved by setting option alpha=0.6. The relevant code follows.
Z1 = Z-Z.min()
Z1 = Z1/Z.max()
Xall = zoom(X,3)
Yall = zoom(Y,3)
Zz = zoom(Z1, 3)
surf = ax.plot_surface(Xall, Yall, Zz, rstride=10, cstride=10,
facecolors = cm.jet(Zz/np.amax(Zz)),
linewidth=0, antialiased=True,
alpha= 0.6)
# Wireframe
ax.plot_wireframe(X, Y, Z, rstride=5, cstride=5, color='black', alpha=1, lw=0.8)
The plot is:

Related

plotting countour profiles in matplotlib

I have a data composed by three 1d-arrays (X,Y,Z) and I want to create a graph like the origin contour profile (https://www.originlab.com/doc/Origin-Help/Contour-Profile), where I have a 3d data plotted in a 2d contour, where the z value is represented by the graphic colors, and two other graphs representing profiles (or slices) of my surface for specific x and y-values. My problem is how to create the profiles.
I started by creating new x and y arrays and a grid surface for z by interpolating the data I had with scipy.interpolate.griddata
and now I can create the contour plot but I don't know how to create the profiles in xz and yz planes. I found out how to this in a 3d plot by using zdir=x and zdir=y (https://matplotlib.org/3.3.1/gallery/mplot3d/contour3d_3.html) but this works only for 3d graphs. I also know that I can trace the profile in the 'xy' plane for a specific z-value with ax.contour(x, y, z, [zvalue]). I want to do something similar to the 'xz' and 'yz' planes.
The code I have is this:
import pandas as pd
import numpy as np
import matplotlib.pyplot as plt
from matplotlib import cm
from scipy.interpolate import griddata
# reading the data
path = 'data/2019_12_11_15h17m29s_TZO_1Nd_3Hz_ref_900nm_900mW.txt_output.dat'
df = pd.read_csv(path)
X = df.position
Y = df.time
Z = df.signal
# interpolating data to create a surface
xi = np.linspace(X.min(), X.max(), 100)
yi = np.linspace(Y.min(), Y.max(), 100)
zi = griddata((X, Y), Z, (xi[None,:], yi[:,None]), method='linear')
zi = np.nan_to_num(zi)
# if I want to plot a 2D contour plot
fig = plt.figure()
ax = plt.axes()
ax.contourf(xi, yi, zi, levels=300, cmap="RdBu_r")
plt.show()
# if I want to plot a 3d surface with profiles
xi2, yi2 = np.meshgrid(xi, yi)
fig = plt.figure()
ax = fig.gca(projection='3d')
ax.plot_surface(xi2, yi2, zi, rstride=3, cstride=3, alpha=0.5)
cset = ax.contour(xi2, yi2, zi, zdir='x', offset=X.min()-30, cmap=cm.coolwarm, levels=10)
cset = ax.contour(xi2, yi2, zi, zdir='y', offset=Y.max()+30, cmap=cm.coolwarm, levels=10)
ax.set_xlim(X.min()-30, X.max()+30)
ax.set_ylim(Y.min()-30, Y.max()+30)
ax.set_zlim(Z.min(), Z.max())
plt.show()
# if I want to make a profile in xy plane:
fig = plt.figure()
ax = plt.axes()
ax.contour(xi, yi, zi, [1])
plt.show()
but I don't know how to create the profiles in 'xz' and 'yz' planes
I found myself a way of doing it that is not exactly what I was looking for but works perfectly. The idea is to fix a column/row of zi and plot against xi/yi to do a profile of the xz/yz plane. Varying the column/row in a for loop I got a result similar to levels of contour plot:
for i in range(0,len(zi),step):
z_xz = zi[i,:]
plt.plot(xi,z_xz)
and
for i in range(0,len(zi[0]),step):
z_xz = zi[:,i]
plt.plot(yi,z_xz)
please, let me know if you find a better solution

Matplotlib - create a scatter plot with points that fill the available space

I can create a scatter plot as follows:
fig, ax = plt.subplots()
x1 = [1, 1, 2]
y1 = [1, 2, 1]
x2 = [2]
y2 = [2]
ax.scatter(x1, y1, color="red", s=500)
ax.scatter(x2, y2, color="blue", s=500)
which gives
What I would like is something like the following (apologies for poor paint work):
I am plotting data that is all integer values, so they're all on a grid. I would like to be able to control the size of the scatter marker so that I could have white space around the points, or I could make the points large enough such that there would be no white space around them (as I have done in the above paint image).
Note - ideally the solution will be in pure matplotlib, using the OOP interface as they suggest in the documentation.
import matplotlib.pyplot as plt
import matplotlib as mpl
# X and Y coordinates for red circles
red_xs = [1,2,3,4,1,2,3,4,1,2,1,2]
red_ys = [1,1,1,1,2,2,2,2,3,3,4,4]
# X and Y coordinates for blue circles
blu_xs = [3,4,3,4]
blu_ys = [3,3,4,4]
# Plot with a small markersize
markersize = 5
fig, ax = plt.subplots(figsize=(3,3))
ax.plot(red_xs, red_ys, marker="o", color="r", linestyle="", markersize=markersize)
ax.plot(blu_xs, blu_ys, marker="o", color="b", linestyle="", markersize=markersize)
plt.show()
# Plot with a large markersize
markersize = 50
fig, ax = plt.subplots(figsize=(3,3))
ax.plot(red_xs, red_ys, marker="o", color="r", linestyle="", markersize=markersize)
ax.plot(blu_xs, blu_ys, marker="o", color="b", linestyle="", markersize=markersize)
plt.show()
# Plot with using patches and radius
r = 0.5
fig, ax = plt.subplots(figsize=(3,3))
for x, y in zip(red_xs, red_ys):
ax.add_patch(mpl.patches.Circle((x,y), radius=r, color="r"))
for x, y in zip(blu_xs, blu_ys):
ax.add_patch(mpl.patches.Circle((x,y), radius=r, color="b"))
ax.autoscale()
plt.show()

2D line not showing clearly along with surface on 3D plot

I am trying to plot a 1D line along with a 2D surface in matplotlib with Axes3D:
from mpl_toolkits.mplot3d import Axes3D
import numpy as np
import matplotlib.pyplot as plt
x = np.arange(-1., 1.1, 0.1)
y = x.copy()
X, Y = np.meshgrid(x, y)
Z = np.abs(X) + np.abs(Y)
plt.close('all')
fig = plt.figure()
ax = fig.gca(projection='3d')
ax.plot(np.zeros_like(y), y, 1, color='k')
ax.plot(x, np.zeros_like(x), 1, color='k')
surf = ax.plot_surface(X, Y, Z, color='w')
plt.show(block=False)
but the 2D plot somehow hides the lines:
If I comment the surf = plot_surface(...) code line, the 1D lines show correctly:
How can I have the lines showing correctly along with the surface?
Axes3D.plot_surface() apparently accepts a transparency (alpha) argument, which actually gets forwarded to a base class, Poly3DCollection.
And of course the line plot() calls accept a linewidth argument.
So if you render the line plots with thicker lines and you render the surface with some transparency, you should be able to find a combination of settings which let you see both the lines and the surface in a balanced way.
https://matplotlib.org/tutorials/toolkits/mplot3d.html#mpl_toolkits.mplot3d.Axes3D.plot_surface
https://matplotlib.org/api/_as_gen/mpl_toolkits.mplot3d.art3d.Poly3DCollection.html#mpl_toolkits.mplot3d.art3d.Poly3DCollection
You can also achieve this by using the zorder in the plot_surface and plot commands to make the lines sit on top of the surface. E.g.
from mpl_toolkits.mplot3d import Axes3D
import matplotlib.pyplot as plt
import numpy as np
x = np.arange(-1., 1.1, 0.1)
y = x.copy()
X, Y = np.meshgrid(x, y)
Z = np.abs(X) + np.abs(Y)
plt.close('all')
fig = plt.figure()
ax = fig.gca(projection='3d')
surf = ax.plot_surface(X, Y, Z, color='w', zorder=1)
ax.plot(np.zeros_like(y), y, 1, color='k', zorder=10)
ax.plot(x, np.zeros_like(x), 1, color='k', zorder=11)
plt.show(block=False)

Matplotlib 2d Plot on Faces of 3d Plot

I am producing plots of a spacecraft's trajectory at a specific point in its orbit.
I have a piece of code which produces a 3d line plot in 3dMatplotlib (a part of mycode and figure is shown here (I have drastically reduced the number of points within X,Y,Z to ~20 per array to make it easier to simply copy and paste as the principle is the same):
#
import matplotlib.pyplot as plt
from mpl_toolkits.mplot3d.axes3d import Axes3D
from numpy import *
XdS=[14.54156005, 14.53922242, 14.53688586, 14.53454823, 14.5322106 , 14.52987297, 14.52753426, 14.52519555, 14.52285792, 14.52051922, 14.51818051, 14.51584073, 14.51350095, 14.51116117, 14.5088214 , 14.50648162, 14.50414076, 14.50179991, 14.49945906, 14.49711821]
YdS=[31.13035144, 31.12920087, 31.12805245, 31.12690188, 31.12575131, 31.12460073, 31.12345016, 31.12229745, 31.12114473, 31.11999201, 31.1188393 , 31.11768443, 31.11652957, 31.11537471, 31.11421984, 31.11306283, 31.11190582, 31.11074882, 31.10959181, 31.1084348]
ZdS=[3.94109446, 3.94060316, 3.94011186, 3.93962083, 3.93912926, 3.93863796, 3.93814639, 3.93765482, 3.93716325, 3.93667169, 3.93617985, 3.93568828, 3.93519618, 3.93470434, 3.9342125 , 3.9337204 , 3.93322829, 3.93273592, 3.93224382, 3.93175144]
fig=plt.figure()
ax = fig.add_subplot(111, projection='3d')
ax.plot(XdS,YdS,ZdS,c='black',linewidth=2)
ax.set_xlabel('XKSM (Saturn Radii)')
ax.set_ylabel('YKSM (Saturn Radii)')
ax.set_zlabel('ZKSM (Saturn Radii)')
plt.show()
#
What I want to do is be able to plot the 2d plots X vs Y, X vs Z, and Y vs Z on the edges/planes of this plot i.e. show what the 3d trajectory looks like looking at it in the 3 2d planes and display them at each axis of the current plot. (It isn’t actually as complicated as it might sound, as I already have the X,Y,Z, values for the trajectory). Here I found a similar example which achieves this, however utilising all 3d plot functions, available at: http://matplotlib.org/1.3.1/examples/mplot3d/contour3d_demo3.html : If you check out check out the link it will show the type of image i am trying to achieve.
from mpl_toolkits.mplot3d import axes3d
import matplotlib.pyplot as plt
from matplotlib import cm
fig = plt.figure()
ax = fig.gca(projection='3d')
X, Y, Z = axes3d.get_test_data(0.05)
ax.plot_surface(X, Y, Z, rstride=8, cstride=8, alpha=0.3)
cset = ax.contour(X, Y, Z, zdir='z', offset=-100, cmap=cm.coolwarm)
cset = ax.contour(X, Y, Z, zdir='x', offset=-40, cmap=cm.coolwarm)
cset = ax.contour(X, Y, Z, zdir='y', offset=40, cmap=cm.coolwarm)
ax.set_xlabel('X')
ax.set_xlim(-40, 40)
ax.set_ylabel('Y')
ax.set_ylim(-40, 40)
ax.set_zlabel('Z')
ax.set_zlim(-100, 100)
plt.show()
This is in theory exactly what I need, in the way it takes sort of a planar view of the 3d situation. However I cannot implement a 2d line plot on a 3d axis nor can I use the offset command in a 2d plot (getting the error: TypeError: There is no line property "offset").
Is there a 2d equivalent to the 3d “offset” command and Is it possible to plot the 2d values on the planes of the 3d plot as I desire? Also is there a way to plot 2d lines having initialised a 3d projection? Can anyone offer any ideas/point me in any direction in general to help me achieve this?
My sincere thanks in advance and apologies if any part of this post is out of order, this is my first one!
Try this:
xmin = min(XdS)
ymax = max(YdS)
zmin = min(ZdS)
length_of_array = len(XdS)
xmin_array = [xmin] * length_of_array
ymax_array = [ymax] * length_of_array
zmin_array = [zmin] * length_of_array
fig=plt.figure()
ax = fig.add_subplot(111, projection='3d')
ax.plot(XdS,YdS,ZdS,zdir='z', c='r')
ax.plot(XdS,YdS,zmin_array, zdir='z', c='g')
ax.plot(xmin_array, YdS, ZdS, 'y')
ax.plot(XdS,ymax_array,ZdS,'b')
ax.set_xlabel('XKSM (Saturn Radii)')
ax.set_ylabel('YKSM (Saturn Radii)')
ax.set_zlabel('ZKSM (Saturn Radii)')
plt.show()

Matplotlib 3D scatter plot with color gradient

How can I create a 3D plot with a color gradient for the points? See the example below, which works for a 2D scatter plot.
Edit (thanks to Chris): What I'm expecting to see from the 3D plot is a color gradient of the points ranging from red to green as in the 2D scatter plot.
What I see in the 3D scatter plot are only red points.
Solution: for some reasons (related to the gradient example I copied elsewhere) I set xrange to len-1, which messes everything in the 3D plot.
import numpy as np
import matplotlib.pyplot as plt
from mpl_toolkits.mplot3d import Axes3D
# Create Map
cm = plt.get_cmap("RdYlGn")
x = np.random.rand(30)
y = np.random.rand(30)
z = np.random.rand(30)
#col = [cm(float(i)/(29)) for i in xrange(29)] # BAD!!!
col = [cm(float(i)/(30)) for i in xrange(30)]
# 2D Plot
fig = plt.figure()
ax = fig.add_subplot(111)
ax.scatter(x, y, s=10, c=col, marker='o')
# 3D Plot
fig = plt.figure()
ax3D = fig.add_subplot(111, projection='3d')
ax3D.scatter(x, y, z, s=10, c=col, marker='o')
plt.show()
Here is an example for 3d scatter with gradient colors:
import matplotlib.cm as cmx
from mpl_toolkits.mplot3d import Axes3D
def scatter3d(x,y,z, cs, colorsMap='jet'):
cm = plt.get_cmap(colorsMap)
cNorm = matplotlib.colors.Normalize(vmin=min(cs), vmax=max(cs))
scalarMap = cmx.ScalarMappable(norm=cNorm, cmap=cm)
fig = plt.figure()
ax = Axes3D(fig)
ax.scatter(x, y, z, c=scalarMap.to_rgba(cs))
scalarMap.set_array(cs)
fig.colorbar(scalarMap)
plt.show()
Of course, you can choose the scale to range between different values, like 0 and 1.
Following works: I can't figure out why yours doesn't. You should be able to set color as a sequence of RGBA floats, or just sequence of floats.
# Create Map
cm = plt.get_cmap("RdYlGn")
x = np.random.rand(30)
y = np.random.rand(30)
z = np.random.rand(30)
col = np.arange(30)
# 2D Plot
fig = plt.figure()
ax = fig.add_subplot(111)
ax.scatter(x, y, s=10, c=col, marker='o')
# 3D Plot
fig = plt.figure()
ax3D = fig.add_subplot(111, projection='3d')
p3d = ax3D.scatter(x, y, z, s=30, c=col, marker='o')
plt.show()
However, in help of scatter, I see the following, it may be related.
A :class:`matplotlib.colors.Colormap` instance or registered
name. If *None*, defaults to rc ``image.cmap``. *cmap* is
only used if *c* is an array of floats.

Categories