Plot x,y,data in a heatmap with matplotlib - python

I'm having some trouble to plot data in a 2D heatmap using matplotlib.
The code is the following:
from ugtm import eGTM
import numpy as np
from sklearn import preprocessing
import matplotlib.pyplot as plt
from scipy.interpolate import griddata
X_train = np.random.randn(100, 50)
X_test = np.random.randn(50, 50)
gtm = eGTM().fit(X_train)
responsibilities = gtm.optimizedModel.matR
nodes_cumulated_responsibilities = preprocessing.MinMaxScaler().fit_transform(np.sum(gtm.optimizedModel.matR,0).reshape(-1,1))
nodes_coordinates = gtm.optimizedModel.matX
transformed = eGTM().fit(X_train).transform(X_test)
Z, xedges, yedges = np.histogram2d(nodes_coordinates[:,0], nodes_coordinates[:,1],normed=True,
bins=15,weights=nodes_cumulated_responsibilities[:,0])
plt.figure()
plt.pcolormesh(xedges, yedges,Z.T,cmap='bone_r')
plt.scatter(transformed[:,0],transformed[:,1],color='r')
plt.title('np.hist2d')
I have the "nodes_coordinates" array shape(256,2) which represents the coordinates x,y of the nodes. Then i have "nodes_cumulated_responsibilities" array shape(256,1) representing the value of each node in the respective x,y coordinate. I also have a "transformed" array shape(50,2) representing 50 cells that "X_test" hitted in the heatmap by the eGTM.
Resuming, i would like to make a heatmap using nodes_coordinates and nodes_cumulated_responsibilities as background, and then plot in this map a scatter plot of the "X_test" hitted nodes on the heatmap.
But i want the scatter plot to be in the center of the node for any X_train or any X_test.. This is whats i don't know how to do.
Some points for this code:
The size of the map is 16x16 by default for any size of X_test, but it can be set to any integer, thus the map can be any nxn.
The plt.pcolormesh needs the np.histogram2d to get a meshgrid with edges added to it. But i don't like to use np.histogram2d since i need to pass the 'bins' argument to adjust the heatmap correctly and i suspected it could lead me to some wrong maps or scatters.
The np.meshgrid gives me a meshgrid for the heatmap but without the edges, so i cant use this with pcolormesh.
The approach to use the plt.imshow to plot the heatmap using the np.meshgrid seems more trustable. But i don't know how to convert the 1D array "nodes_cumulated_responsibilities" to a 256x256 array.
A very similiar example of what i want to do is in: https://github.com/JustGlowing/minisom/blob/master/examples/BasicUsage.ipynb
Example of heatmap with scatter plot

Related

Python contour plot in traditional 3D data?

I've been using Python/NumPy for a lot of things for a while now, but I am still confused about creating 3D plots.
In a "traditional" data analysis program (Origin, SigmaPlot, Excel...), if you want to make a 3D plot or a contour plot, you usually have your data in (X,Y,Z) format, that is, for each pair of X and Y you have one value of Z.
As opposed to this, all Python plotting guides I find use numpy.meshgrid for plotting -and I don't fully understand the connection to the traditional plotting software.
Let's say I have the following code:
axes_range = np.linspace(-5, 5, num=25)
alphas = []
for xcoord in axes_range:
for ycoord in axes_range:
alphas.append(f(xcoord,ycoord))
What's the best way of making a plot of (xcoord, ycoord, alphas)?
With matplotlib you simply need
import matplotlib.pylab as plt
import numpy as np
from matplotlib import cm
X, Y = np.meshgrid(xcoord, ycoord)
plt.contourf(X, Y, alphas.T, levels=20, cmap=cm.jet)
plt.show()
I think you need to transpose alphas as I do here.

Coloring by 2D location in 3D scatter plot

I have a 3D scatter plot of first three principal components plotted by matplotlib.pyplot. For each point plotted, I also have a separate 2x1 numpy array which depicts its location in a 2D environment.
Is it possible to use the 2x1 arrays to introduce colouring by location in my 3D scatter plot?
This is an approximation of my code:
import numpy as np
import matplotlib.pyplot as plt
def plotThreeComponents():
lv_1 = np.array([0,1,2,3,7])
lv_2 = np.array([3,2,1,0,7])
lv_3 = np.array([0,1,0,5,7])
location = np.array([[5,7,0,4,7],
[1,1,2,4,7]])
plt.figure()
ax = plt.axes(projection='3d')
ax.scatter3D(lv_1, lv_2, lv_3, c=location, s = 4)
ax.set_xlabel('PC1')
ax.set_ylabel('PC2')
ax.set_zlabel('PC3')
plt.show()
pass
plotThreeComponents()
I also tried to add this to the function:
colorList = []
for i in range(location.shape[1]):
colorList.append(location[:,i])
To generate a list where each element is an array of shape (2, )
and then changed
ax.scatter3D(lv_1, lv_2, lv_3, c=colorList, s = 4)
However, I am still getting an Error message stating that "'c' argument has 10 elements, which is inconsistent with 'x' and 'y' with size 5.", even if len(colorList) = 5
Column vectors of 'location' array depict coordinates in 2D space.
Location and lv_1, lv_2, lv_3 are linked indirectly.
what should be 'c' in 'ax.scatter3D' so that I get coloring by 2D location?
Thank you for any suggestions.

4D Density Plot in Python

