I seem unable to solve this problem. I have multiple sets of data with the same x,y points. I do Delaunay triangulation and plot it with tripcolor. I read on this forum, that to plot several sets of data into the same plot, I need to specify the axis and stuff, but it doesn't seem to work for me here (beginner at matplotlib, sorry). My code:
import matplotlib.pyplot as plt
import matplotlib.tri as tri
from pylab import genfromtxt
data=genfromtxt("momentAF.txt")
data2=genfromtxt("momentZZ.txt")
x = data[:,0]
y = data[:,1]
z1 = data[:,4]
z2 = data2[:,4]
circle=plt.Circle((0,0),1,color="black",fill=False)
triang = tri.Triangulation(x, y)
ax = plt.subplot(111)
ax.set_aspect('equal')
ax.add_artist(circle)
ax.tripcolor(triang, z2**2, shading='gouraud', cmap='Greens')
ax.tripcolor(triang, z1**2, shading='gouraud', cmap='Reds')
#plt.colorbar()
plt.title("ST, G'=-0.0")
Any help is greatly appreciated, thanks.
EDIT:
A rough example of what I'm going for:
EDIT2: I tried to display the several data sets without setting transparency for all of them using colormap option "set_under":
my_cmap = cm.get_cmap("Greens")
my_cmap2 = cm.get_cmap("Reds")
my_cmap.set_under('w',alpha=0)
my_cmap2.set_under('w',alpha=0)
and then
ax.tripcolor(triang, z1**2, shading='gouraud', cmap=my_cmap, vmin=0.01)
ax.tripcolor(triang, z2**2, shading='gouraud', cmap=my_cmap2, vmin=0.01)
but it still only shows the region where z1 is non-zero (i.e. the region where z1 is non-zero is overwritten by white from my_cmap2, which I wanted to be transparent). I also tried masked arrays,
masked = np.ma.masked_where(z1<.1,z3**2)
masked2 = np.ma.masked_where(z2<.1,z4**2)
ax.tripcolor(triang, masked, shading='gouraud', cmap="Greens")
ax.tripcolor(triang, masked2, shading='gouraud', cmap="Reds")
still to no avail though.
It's not that it does not work, it is just that you are plotting twice the same triangulation, only changing the color (the argument coming after triang in tripcolor signature is the color of the data points).
The next argument must be C, the array of color values, either one per point in the triangulation if color values are defined at points, or one per triangle in the triangulation if color values are defined at triangles. If there are the same number of points and triangles in the triangulation it is assumed that color values are defined at points; to force the use of color values at triangles use the kwarg facecolors*=C instead of just *C.
So what your code below is doing is plotting the triangulation triang
with color level z1**2
of cmap Greens
, then plotting on top of it the exact same triangulation, just changing the color levels to z2**2
and cmap to Reds
.
ax.tripcolor(triang, z2**2, shading='gouraud', cmap='Greens')
ax.tripcolor(triang, z1**2, shading='gouraud', cmap='Reds')
So of course, you can only see the last plotted (the red) since it's exactly covering the first plotted (the green). You might be able to see both using transparency with alpha
:
ax.tripcolor(triang, z2**2, shading='gouraud', cmap='Greens', alpha=0.5)
ax.tripcolor(triang, z1**2, shading='gouraud', cmap='Reds', alpha=0.5)
But the end result will be a mixture of colors (with predominance of the last plotted), I am not sure that is what you want...
Just like cphlewis said, it will be easier to understand what you want if you show what kind of data you use, and what kind of result you want.
EDIT :
I think I found a way to do what you want using mask :
import matplotlib.pyplot as plt
import matplotlib.tri as tri
x = np.random.uniform(-0.7,0.7,10)
y = np.random.uniform(-0.7,0.7,10)
z1 = np.random.uniform(-1,1,10)
z2 = - z1
circle=plt.Circle((0,0),1,color="black",fill=False)
triang1 = tri.Triangulation(x, y)
triang2 = tri.Triangulation(x, y)
mask1 = np.logical_or.reduce(( np.where(z1[triang1.triangles]<=0, 1,0).T ))
mask2 = np.logical_or.reduce(( np.where(z2[triang2.triangles]<=0, 1,0).T ))
triang1.set_mask(mask1)
triang2.set_mask(mask2)
ax = plt.subplot(111)
ax.set_aspect('equal')
ax.add_artist(circle)
t1 = ax.tripcolor(triang1, z1, shading='gouraud', cmap=matplotlib.cm.Greens, alpha=0.5)
t2 = ax.tripcolor(triang2, z2, shading='gouraud', cmap=matplotlib.cm.Reds, alpha=0.5)
Basically, you create a mask, and set it and triang1
, which will control which triangle are displayed.
triang2.triangles
is the list of triangle (actually a 3*nb_of_triangles array, basically it's an array of vertices). z2[triang2.triangles]
gives you the corresponding zlevel for each vertice. np.where(z2[triang2.triangles]<=0,1,0).T
test if the vertice level is zero, so if it should be masked or not. The np.logical_or.reduce
do a logical or, so that a triangle is masked if at least one of its vertices is masked (so basically, only triangles with their vertices visible are not masked).
Note that there might be some way to implement transparency by directly editing t1._facecolors
, but I can't really see how those are calculated...