Plotting a Heatmap with Python - python

I want to generate a heatmap using Python.
The map should be like this:
I have a numpy array with dimension (n,n) and each "cell" contains a certain value. The higher higher that value is, the bigger a pink square should be.
How can I plot this kind of chart using matplotlib? Are there other libraries that I can use?
Thank you.

You could try this
n = 8
x = np.arange(n)
y = np.arange(n)
X, Y = np.meshgrid(x, y)
Z = np.random.randint(0, 800, (len(x), len(y)))
plt.figure()
plt.axes(aspect='equal')
plt.scatter(X+.5, Y+.5, Z, 'pink', marker='s')
plt.grid()
plt.xlim(0, n)
plt.ylim(0, n)
plt.tick_params(labelsize=0, length=0)

Related

Plot a surface passing through all the data points in 3D space - Python

I am not really sure if this is possible to do, but essentially I have a list of data corresponding to x, y and z coordinates.
Below image shows the result when I plot these points using a scatter graph (which I created using Python pyplot library).
My question is, is there any way of plotting the graph of a plane that passes through all of these points instead of plotting them as single points?
When I searched online all I found was resources telling me how to find equation of plane passing though 3 points but as you can see I have many points.
Any help will be appreciated.
Let's say that to have your plot you use this code
fig, ax = plt.subplots(subplot_kw=dict(projection='3d'))
ax.scatter(x, y, z)
plt.show()
and let's say that you know nrows, ncols, the number of rows (y) and columns (x) of your base grid.
If these assumptions are correct, then you can use this code to plot a surface connecting the points
fig, ax = plt.subplots(subplot_kw=dict(projection='3d'))
ax.plot_surface(*(v.reshape(nrows, ncols) for v in (x, y, z)))
plt.xlabel('x') ; plt.ylabel('y')
plt.show()
or, if you want something fancier,
fig, ax = plt.subplots(subplot_kw=dict(projection='3d'),
layout='constrained')
surf = ax.plot_surface(*(v.reshape(nrows, ncols) for v in(x, y, z)),
cmap='Blues_r', ec='gray', lw=0.2)
plt.xlabel('x') ; plt.ylabel('y')
plt.colorbar(surf)
plt.show()
The prelude to my code, if you want to check my results, is
import numpy as np
import matplotlib.pyplot as plt
nrows, ncols = 63, 126
x = np.linspace(0, 12.5, ncols)
y = np.linspace(-6.2, 6.2, nrows)
X, Y = np.meshgrid(x, y)
x, y = (V.flatten() for V in (X, Y))
z = np.sin(x)-np.cos(y)
fig, ax = ...
...

Plot 4D Contour in Python (X,Y,Z + Data)

I have a large set of measurements that I want to visualize in 4D using matplotlib in Python.
Currently, my variables are arranged in this way:
x = np.array(range(0, v1))
y = np.array(range(0, v2))
z = np.array(range(0, v3))
I have C which is a 3D array containing measurement values for each combination of the previous variables. So it has a dimension of v1*v2*v3.
Currently, I visualize my measurements using contourf function and I plot that for each z value. This results in 3D contour plot i.e. 2D + color map for the values. Now, I want to combine all the variables and look at the measurements in 4D dimensions (x, y, z, and color corresponding to the measurement value). What is the most efficient way to do this in python?
Regarding to #Sameeresque answer, I think the question was about a 4D graph like this (three coordinates x, y, z and a color as the fourth coordinate):
import numpy as np
import matplotlib.pyplot as plt
# only for example, use your grid
z = np.linspace(0, 1, 15)
x = np.linspace(0, 1, 15)
y = np.linspace(0, 1, 15)
X, Y, Z = np.meshgrid(x, y, z)
# Your 4dimension, only for example (use yours)
U = np.exp(-(X/2) ** 2 - (Y/3) ** 2 - Z ** 2)
# Creating figure
fig = plt.figure()
ax = plt.axes(projection="3d")
# Creating plot
ax.scatter3D(X, Y, Z, c=U, alpha=0.7, marker='.')
plt.show()
A 4D plot with (x,y,z) on the axis and the fourth being color can be obtained like so:
from mpl_toolkits.mplot3d import Axes3D
import matplotlib.pyplot as plt
import numpy as np
fig = plt.figure()
ax = fig.add_subplot(111, projection='3d')
x = np.array(range(0, 50))
y = np.array(range(0, 50))
z = np.array(range(0, 50))
colors = np.random.standard_normal(len(x))
img = ax.scatter(x, y, z, c=colors, cmap=plt.hot())
fig.colorbar(img)
plt.show()
A simple way to visualize your 4D function, call it W(x, y, z), could be producing a gif of the cross-section contour plots along the z-axis.
Package plot4d could help you do it. An example plotting an isotropic 4D function:
from plot4d import plotter
import numpy as np
plotter.plot4d(lambda x,y,z:x**2+y**2+z**2, np.linspace(0,1,20), wbounds=(0,3), fps=5)
The code above generates this gif:

How to change the axis dimension from pixel to length in matplotlib? is there any code in general?

