I'm coding with python.
I have 3 arrays x, y and z, and I would like to do 2d density map of the z values in the plan (x,y) with colorbar.
So in my plot, the color at the point x[0] and y[0] would be determined by the value of z[0], the color at the point x[1] and y[1] would be determined by the value of z[1], etc.
Does anyone know how to do this ?
Thank you
Check out https://matplotlib.org/api/_as_gen/matplotlib.pyplot.scatter.html
For different colormaps: https://matplotlib.org/tutorials/colors/colormaps.html
A sample piece of code for your need will be something like this
#--------------------------Plotting starts here---------------------------------#
fig, ax0 = plt.subplots()
im0 = plt.scatter(x,y,s=1,c=z, cmap='bwr')
#------------------if you want to use pcolormesh-------------------
#----------and have Z values stored as a numpy array Data---------------------#
#X,Y = np.meshgrid(x,y)
#im0 = ax0.pcolormesh(X,Y,Data, cmap="YourFavouriteColormap')
cbar = fig.colorbar(im0,ax=ax0)
ax0.set_title("Your title")
plt.xlabel("xlabel")
plt.ylabel("ylabel")
filename = "prefix" + "."+ "fileformat"
plt.savefig(filename)
Edit 1:
From one of your comments, if you have grid data, you can try pcolormesh and try shading, an optional argument for interpolation.
shading{'flat', 'gouraud'}, optional
The fill style, Possible values:
'flat': A solid color is used for each quad. The color of the quad (i, j), (i+1, j), (i, j+1), (i+1, j+1) is given by C[i, j].
'gouraud': Each quad will be Gouraud shaded: The color of the corners (i', j') are given by C[i',j']. The color values of the area in between is interpolated from the corner values. When Gouraud shading is used, edgecolors is ignored.
You can use matplotlib's scatter plots with legends and grid where the size of each circle can be referred to z values. This is an example I got from here:
volume = np.random.rayleigh(27, size=40)
amount = np.random.poisson(10, size=40)
ranking = np.random.normal(size=40)
price = np.random.uniform(1, 10, size=40)
fig, ax = plt.subplots()
scatter = ax.scatter(volume, amount, c=ranking, s=0.3*(price*3)**2,
vmin=-3, vmax=3, cmap="Spectral")
legend1 = ax.legend(*scatter.legend_elements(num=5),
loc="upper left", title="Ranking")
ax.add_artist(legend1)
kw = dict(prop="sizes", num=5, color=scatter.cmap(0.7), fmt="$ {x:.2f}",
func=lambda s: np.sqrt(s/.3)/3)
legend2 = ax.legend(*scatter.legend_elements(**kw),
loc="lower right", title="Price")
plt.show()
Output:
In response to your comment AshlinJP :
Either way I still got the error message : "imshow() got multiple values for keyword argument 'cmap'"
I don't know if it has any importance but I use python 2.7
Actually my code is :
import numpy as np
import matplotlib.pyplot as plt
x,y,z = np.loadtxt('gamma.txt', unpack = True)
fig, ax0 = plt.subplots()
cmap = plt.get_cmap('viridis')
im0 = ax0.imshow(x,y,z, cmap=cmap, interpolation="gaussian")
cbar = fig.colorbar(im0,ax=ax0)
ax0.set_title("Your title")
plt.xlabel("xlabel")
plt.ylabel("ylabel")
Related
I am plotting from a CSV file that contains Cartesian coordinates and I want to change it to Polar coordinates, then plot using the Polar coordinates.
Here is the code
import matplotlib.pyplot as plt
import pandas as pd
import numpy as np
import seaborn as sns
df = pd.read_csv('test_for_plotting.csv',index_col = 0)
x_temp = df['x'].values
y_temp = df['y'].values
df['radius'] = np.sqrt( np.power(x_temp,2) + np.power(y_temp,2) )
df['theta'] = np.arctan2(y_temp,x_temp)
df['degrees'] = np.degrees(df['theta'].values)
df['radians'] = np.radians(df['degrees'].values)
ax = plt.axes(polar = True)
ax.set_aspect('equal')
ax.axis("off")
sns.set(rc={'axes.facecolor':'white', 'figure.facecolor':'white','figure.figsize':(10,10)})
# sns.scatterplot(data = df, x = 'x',y = 'y', s= 1,alpha = 0.1, color = 'black',ax = ax)
sns.scatterplot(data = df, x = 'radians',y = 'radius', s= 1,alpha = 0.1, color = 'black',ax = ax)
plt.tight_layout()
plt.show()
Here is the dataset
If you run this command using polar = False and use this line to plot sns.scatterplot(data = df, x = 'x',y = 'y', s= 1,alpha = 0.1, color = 'black',ax = ax) it will result in this picture
now after setting polar = True and run this line to plot sns.scatterplot(data = df, x = 'radians',y = 'radius', s= 1,alpha = 0.1, color = 'black',ax = ax) It is supposed to give you this
But it is not working as if you run the actual code the shape in the Polar format is the same as Cartesian which does not make sense and it does not match the picture I showed you for polar (If you are wondering where did I get the second picture from, I plotted it using R)
I would appreciate your help and insights and thanks in advance!
For a polar plot, the "x-axis" represents the angle in radians. So, you need to switch x and y, and convert the angles to radians (I also added ax=ax, as the axes was created explicitly):
import matplotlib.pyplot as plt
import pandas as pd
import numpy as np
import seaborn as sns
data = {'radius': [0, 0.5, 1, 1.5, 2, 2.5], 'degrees': [0, 25, 75, 155, 245, 335]}
df_temp = pd.DataFrame(data)
ax = plt.axes(polar=True)
sns.scatterplot(x=np.radians(df_temp['degrees']), y=df_temp['radius'].to_numpy(),
s=100, alpha=1, color='black', ax=ax)
for deg, y in zip(df_temp['degrees'], df_temp['radius']):
x = np.radians(deg)
ax.axvline(x, color='skyblue', ls=':')
ax.text(x, y, f' {deg}', color='crimson')
ax.set_rlabel_position(-15) # Move radial labels away from plotted dots
plt.tight_layout()
plt.show()
About your new question: if you have an xy plot, and you convert these xy values to polar coordinates, and then plot these on a polar plot, you'll get again the same plot.
After some more testing with the data, I decided to create the plot directly with matplotlib, as seaborn makes some changes that don't have exactly equal effects across seaborn and matplotlib versions.
What seems to be happening in R:
The angles (given by "x") are spread out to fill the range (0,2 pi). This either requires a rescaling of x, or change how the x-values are mapped to angles. One way to get this, is subtracting the minimum. And with that result divide by the new maximum and multiply by 2 pi.
The 0 of the angles it at the top, and the angles go clockwise.
The following code should create the plot with Python. You might want to experiment with alpha and with s in the scatter plot options. (Default the scatter dots get an outline, which often isn't desired when working with very small dots, and can be removed by lw=0.)
ax = plt.axes(polar=True)
ax.set_aspect('equal')
ax.axis('off')
x_temp = df['x'].to_numpy()
y_temp = df['y'].to_numpy()
x_temp -= x_temp.min()
x_temp = x_temp / x_temp.max() * 2 * np.pi
ax.scatter(x=x_temp, y=y_temp, s=0.05, alpha=1, color='black', lw=0)
ax.set_rlim(y_temp.min(), y_temp.max())
ax.set_theta_zero_location("N") # set zero at the north (top)
ax.set_theta_direction(-1) # go clockwise
plt.show()
At the left the resulting image, at the right using the y-values for coloring (ax.scatter(..., c=y_temp, s=0.05, alpha=1, cmap='plasma_r', lw=0)):
I have a set of x,y values for two curves on excel sheets.
Using xlrd module, I have been able to plot them as below:
Question:
How do I shade the three areas with different fill colors? Had tried with fill_between but been unsuccessful due to not knowing how to associate with the x and y axes. The end in mind is as diagram below.
Here is my code:
import xlrd
import numpy as np
import matplotlib.pyplot as plt
workbook = xlrd.open_workbook('data.xls')
sheet = workbook.sheet_by_name('p1')
rowcount = sheet.nrows
colcount = sheet.ncols
result_data_p1 =[]
for row in range(1, rowcount):
row_data = []
for column in range(0, colcount):
data = sheet.cell_value(row, column)
row_data.append(data)
#print(row_data)
result_data_p1.append(row_data)
sheet = workbook.sheet_by_name('p2')
rowcount = sheet.nrows
colcount = sheet.ncols
result_data_p2 =[]
for row in range(1, rowcount):
row_data = []
for column in range(0, colcount):
data = sheet.cell_value(row, column)
row_data.append(data)
result_data_p2.append(row_data)
x1 = []
y1 = []
for i,k in result_data_p1:
cx1,cy1 = i,k
x1.append(cx1)
y1.append(cy1)
x2 = []
y2 = []
for m,n in result_data_p2:
cx2,cy2 = m,n
x2.append(cx2)
y2.append(cy2)
plt.subplot(1,1,1)
plt.yscale('log')
plt.plot(x1, y1, label = "Warm", color = 'red')
plt.plot(x2, y2, label = "Blue", color = 'blue')
plt.xlabel('Color Temperature (K)')
plt.ylabel('Illuminance (lm)')
plt.title('Kruithof Curve')
plt.legend()
plt.xlim(xmin=2000,xmax=7000)
plt.ylim(ymin=10,ymax=50000)
plt.show()
Please guide or lead to other references, if any.
Thank you.
Here is a way to recreate the curves and the gradients. It resulted very complicated to draw the background using the logscale. Therefore, the background is created in linear space and put on a separate y-axis. There were some problems getting the background behind the rest of the plot if it were drawn on the twin axis. Therefore, the background is drawn on the main axis, and the plot on the second axis. Afterwards, that second y-axis is placed again at the left.
To draw the curves, a spline is interpolated using six points. As the interpolation didn't give acceptable results using the plain coordinates, everything was interpolated in logspace.
The background is created column by column, checking where the two curves are for each x position. The red curve is extended artificially to have a consistent area.
import numpy as np
import matplotlib.pyplot as plt
import matplotlib.ticker as mticker
from scipy import interpolate
xmin, xmax = 2000, 7000
ymin, ymax = 10, 50000
# a grid of 6 x,y coordinates for both curves
x_grid = np.array([2000, 3000, 4000, 5000, 6000, 7000])
y_blue_grid = np.array([15, 100, 200, 300, 400, 500])
y_red_grid = np.array([20, 400, 10000, 500000, 500000, 500000])
# create interpolating curves in logspace
tck_red = interpolate.splrep(x_grid, np.log(y_red_grid), s=0)
tck_blue = interpolate.splrep(x_grid, np.log(y_blue_grid), s=0)
x = np.linspace(xmin, xmax)
yr = np.exp(interpolate.splev(x, tck_red, der=0))
yb = np.exp(interpolate.splev(x, tck_blue, der=0))
# create the background image; it is created fully in logspace
# the background (z) is zero between the curves, negative in the blue zone and positive in the red zone
# the values are close to zero near the curves, gradually increasing when they are further
xbg = np.linspace(xmin, xmax, 50)
ybg = np.linspace(np.log(ymin), np.log(ymax), 50)
z = np.zeros((len(ybg), len(xbg)), dtype=float)
for i, xi in enumerate(xbg):
yi_r = interpolate.splev(xi, tck_red, der=0)
yi_b = interpolate.splev(xi, tck_blue, der=0)
for j, yj in enumerate(ybg):
if yi_b >= yj:
z[j][i] = (yj - yi_b)
elif yi_r <= yj:
z[j][i] = (yj - yi_r)
fig, ax2 = plt.subplots(figsize=(8, 8))
# draw the background image, set vmax and vmin to get the desired range of colors;
# vmin should be -vmax to get the white at zero
ax2.imshow(z, origin='lower', extent=[xmin, xmax, np.log(ymin), np.log(ymax)], aspect='auto', cmap='bwr', vmin=-12, vmax=12, interpolation='bilinear', zorder=-2)
ax2.set_ylim(ymin=np.log(ymin), ymax=np.log(ymax)) # the image fills the complete background
ax2.set_yticks([]) # remove the y ticks of the background image, they are confusing
ax = ax2.twinx() # draw the main plot using the twin y-axis
ax.set_yscale('log')
ax.plot(x, yr, label="Warm", color='crimson')
ax.plot(x, yb, label="Blue", color='dodgerblue')
ax2.set_xlabel('Color Temperature')
ax.set_ylabel('Illuminance (lm)')
ax.set_title('Kruithof Curve')
ax.legend()
ax.set_xlim(xmin=xmin, xmax=xmax)
ax.set_ylim(ymin=ymin, ymax=ymax)
ax.grid(True, which='major', axis='y')
ax.grid(True, which='minor', axis='y', ls=':')
ax.yaxis.tick_left() # switch the twin axis to the left
ax.yaxis.set_label_position('left')
ax2.grid(True, which='major', axis='x')
ax2.xaxis.set_major_formatter(mticker.StrMethodFormatter('{x:.0f} K')) # show x-axis in Kelvin
ax.text(5000, 2000, 'Pleasing', fontsize=16)
ax.text(5000, 20, 'Appears bluish', fontsize=16)
ax.text(2300, 15000, 'Appears reddish', fontsize=16)
plt.show()
I have a matrix generated by parsing a file the numpy array is the size 101X101X41 and each entry has a value which represents the magnitude at each point.
Now what I want to do is to plot it in a 3d plot where the 4th dimension will be represented by color. so that I will be able to see the shape of the data points (represent molecular orbitals) and deduce its magnitude at that point.
If I plot each slice of data I get the desired outcome, but in a 2d with the 3rd dimension as the color.
Is there a way to plot this model in python using Matplotlib or equivalent library
Thanks
EDIT:
Im trying to get the question clearer to what I desire.
Ive tried the solution suggested but ive received the following plot:
as one can see, due to the fact the the mesh has lots of zeros in it it "hide" the 3d orbitals. in the following plot one can see a slice of the data, where I get the following plot:
So as you can see I have a certain structure I desire to show in the plot.
my question is, is there a way to plot only the structure and ignore the zeroes such that they won't "hide" the structure.
the code I used to generate the plots:
x = np.linspase(1,101,101)
y = np.linspase(1,101,101)
z = np.linspase(1,101,101)
xx,yy,zz = np.meshgrid(x,y,z)
fig=plt.figure()
ax = fig.add_subplot(111, projection='3d')
ax.scatter(xx, yy, zz, c=cube.calc_data.flatten())
plt.show()
plt.imshow(cube.calc_data[:,:,11],cmap='jet')
plt.show()
Hope that now the question is much clearer, and that you'd appreciate the question enough now to upvote
Thanks.
you can perform the following:
fig = plt.figure()
ax = fig.add_subplot(111, projection='3d')
epsilon = 2.5e-2 # threshold
height, width, depth = data.shape
global_min = np.inf
global_max = -np.inf
for d in range(depth):
slice = data[:, :, d]
minima = slice.min()
if (minima < global_min): global_min = minima
maxima = slice.max()
if (maxima>global_max): global_max=maxima
norm = colors.Normalize(vmin=minima, vmax=maxima, clip=True)
mapper = cm.ScalarMappable(norm=norm, cmap=cm.jet)
points_gt_epsilon = np.where(slice >= epsilon)
ax.scatter(points_gt_epsilon[0], points_gt_epsilon[1], d,
c=mapper.to_rgba(data[points_gt_epsilon[0],points_gt_epsilon[1],d]), alpha=0.015, cmap=cm.jet)
points_lt_epsilon = np.where(slice <= -epsilon)
ax.scatter(points_lt_epsilon[0], points_lt_epsilon[1], d,
c=mapper.to_rgba(data[points_lt_epsilon[0], points_lt_epsilon[1], d]), alpha=0.015, cmap=cm.jet)
ax.set_xlabel('X Label')
ax.set_ylabel('Y Label')
ax.set_zlabel('Z Label')
plt.title('Electron Density Prob.')
norm = colors.Normalize(vmin=global_min, vmax=global_max, clip=True)
cax, _ = colorbar.make_axes(ax)
colorbar.ColorbarBase(cax, cmap=cm.jet,norm=norm)
plt.savefig('test.png')
plt.clf()
What this piece of code does is going slice by slice from the data matrix and for each scatter plot only the points desired (depend on epsilon).
in this case you avoid plotting a lot of zeros that 'hide' your model, using your words.
Hope this helps
You can adjust the color and size of the markers for the scatter. So for example you can filter out all markers below a certain threshold by putting their size to 0. You can also make the size of the marker adaptive to the field strength.
As an example:
import numpy as np
import matplotlib.pyplot as plt
from mpl_toolkits.mplot3d import Axes3D
f = lambda x,y,z: np.exp(-(x-3)**2-(y-3)**2-(z-1)**2) - \
np.exp(-(x+3)**2-(y+3)**2-(z+1)**2)
t1 = np.linspace(-6,6,101)
t2 = np.linspace(-3,3,41)
# Data of shape 101,101,41
data = f(*np.meshgrid(t1,t1,t2))
print(data.shape)
# Coordinates
x = np.linspace(1,101,101)
y = np.linspace(1,101,101)
z = np.linspace(1,101,41)
xx,yy,zz = np.meshgrid(x,y,z)
fig=plt.figure()
ax = fig.add_subplot(111, projection='3d')
s = np.abs(data/data.max())**2*25
s[np.abs(data) < 0.05] = 0
ax.scatter(xx, yy, zz, s=s, c=data.flatten(), linewidth=0, cmap="jet", alpha=.5)
plt.show()
I have some z=f(x,y) data which i would like to plot. The issue is that (x,y) are not part of a "nice" rectangle, but rather arbitrary parallelograms, as shown in the attached image (this particular one is also a rectangle, but you could think of more general cases). So I am having a hard time figuring out how I can use plot_surface in this case, as this usually will take x and y as 2d arrays, and here my x-and y-values are 1d. Thanks.
Abritrary points can be supplied as 1D arrays to matplotlib.Axes3D.plot_trisurf. It doesn't matter whether they follow a specific structure.
Other methods which would depend on the structure of the data would be
Interpolate the points on a regular rectangular grid. This can be accomplished using scipy.interpolate.griddata. See example here
Reshape the input arrays such that they live on a regular and then use plot_surface(). Depending on the order by which the points are supplied, this could be a very easy solution for a grid with "parallelogramic" shape.
As can be seen from the sphere example, plot_surface() also works in cases of very unequal grid shapes, as long as it's structured in a regular way.
Here are some examples:
For completeness, find here the code that produces the above image:
import matplotlib.pyplot as plt
from mpl_toolkits.mplot3d import Axes3D
import numpy as np
f = lambda x,y: np.sin(x+0.4*y)*0.23+1
fig = plt.figure(figsize=(5,6))
plt.subplots_adjust(left=0.1, top=0.95,wspace=0.01)
ax0 = fig.add_subplot(322, projection="3d")
ma = 6*(np.random.rand(100)-0.5)
mb = 6*(np.random.rand(100)-0.5)
phi = np.pi/4
x = 1.7*ma*np.cos(phi) + 1.7*mb*np.sin(phi)
y = -1.2*ma*np.sin(phi) +1.2* mb*np.cos(phi)
z = f(x,y)
ax0.plot_trisurf(x,y,z)
ax1 = fig.add_subplot(321)
ax0.set_title("random plot_trisurf()")
ax1.set_aspect("equal")
ax1.scatter(x,y, marker="+", alpha=0.4)
for i in range(len(x)):
ax1.text(x[i],y[i], i , ha="center", va="center", fontsize=6)
n = 10
a = np.linspace(-3, 3, n)
ma, mb = np.meshgrid(a,a)
phi = np.pi/4
xm = 1.7*ma*np.cos(phi) + 1.7*mb*np.sin(phi)
ym = -1.2*ma*np.sin(phi) +1.2* mb*np.cos(phi)
shuf = np.c_[xm.flatten(), ym.flatten()]
np.random.shuffle(shuf)
x = shuf[:,0]
y = shuf[:,1]
z = f(x,y)
ax2 = fig.add_subplot(324, projection="3d")
ax2.plot_trisurf(x,y,z)
ax3 = fig.add_subplot(323)
ax2.set_title("unstructured plot_trisurf()")
ax3.set_aspect("equal")
ax3.scatter(x,y, marker="+", alpha=0.4)
for i in range(len(x)):
ax3.text(x[i],y[i], i , ha="center", va="center", fontsize=6)
x = xm.flatten()
y = ym.flatten()
z = f(x,y)
X = x.reshape(10,10)
Y = y.reshape(10,10)
Z = z.reshape(10,10)
ax4 = fig.add_subplot(326, projection="3d")
ax4.plot_surface(X,Y,Z)
ax5 = fig.add_subplot(325)
ax4.set_title("regular plot_surf()")
ax5.set_aspect("equal")
ax5.scatter(x,y, marker="+", alpha=0.4)
for i in range(len(x)):
ax5.text(x[i],y[i], i , ha="center", va="center", fontsize=6)
for axes in [ax0, ax2,ax4]:
axes.set_xlim([-3.5,3.5])
axes.set_ylim([-3.5,3.5])
axes.set_zlim([0.9,2.0])
axes.axis("off")
plt.savefig(__file__+".png")
plt.show()
If your data is in order, and you know the size of the parallgram, a reshape will probably suffice:
ax.surface(x.reshape(10, 10), y.reshape(10, 10), z.reshape(10, 10))
Will work if the parallelogram has 10 points on each side, and the points are ordered in a zigzag pattern
we are building our reports on matplotlib. Each page has multiple charts and some text.
In the report data there is over 100 locations, each location has a density. The idea is to plot the points on a map where the color (shade of red) represents the density of the location.
However, I do not understand the connection between the kwargs : c and cmap in the ax.scatter call, nor do I understand the role of color.Normalize in this application.
import pandas as pd
import matplotlib
import numpy as np
from pandas import Series, DataFrame
import csv
from scipy import stats
import matplotlib.pyplot as plt
import random
import matplotlib.colors as colors
# Get the data and transform
data = pd.read_csv('logHistThis.csv')
data.drop('Unnamed: 0', axis=1, inplace=True)
dataMean = data['Density'].mean()
data = list(data['Density'])
# I was under the impresion that the data for the colormap
# had to be between 1 and 0 so did this:
aColorScale = []
def myColorScale(theData):
aColorScale = []
for x in theData:
this = x/100
aColorScale.append(this)
return aColorScale
aColorScale = myColorScale(data)
estimated_mu, estimated_sigma = stats.norm.fit(data)
xmin = min(data)
xmax = max(data)
x = np.linspace(xmin, xmax, 100)
pdf = stats.norm.pdf(x, loc=estimated_mu, scale=estimated_sigma)
thisRangeMin = np.log(27)
thisRangeMax = np.log(35)
q = [np.random.choice(data, 40)]
z = [ np.random.randint(1, 50, size=40)]
s = 100 *q
colormap = 'Reds'
normalize =matplotlib.colors.Normalize(vmin=xmin, vmax=xmax)
#plt.scatter(x,y,z,s=5, cmap=colormap, norm=normalize, marker='*')
fig = plt.figure(figsize=(10, 5), frameon=False, edgecolor='000000', linewidth = 1)
rect0 = .05, .05, .4, .9
rect1 = .5, .05, .4, .9
# This works great
ax1 = fig.add_axes(rect0)#<-----------x2TopTenSummary
ax1.hist(data, bins=13, normed=True, color='c', alpha=0.05)
#ax1.fill_between(x, pdf, where=(), alpha=.2)
ax1.fill_between(x, pdf, where=((x < thisRangeMax) & ( x > thisRangeMin)), alpha=.2, label='City Range')
ax1.vlines(dataMean, 0, stats.norm.pdf(dataMean, loc=estimated_mu, scale=estimated_sigma), color='r')
ax1.plot(x, pdf, 'k')
# This does not work :
# It just gives blue dots
ax2= fig.add_axes(rect1)
ax2= fig.add_axes(rect1)
ax2.scatter(q,z, s=200, cmap= 'Reds',norm=matplotlib.colors.Normalize(vmin=min(aColorScale) , vmax=max(aColorScale)))
# Tried to set the color map in a variety of ways:
# When kwarg 'c' is set to the variable 'aColorScale' i get the error
plt.show()
plt.close()
So my question is how do we incorporate the colormap in an application of this sort?
Multiple axes on a figure with a predetermined size (A4 or letter).
The color determination is a third variable z, (not x or y)
The color determinant is a float where 0 < z < 8
the call is ax not plt
The description of the application in the docs is unclear to me:
the doc for axes.scatter
the doc for color.normalize
I have seen plenty of examples where there is only one ax in the figure and the call is to plt.scatter... for example here
In our case x, y will be longitude, lattitude and the variable is 'data' a list or array of floats between 0 and 8.
Thanks
Okay the answer came from the PyCon Israel 2017 in this document by Tamir Lousky.
The normalization of the data and the correlation with color map happens with this block of code right here:
aColorScale = data
aColorScale = np.array(aColorScale)
norm = (aColorScale - aColorScale.min())/(aColorScale.max() - aColorScale.min())
cmap= plt.get_cmap('Reds')
colors = [cmap(tl) for tl in norm]#<---- thisRightHere
Then colors gets fed into ax2:
ax2= fig.add_axes(rect1)
ax2.scatter(q,z, s=200, color = colors)
I wish those who downvoted my question would say why, there was hours of searching and trying to find this.
Anyway here is the final image:
While I do have problems understanding the issue itself, I can tell you that the solution you have in your answer can be simplified to the usual way to plot scatters:
ax2= fig.add_axes(rect1)
ax2.scatter(q,z, c=aColorScale, s=200, cmap='Reds')