I am looking to plot some density maps from some grid-like data:
X,Y,Z = np.mgrids[-5:5:50j, -5:5:50j, -5:5:50j]
rho = np.random.rand(50,50,50) #for the sake of argument
I am interested in producing an interpolated density plot as shown below, from Mathematica here, using Python.
Is there any solution in Matplotlib or another plotting suite for this sort of plot?
To be clear, I do not want a scatterplot of coloured points, which is not suitable the plot I am trying to make. I would like a 3D interpolated density plot, as shown below.
Plotly
Plotly Approach from https://plotly.com/python/3d-volume-plots/ uses np.mgrid
import plotly.graph_objects as go
import numpy as np
X, Y, Z = np.mgrid[-8:8:40j, -8:8:40j, -8:8:40j]
values = np.sin(X*Y*Z) / (X*Y*Z)
fig = go.Figure(data=go.Volume(
x=X.flatten(),
y=Y.flatten(),
z=Z.flatten(),
value=values.flatten(),
isomin=0.1,
isomax=0.8,
opacity=0.1, # needs to be small to see through all surfaces
surface_count=17, # needs to be a large number for good volume rendering
))
fig.show()
Pyvista
Volume Rendering example:
https://docs.pyvista.org/examples/02-plot/volume.html#sphx-glr-examples-02-plot-volume-py
3D-interpolation code you might need with pyvista:
interpolate 3D volume with numpy and or scipy

matplotlib imshow how to plot points instead of image?

Here is the code:
plots=imshow(Z,extent=extent,origin,cmap=cmap,aspect='auto',vmin=vmin,vmax=vmax)
plots.plot(Response,component,vrange)
It plots an image based on data list Z, how can I let it print data points instead of an image?
Looks like needs to change to scatter(x, y,...) to plot data points, how difficult it is to change array Z to x, y?
As #jdj081 said, you want to produce a scatter plot.
import os.path
import matplotlib
import matplotlib.pyplot as plt
import numpy as np
# get an image from the sample data directory
fname = os.path.join(matplotlib.get_data_path(), 'sample_data', 'lena.png')
im = plt.imread(fname)
# Reduce the data by a factor of 4 (so that we can see the points)
im = im[::4, ::4]
# generate coordinates for the image. Note that the image is "top down", so the y coordinate goes from high to low.
ys, xs = np.mgrid[im.shape[0]:0:-1, 0:im.shape[1]]
# Scatter plots take 1d arrays of xs and ys, and the colour takes a 2d array,
# with the second dimension being RGB
plt.scatter(xs.flatten(), ys.flatten(), s=4,
c=im.flatten().reshape(-1, 3), edgecolor='face')
plt.show()
You didn't provide much information to go on, but it sounds like you really want to create a scatter plot.
There are many options here depending on what you are plotting and what you want to see, but I have found the following helpful:
Fixing color in scatter plots in matplotlib
import pylab
pylab.figure(1)
pylab.plot([1,2,3,4],[1,7,3,5]) # draw on figure one
pylab.show() # show figure on screen

Matplotlib : quiver and imshow superimposed, how can I set two colorbars?

I have a figure that consists of an image displayed by imshow(), a contour and a vector field set by quiver(). I have colored the vector field based on another scalar quantity. On the right of my figure, I have made a colorbar(). This colorbar() represents the values displayed by imshow() (which can be positive and negative in my case). I'd like to know how I could setup another colorbar which would be based on the values of the scalar quantity upon which the color of the vectors is based. Does anyone know how to do that?
Here is an example of the image I've been able to make. Notice that the colors of the vectors go from blue to red. According to the current colorbar, blue means negative. However I know that the quantity represented by the color of the vector is always positive.
Simply call colorbar twice, right after each plotting call. Pylab will create a new colorbar matching to the latest plot. Note that, as in your example, the quiver values range from 0,1 while the imshow takes negative values. For clarity (not shown in this example), I would use different colormaps to distinguish the two types of plots.
import numpy as np
import pylab as plt
# Create some sample data
dx = np.linspace(0,1,20)
X,Y = np.meshgrid(dx,dx)
Z = X**2 - Y
Z2 = X
plt.imshow(Z)
plt.colorbar()
plt.quiver(X,Y,Z2,width=.01,linewidth=1)
plt.colorbar()
plt.show()
Running quiver doesn't necessarily return the type of mappable object that colorbar() requires. I think it might be because I explicitly "have colored the vector field based on another scalar quantity" like Heimdall says they did. Therefore, Hooked's answer didn't work for me.
I had to create my own mappable for the color bar to read. I did this by using Normalize from matplotlib.colors on the data that I wanted to use to color my quiver vectors (which I'll call C, which is an array of the same shape as X, Y, U, and V.)
My quiver call looks like this:
import matplotlib.pyplot as pl
import matplotlib.cm as cm
import matplotlib.colors as mcolors
import matplotlib.colorbar as mcolorbar
pl.figure()
nz = mcolors.Normalize()
nz.autoscale(C)
pl.quiver(X, Y, U, V, color=cm.jet(nz(C)))
cax,_ = mcolorbar.make_axes(pl.gca())
cb = mcolorbar.ColorbarBase(cax, cmap=cm.jet, norm=nz)
cb.set_label('color data meaning')
Giving any other arguments to the colorbar function gave me a variety of errors.

Categories

Resources