I have a dataset which consists of three values (x, y, z).
z is a value given by a specific function of x and y that I don't have access to.
The data points are
(500,10,1.543),(500,20,1.432) ... (500,100,0.534) , (600,10,1.232),(600,20,1.432) ... till x value reaches (5000,100,0.032)
I want to plot it using a contour plot.
I tried:
x = np.array(a[0]) # Your x values
y = np.array(a[1]) # Your y values
z = np.array(a[2]) # Corresponding z values
# Create a grid of coordinates
xi = np.linspace(x.min(), x.max(), 100)
yi = np.linspace(y.min(), y.max(), 100)
Xi, Yi = np.meshgrid(xi, yi)
# Interpolate z values onto the grid
from scipy.interpolate import griddata
Zi = griddata((x, y), z, (Xi, Yi), method='linear')
# Create the contour plot
plt.figure(figsize=(10, 8))
plt.contourf(Xi, Yi, Zi, cmap='viridis')
contours = plt.contour(Xi, Yi, Zi, levels=10, colors='black')
# Add colorbar
plt.colorbar(label='Z Value')
# Add scatter plot of original data points
plt.scatter(x, y, color='red', alpha=0.5)
# Add labels and title
plt.title('Contour Plot of X-Y-Z Data')
plt.xlabel('X')
plt.ylabel('Y')
# Add labels to contours
plt.clabel(contours, inline=True, fontsize=10)
plt.show()
The error I get is:
"message": "QH6013 qhull input error: input is less than 3-dimensional since all points have the same x coordinate 50
If your data is in the array a
, and you have 46 points [500, 600, ..., 4900, 5000]
on the x axis and 10 points [10, 20, ..., 90, 100]
on the y axis, you can reshape the rows to a form suitable to be contoured
X, Y, Z = [arr.reshape(46, 10) for arr in a]
next, it's just
filled = plt.contourf(X, Y, Z)
contours = plt.contour(X, Y, Z)
plt.colorbar(filled)
plt.clabel(contours)
The top figure was generated using this code
import matplotlib.pyplot as plt
import numpy as np
from itertools import product
# generate fake data
a = np.array([[x, y, z] for z, (x, y) in
enumerate(product(range(500, 5001, 100), range(10, 101, 10)))]).T
# unpack data in 3 46×10 arrays
X, Y, Z = np.array([v.reshape(46, 10) for v in a])
# prepare for plotting
levels = 11
colors = ['w']*(levels//2+1)
colors += ['k']*((levels//2+1) if levels%2 else levels//2)
# plotting
filled = plt.contourf(X, Y, Z, levels=levels)
plt.colorbar(filled)
contours = plt.contour(X, Y, Z,
levels=levels, linewidths=0.75,
colors=colors)
plt.clabel(contours, fontsize=11)
plt.show()
The choice of colors for the contour lines/labels in the code above works for perceptually uniform colormaps, dark to light, and you need to rework the choice if it's a light to dark colormap or it's a diverging colormaps. Don't use 'jet' ;-)