Since the complete simulation is to big to post it right here only the code to plot the spectrum is given (I think this is enough)
d = i.sum(axis=2)
pylab.figure(figsize=(15,15))
pylab = imshow(d)
plt.axis('tight')
pylab.show()
This spectrum is given in pixel. But I would like to have this in the units of length. I will hope you may give me some advices.
Do you mean that you want axis ticks to show your custom dimensions instead of the number of pixels in d? If yes, use the extent keyword of imshow:
import numpy
import matplotlib
matplotlib.use('Agg')
import matplotlib.pyplot as plt
d = numpy.random.normal(size=(20, 40))
fig = plt.figure()
s = fig.add_subplot(1, 1, 1)
s.imshow(d, extent=(0, 1, 0, 0.5), interpolation='none')
fig.tight_layout()
fig.savefig('tt.png')
I'm guess a bit at what your problem is, so let's start by stating my interpretation/ You have some 2D data d that you plot using imshow and the units on the x and y axes are in the number of pixels. For example in the following we see the x axis labelled from 0 -> 10 for the number of data points:
import numpy as np
import matplotlib.pyplot as plt
# Generate a fake d
x = np.linspace(-1, 1, 10)
y = np.linspace(-1, 1, 10)
X, Y = np.meshgrid(x, y)
d = np.sin(X**2 + Y**2)
plt.imshow(d)
If this correctly describes your issue, then the solution is to avoid using imshow, which is designed to plot images. Firstly this will help as imshow attemps to interpolate to give a smoother image (which may hide features in the spectrum) and second because it is an image, there is no meaningful x and y data so it doesn't plot it.
The best alternative would be to use plt.pcolormesh which generate a psuedocolor plot of a 2D array and takes as arguments X and Y, which are both 2D arrays of points to which the values of d correspond.
For example:
# Generate a fake d
x = np.linspace(-1, 1, 10)
y = np.linspace(-1, 1, 10)
X, Y = np.meshgrid(x, y)
d = np.sin(X**2 + Y**2)
plt.pcolormesh(X, Y, d)
Now the x and y values correspond to the values of X and Y.

Plot of 3D matrix with colour scale - Python

I would like to plot a 3D matrix - essentially a box of numbers, each labelled by an x, y, z triad of coordinates- by assigning a different colour to each of the x, y, z point, according to its magnitude (for example, bigger numbers in red and smaller numbers in blue).
I cannot plot sections of the matrix, I rather need to plot the whole matrix together.
If we call matrix3D my matrix, its elements are built this way:
matrix3D[x][y][z] = np.exp(-(x**2+y**2+z**2))
How can I obtain the desired plot?
EDIT: Using Mayavi2 Contour3D(), I have tried to write the following:
from mayavi import mlab
X = np.arange(0, n_x, 1)
Y = np.arange(0, n_z, 1)
Z = np.arange(0, n_z, 1)
X, Y, Z = np.meshgrid(X, Y, Z)
obj = mlab.contour3d(X, Y, Z, matrix3D, contours=4, transparent=True)
where n_x, n_y, n_z are the dimension of the 3 axes. How can I actually see and/or save the image now?
If you need to plot the whole thing I think you're best taking a look at mayavi. This will let you plot a volume and you should be able to get the results you need.
I know you said you need to plot the whole thing at once, but this might still be of some use. You can use countourf to plot like this:
import numpy as np
import matplotlib.pyplot as plt
matrix3D = np.empty((10, 10, 10))
x = np.arange(10)
y = np.arange(10)
z = np.arange(10)
matrix3D[x][y][z] = np.exp(-(x**2+y**2+z**2))
fig = plt.figure()
ax = fig.add_subplot(plt.subplot(1, 1, 1))
ax.contourf(x, y, matrix3D[:, :, 3])
plt.show()
This gives you a slice of the 3D matrix (in this example the 4th slice).

Connect the points to zero for missing points

I have a dataset like this,where I have a set of values for xs and I plot the corresponding line graph with the values of ys.
xs = np.array([1,2,5,6,9,10,11)
ys = pow(xs,2)
ys
plt.plot(xs, ys, linestyle='-', marker='o')
plt.show()
If you notice by default, plot connects the points and draws line. But, I want to draw the line at 0 for missing points. How do I do this ? Should I manipulate the data to fill missing values with zeros (numpy,maybe) or is there a way to plot this matplotlib.plot ?
To be precise I need to plot: xs = np.array([1,2,0,0,5,6,0,0,9,10,11,0,0,0,0])
ys = pow(xs,2)
But, as of now, this is my xs=np.array([1,2,5,6,9,10,11). How do i fill the missing elements in the range 1:15. I looked at masked_array which is different. Is there any other fill option in numpy ?
Since you want to plot points that aren't in your data set, it will be hard to do directly in matplotlib. But, constructing the points is easy enough using put:
xs = array([1,2,5,6,9,10,11])
ys = xs**2
x = arange(12)
y = zeros(12, dtype=int32)
put(y, xs, ys)
plt.plot(x, y, 'o', clip_on=False)
If you aren't dealing with an integer X axis, you can do this:
xs = array([1.0,2,5,6,9,10,11])
ys = xs**2
x = arange(0, 12, 0.5)
y = zeros(x.shape)
mask = r_[diff(searchsorted(xs, x)), 0]
y[mask == 1] = ys
plt.plot(x, y, 'o', clip_on=False)

Categories