I have 3 different parameters X,Y and Z over a range of values, and for each combination of these a certain value of V. To make it clearer, the data would look something like this.
X Y Z V
1 1 2 10
1 2 3 15
etc...
I'd like to visualize the data with a surface/contour plot, using V as a colour to see its value at that point, but I do not see how to add my custom colouring scheme into the mix using Python. Any idea on how to do this (or is this visualization outright silly)?
Thanks a lot!
It really depends on how you plan on plotting this data. I like to plot graphs with
gnuplot
: it's easy, free and intuitive. To plot your example withgnuplot
you'd have to print those line into a file (with only those four columns) and plot using a code like the followingAssuming that you save your data into the file
file.txt
.splot
stands for surface plot. Of course, this is a minimum example.Alternatively you can use
matplotlib
, but that is not, in my opinion, as intuitive. Although it has the advantage of centering all the processing in python.Matplotlib allows one to pass the facecolors as an argument to e.g.
ax.plot_surface
.That would imply then that you would have to perform 2D interpolation on your current array of colors, because you currently only have the colors in the corners of the rectangular faces (you did mention that you have a rectilinear grid).
You could use
scipy.interpolate.interp2d
for that, but as you see from the documentation, it is suggested to usescipy.interpolate.RectBivariateSpline
.To give you a simple example:
Now I have a similar dataset as you (one-dimensional arrays for
x, y, z
andcolors
). Remark that the colors are defined for each point (x,y). But when you want to plot withplot_surface
, you'll generate rectangular patches, of which the corners are given by those points.So, on to interpolation then:
In this last step, you could also have used
interp2d
(withkind='linear'
replacing thekx=1, ky=1
). But since the docs suggest to use the fasterRectBivariateSpline
...Now you're ready to plot it:
As you can see, the colors on the faces have nothing to do anymore with the height of the dataset.
Note that you could have thought simply passing the 2D array C to
facecolors
would work, and matplotlib would not have complained. However, the result isn't accurate then, because matplotlib will use only a subset of C for the facecolors (it seems to ignore the last column and last row of C). It is equivalent to using only the color defined by one coordinate (e.g. the top-left) over the entire patch.An easier method would have been to let matplotlib do the interpolation and obtain the facecolors and then pass those in to the real plot:
However, that won't work in releases <= 1.4.1 due to this recently submitted bug.