Question

Is there a way to place custom patterns into selected areas on an imshow graph? To be precise, I need to make it so that, in addition to the numerical-data-carrying colored squares, I also have different patterns in other squares indicate different failure modes for the experiment (and also generate a key explaining the meaning of these different patterns). An example of a pattern that would be useful would be various types of crosshatches. i need to be able to do this without disrupting the main color-numerical data relationship on the graph.

Below is code from my attempt to use what was suggested in the answers. If I comment the error section the imshow shows up fine with white space wherever there is no data from the masking. I am not even attempting to do different kinds of crosshatching for different failure types or deal with cases where either the simulation or the experiment worked but the other didn't yet.

EDIT3: I am receiving error massages from the multiprocessing package about how it 'can't pickle' the object. Due to the program this is a part of it goes through the multiprocessing package. Any way to fix this or do it without add_patches (the plot method suggested below doesn't work, as the plotting happens on a completely different coordinate system and draws connecting lines)?

import numpy as np
import matplotlib.patches as patches
...
grid = np.ma.array(grid, mask=np.isnan(grid))
plot.imshow(grid, interpolation='nearest', aspect='equal', vmax = private.vmax, vmin = private.vmin)
if show_fail and faildat != []:
    faildat = faildat[np.lexsort((faildat[:,yind],faildat[:,xind]))]
    fails = []
    for i in range(len(faildat)):
        fails.append((faildat[i,1],faildat[i,0]))
    for F in fails:
        p = patches.Rectangle(F,1,1,hatch='/',fill=False)
        plot.add_patch(p)
plot.minorticks_off()
plot.set_xticks(range(len(placex)))        
plot.set_yticks(range(len(placey)))
plot.set_xticklabels(placex)        
plot.set_yticklabels(placey, rotation = 0)
plot.colorbar()
plot.show()
Was it helpful?

Solution

There are several ways to do this, which is better will depend on if you need to mark large regions or scattered individual pixels.

If you need to mark large regions, you can do this by added rectangles over the image:

import matplotlib as mpl
import matplotlib.pyplot as plt
from numpy.random import rand

ax = plt.gca()
ax.imshow(rand(50,50))
ax.add_patch(mpl.patches.Rectangle((2,2),20,20,hatch='//////////',fill=False,snap=False))
plt.draw()

Rectangle (doc) a variety of hash options. This is just adding additional artists on top of the image, they will not affect the data-color mapping in any way. The large number of / increases the density of the hash marks, which may be necessary to acctually see the hashing with small boxes.

ex:

from numpy.random import rand
import matplotlib as mpl
import matplotlib.pyplot as plt
     
ax = plt.gca()
ax.imshow(rand(50,50),interpolation='nearest')
for i,j in np.floor(50*rand(10,2)).astype('int'):
    ax.add_patch(mpl.patches.Rectangle((i-.5, j-.5), 1, 1, hatch='///////', fill=False, snap=False))

plt.draw()

image with some pixel hatched If you just need to mark a few pixels here and you might be able to get away with just plotting (using plot([x],[y],marker='x') and maybe playing with the marker size).

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top