Han Zhengzu
Han Zhengzu

Reputation: 3852

Plotting pcolormesh with a bunch of 2-d arrays with different color

Here is my question

Sorry for the confused expression.

Just check my update. It's more clear.

1. Intro

It shows like this:

### mask the value 0 of data[1,:,:]
data_mask = np.ma.masked_less(data[[1,:,:],0.001)
pc =plt.pcolor(xx,yy,data_mask[i,:,:],alpha =1,facecolor = "pink",edgecolor = 'steelblue',zorder =3)
## plotting the grid line
mesh =plt.pcolor(xx,yy,data[1,:,:],cmap="gray",alpha =0.45,facecolor = "none",edgecolor = 'k')       

Sorry, China don't allow me using imgur
(source: tietuku.com)

2. My attempt


(source: tietuku.com)

3. My code

Two 2-d array for example.

(source: tietuku.com)

cs=plt.cm.jet(np.arange(2)/2.)     
for i in range(0,2,1):
    data_mask = np.ma.masked_less(data[i,:,:],0.001)
    plt.pcolor(xx,yy, data_mask[i,:,:],alpha =0.95,facecolor = cs[i],edgecolor = 'k',zorder =3)      

result

(source: tietuku.com)

These figure all seemed that the color setting was wrong.

4. My question

  1. How to set the pcolor grid color? In my example, using facecolor = didn't work. And I know using cmap = plt.cm.xxx works(picture below). But I must plot this two 2-d array separately.


(source: tietuku.com)

  1. As I said in 'My attempt 2', Is there a method to testify the overlapping and label these grid in some smart way.

What I can figure out was generating another np.array named 'overlap' and save the information of each grid

for i in range(0,data.shape[1],1):
    for j in range(0,dat.shape[2],1):
        if (data[0,i,j] == 1) & (data[1,i,j] == 1.0):
            overlap[i,j] = 1       

When there are more than two 2-d array, this method couldn't cope with.

Update -2016-01-17

I summarize my question into one figure with the code which generate it:

cover_mask = np.ma.masked_less(data[0,:,:],0.001)
plt.pcolor(xx,yy,data_mask[0,:,:],cmap = plt.cm.Set1,alpha =0.75,\
           edgecolor = 'k',zorder =3)      

cover_mask = np.ma.masked_less(cov[1,:,:],0.001)       
plt.pcolor(xx,yy,cover_mask[1,:,:],cmap = plt.cm.Set2,alpha =0.75,\
           edgecolor = 'k',zorder =3)          

http://i4.tietuku.com/1d47a3410417cd4f.png

My question

  1. In the code above, I plot the 2-d arrays separately. If the grid color can be set using facecolor = 'cs[i]' with cs=plt.cm.xxx(np.arange(2)/2.) , I can loop all of my data[0:10,:,:].But I can only use cmap = xxx to differ each array's color. I don't know how to loop the colormap.

  2. In the picture above, the red grids and the green grids are overlapped. For better visualization effect, I want to label these overlapping grids striked.

Idea 1

Idea 2

label the overlapping grid wiht 'X' or something esle like the figure below.


(source: tietuku.com)

Add

Based on this post, it seems that 'pcolor/pcolormesh' don't have the function of setting hatch = '* '.

Upvotes: 1

Views: 2691

Answers (2)

ktbiz
ktbiz

Reputation: 586

Disclaimer: I haven't used numpy color plots before.

That said I think I see where your problem is. From the cmap documentation:

Typically Colormap instances are used to convert data values (floats) from the interval [0, 1] to the RGBA color that the respective Colormap represents.

I believe the problem is that you're setting all the grid values to 1, and then all the overlap values to 1 as well. So in a cmap they end up being the same color. If you want them to be different colors they need to be different values. Or if you want some value inbetween use a float between 0 and 1. Setting all the values of one array to 1 and the other to 0, with the overlap cells getting set to 0.5 would give you colors at the opposite end of the cmap with the overlap cells a mix of both (assuming you're using a 2 color cmap). Revised:

for i in range(0,data.shape[1],1):
    for j in range(0,dat.shape[2],1):
        #assuming you've set one array to 0 and the other to 1
        overlap[0, i, j] = abs(data[0, i, j] / data[1, i, j) / 2 
        #if (data[0,i,j] == 1) & (data[1,i,j] == 1.0)
            #overlap[i,j] = 1

Hope that answers your question, it was a little confusing. I appreciate all the information you provided but a clear "This is exactly what is wrong" statement at the beginning would definitely help understand the problem. And hey let me know if this fixes it because I'm interested.

Upvotes: 1

HYRY
HYRY

Reputation: 97291

If you only want to set overlap cells to one color, then following code works:

import numpy as np
import pylab as pl
from matplotlib import colors

data = (np.random.rand(3, 5, 10) > 0.8).astype(np.int)
cdata = (data * np.arange(1, 4)[:, None, None]).sum(axis=0)
overlap = data.sum(axis=0) > 1
cdata[overlap] = 4

y, x = np.mgrid[:6, :11]

cmap = colors.ListedColormap(["w", "r", "g", "b", "k"])
pl.pcolormesh(x, y, cdata, edgecolor="black", cmap=cmap)

The main point is to call pcolormesh() only once, and use a ListedColormap cmap object to set colors of every cell, here is the output:

enter image description here

the colors of the arrays are "r", "g", "b", and the overlap color is black. Here is the content of data:

array([[[0, 0, 0, 1, 0, 1, 0, 0, 1, 0],
        [0, 0, 0, 0, 1, 0, 1, 0, 0, 0],
        [0, 0, 1, 0, 0, 0, 1, 1, 0, 0],
        [1, 1, 0, 0, 0, 0, 1, 0, 0, 0],
        [0, 0, 0, 1, 0, 0, 0, 1, 0, 0]],

       [[0, 0, 0, 1, 1, 0, 1, 1, 0, 0],
        [0, 0, 0, 0, 0, 0, 0, 0, 1, 0],
        [0, 0, 0, 0, 0, 0, 0, 1, 0, 0],
        [0, 0, 0, 0, 0, 0, 0, 0, 1, 0],
        [1, 1, 1, 0, 0, 0, 1, 0, 0, 0]],

       [[0, 0, 0, 0, 0, 0, 1, 1, 0, 0],
        [0, 0, 0, 0, 1, 0, 0, 0, 0, 0],
        [0, 0, 0, 0, 0, 1, 0, 0, 0, 1],
        [0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
        [0, 0, 0, 0, 0, 0, 0, 0, 0, 0]]])

Upvotes: 1

Related Questions