Matplotlib - contour plot - python

I am struggling a bit with contour plot in matplotlib. I've read through the instructions and example but can't seem to figure out what I need to do.
I have x, y, z data. The data is basically as follows:
x y z
1.1 2.1 0
0.9 3.2 1
2.6 4.1 0
3.1 1.1 1
0.3 0.9 1
...
It is a long list of x-y coordinates and at each point it is a 0-1. The use case is balls(1), strikes(0) crossing the strikezone in baseball. When I plot the data using plt.hexbin you see the following:
What I want to do is to plot a contour at the 50% line. Like this imagine below:
I was hoping to use contour but I am unclear how I can get the data is a sufficient format to draw the contour plot and use 'levels' to plot just the 50% contour. Apparently the function contour(X,Y,Z) requires 2-D arrays so based on the data I have I am unclear on what exactly I need to do.
Is there a way I can put the data I have into a function to get the contour plot I want, like with hexbin?

First you need to create a meshgrid from your x and y data:
X,Y = np.meshgrid(data[:,0], data[:,1])
Then you can interpolate the z grid:
# Choose one option
# Z = griddata((data[:,0], data[:,1]), data[:,2], (X, Y), method='nearest')
Z = griddata((data[:,0], data[:,1]), data[:,2], (X, Y), method='linear')
# Z = griddata((data[:,0], data[:,1]), data[:,2], (X, Y), method='cubic')
And plot the data using contour with the specified level at 0.5:
levels = 0.5
contour(X,Y,Z,levels)
Let me know if this approach worked out for you.

Related

Visualization using pcolormesh in python

in my script I use plt.pcolormesh to visualize my data.
The following code is a simplification, but should help me to explain my problem.
In the example I created two vectors X and Y, both containing values from 0 to 9.
X and Y represent coordinates.
Z is defined to have the value 2, only the points between the X/Y-coordinates 3 and (including) 6 get the value 4.
Hence, Z can be seen as value for each coordinate.
My aim is to use plt.pcolormesh to color the area between these coordinates in a different color than the surrounding area.
But if I use plt.pcolormesh, also the quadrant above and to the right of the X/Y-coordinate is colored.
I know that I simply could change the definition of my X/Y-variables, but this isn't possible in my original code.
Thus, I want you to ask if there is a function in python which works similar to plt.pcolormesh, but only colors the area between my defined coordinates?
I hope, someone can help me ;)
X, Y = np.mgrid[slice(0,10,1), slice(0,10,1)]
Z = 2 * np.ones((10,10))
Z[3:7,3:7] = 4
plt.figure()
plt.pcolormesh(X, Y, Z, cmap=cm.rainbow)
plt.title('Test Meshgrid')
plt.colorbar()
Best regards,
Kai

Plotting 3D points with Python Matploltlib

I want to create a small simulation, and I think I know how, but in order to actually see what happens I need to visualize it.
I started with a 5x5x5 array, which I want to fill up with values.
data = numpy.zeros(shape=(5,5,5))
data[:,:,0]=4
data[:,:,1]=3
data[:,:,2]=2
data[:,:,3]=1
data[:,:,4]=0
This should create a cube which has a gradient in the upward direction (if the third axis is z).
Now, how can I plot this? I dont want a surface plot, or wireframe. Just Points on each coordinate, and maybe colorcoded or transperency by value.
As a test I tried plotting all coordinates using
ax.scatter(numpy.arange(5),numpy.arange(5),numpy.arange(5))
but this will only plot a line consisting of 5 dots.
So... how can I get the 125 dots, that I want to create?
Thx.
You can encode the value in color like this:
x = np.arange(5)
X, Y, Z = np.meshgrid(x,x,x)
v = np.arange(125)
ax.scatter(X,Y,Z, c=v)
See here for the documention.

Return z coordinate when x and y coordinates given as arguments in matplotlib

I have been searching the documentation of matplotlib for a very long time now and I can't find a function that can do this for me. I have plotted a matrix and used bicubic interpolation to make it into a smooth graph, and I would like to be able to find the z coordinate of a point when I give the x and y coordinates. For example:
plt.some_function(1.5, 2)
Where 1.5 is the x coordinate and 2 is the y coordinate, would produce the result:
3
Where 3 is the z coordinate of that point.

Plotting a 3D Cylindrical Surface plot in Python

I am trying to create a cylindrical 3D surface plot using Python, where my independent variables are z and theta, and the dependent variable is radius (i.e., radius is a function of vertical position and azimuth angle).
So far, I have only been able to find ways to create a 3D surface plot that:
has z as a function of r and theta
has r as a function of z, but does not change with theta (so, the end product looks like a revolved contour; for example, the case of r = sin(z) + 1 ).
I would like to have r as a function of z and theta, because my function will produce a shape that, at any given height, will be a complex function of theta.
On top of that, I need the surface plot be able to have (but does not have to have, depending on the properties of the function) an open top or bottom. For example, if r is constant from z = 0 to z = 1 (a perfect cylinder), I would want a surface plot that would only consist of the side of the cylinder, not the top or bottom. The plot should look like a hollow shell.
I already have the function r defined.
Thanks for any help!
Apparently, after some trial and error, the best/easiest thing to do in this case is to just to convert the r, theta, and z data points (defined as 2D arrays, just like for an x,y,z plot) into cartesian coordinates:
# convert to rectangular
x = r*numpy.cos(theta)
y = r*numpy.sin(theta)
z = z
The new x,y,z arrays can be plotted just like any other x,y,z arrays generated from a polynomial where z is a function of x,y. I had originally thought that the data points would get screwed up because of overlapping z values or maybe the adjacent data points would not be connected correctly, but apparently that is not the case.

Basemap streamplot blank sphere

I want to make a streamplot in Basemap module, but I get a blank sphere. Please help me resolve this problem. I use matplotlib 1.3 and ordinary streamplot is working fine.
import matplotlib.pyplot as plt
import numpy as np
from mpl_toolkits.basemap import Basemap
map = Basemap(projection='ortho',lat_0=45,lon_0=-100,resolution='l')
# draw lat/lon grid lines every 30 degrees.
map.drawmeridians(np.arange(0,360,30))
map.drawparallels(np.arange(-90,90,30))
# prepare grids
lons = np.linspace(0, 2*np.pi, 100)
lats = np.linspace(-np.pi/2, np.pi/2, 100)
lons, lats = np.meshgrid(lons, lats)
# parameters for vector field
beta = 0.0
alpha = 1.0
u = -np.cos(lats)*(beta - alpha*np.cos(2.0*lons))
v = alpha*(1.0 - np.cos(lats)**2)*np.sin(2.0*lons)
speed = np.sqrt(u*u + v*v)
# compute native map projection coordinates of lat/lon grid.
x, y = map(lons*180./np.pi, lats*180./np.pi)
# contour data over the map.
cs = map.streamplot(x, y, u, v, latlon = True, color = speed, cmap=plt.cm.autumn, linewidth=0.5)
plt.show()
I can't exactly tell you what's wrong, but from the matplotlib.streamplot manual:
matplotlib.pyplot.streamplot(x, y, u, v, density=1, linewidth=None,
color=None, cmap=None, norm=None, arrowsize=1, arrowstyle=u'-|>',
minlength=0.1, transform=None, zorder=1, hold=None)ΒΆ
Draws streamlines of a vector flow.
x, y : 1d arrays
an evenly spaced grid.
u, v : 2d arrays
x and y-velocities. Number of rows should match length of y, and the number of columns should match x.
Additionally from matplotlib.basemap.streamplot you can read that
If latlon keyword is set to True, x,y are intrepreted as longitude and latitude in degrees.
Which corresponds to the fact that x and y should be 1D arrays (lat, lon). However in your example x and y are
>>> np.shape(x)
(100, 100)
>>> np.shape(y)
(100, 100)
Then again you call the method map() "to compute native map projection coordinates of lat/lon grid" which is coincidentally the same as the name of your basemap.map. So it depends on which one do you want? Because both will return a value! (or better to say, both will return an error)
Aditionally check out the values you have in your u array. They are of range e-17. While other values are easily in the range e+30. IIRC the way you get streamlines is by solving a differential equation in which points you sent it as values are used as parameters at coordinates you sent. It's not hard to imagine a that while calculating something with these numbers a floating point round-off occurs and you suddenly start getting NaN or 0 values.
Try to scale your example better or if you want to pursue the solution to the end you can try and use np.seterr to get a more detailed idea where it fails.
Sorry I couldn't have been of a bigger help.

Categories