Fill between two horizontal lines thresholds in matplotlib - matplotlib

Dears, I need to make a fill between two thresholds in my chart I have tried with my code but it does not display, could you please tell me what I am doing wrong? I would like my figure like contour red like figure 2
fig = plt.figure(figsize=(15, 6))
ax = fig.add_subplot(111)
ax = lacebita['Prob'].plot(figsize=(15, 7), )
xtime = np.linspace(1990,2021,384)
ax.plot(xtime, lacebita['Prob'], 'black', alpha=1.00, linewidth=2, label = 'Deciles')
ax.fill_between(xtime, 0., lacebita['Prob'], lacebita['Prob']< 30., color='red', alpha=.75)
ax.axhline(50, linestyle='--', color='black',label='Percentile 50')
ax.axhline(33, linestyle='--', color='orange', label='Percentile 33')
ax.set_xlim(1990, 2021)
ax.set_ylim(0, 100, 10)
plt.grid(True)
plt.legend(loc = "upper left")
#ax.autoscale_view()
ax.set_title('Deciles para 12-Meses La Cebita(1990-2020)', fontsize=16)
ax.set_xlim(lacebita.index.min(), lacebita.index.max())
plt.savefig('deciles_12_lacebita.jpg')

There are a couple of ways to go about it. One approach is to fill the space in between the two horizontal threshold lines:
# Make a fake function
t = 20
fs = 10
samples = np.linspace(0, t, int(fs*t), endpoint=False)
wave_y = np.sin(samples)
time_x = np.arange(0, len(wave_y))
# Set upper and lower thresholds where horizontal lines will go and fill in between
upper_th = 0.5
lower_th = -0.5
# Plot function
fig, ax = plt.subplots()
ax.plot(time_x, wave_y)
ax.grid()
ax.set_ylim([-1.25, 1.25])
ax.set_ylabel('y label')
ax.set_xlim([0, 125])
ax.set_xlabel('x label')
# Fill in area under the curve and the horizontal lines
ax.fill_between(x=time_x, y1=upper_th, y2=lower_th, color='red', interpolate=True, alpha=.75)
# Horizontal lines
ax.axhline(upper_th, linestyle='--', color='black', label="upper_th: 0.5")
ax.axhline(lower_th, linestyle='--', color='orange', label='lower_th: - 0.5')
ax.legend()
plt.show()
Or if you change y1 or y2, for example to y1=0, you can play around with where exactly the fill is.
Another method is to fill in between the curve and the horizontal dashed lines. To do that you could modify the original data so that the values that go above the upper threshold and below the lower threshold become the threshold values. In other words, we want to make a new y curve that includes the threshold points by eliminating the points that go above/below the threshold so that matplotlib understands that the horizontal lines are part of the y curve.
# Copy original data, we are now going to modify
new_wave_y = np.copy(wave_y)
# Change values outside thresholds to threshold value for fill in
new_wave_y[new_wave_y < lower_th] = lower_th
new_wave_y[new_wave_y > upper_th] = upper_th
This way we can use where in fill between to point out where exactly under the curve, including under/above the horizontal lines, matplotlib needs to fill in the area. The full script:
# Make a fake function
t = 20
fs = 10
samples = np.linspace(0, t, int(fs*t), endpoint=False)
wave_y = np.sin(samples)
time_x = np.arange(0, len(wave_y))
# Set upper and lower thresholds where horizontal lines will go and fill in between
upper_th = 0.5
lower_th = -0.5
# Copy original data, we are now going to modify
new_wave_y = np.copy(wave_y)
# Change values outside thresholds to threshold value for fill in
new_wave_y[new_wave_y < lower_th] = lower_th
new_wave_y[new_wave_y > upper_th] = upper_th
# Plot function
fig, ax = plt.subplots()
ax.plot(time_x, wave_y)
ax.grid()
ax.set_ylim([-1.25, 1.25])
ax.set_ylabel('y label')
ax.set_xlim([0, 125])
ax.set_xlabel('x label')
# Fill in area under the curve and the horizontal lines
ax.fill_between(x=time_x, y1=new_wave_y, where=(lower_th < new_wave_y), color='red', interpolate=True, alpha=.75)
ax.fill_between(x=time_x, y1=new_wave_y, where=(new_wave_y < upper_th), color='red', interpolate=True, alpha=.75)
# Horizontal lines
ax.axhline(upper_th, linestyle='--', color='black', label="upper_th: 0.5")
ax.axhline(lower_th, linestyle='--', color='orange', label='lower_th: - 0.5')
ax.legend()
plt.show()
You can get some more information in the Matplotlib fill between demo and the fill between docs.
Edit:
If you want to fill in below or above the threshold line, for example fill in below the lower threshold, you can modify the y curve so that the values above the threshold become the threshold value (same as before but reverse) and change the values in fill_between . The full script:
# Make a fake function
t = 20
fs = 10
samples = np.linspace(0, t, int(fs*t), endpoint=False)
wave_y = np.sin(samples)
time_x = np.arange(0, len(wave_y))
# Set upper and lower thresholds where horizontal lines will go and fill in between
upper_th = 0.5
lower_th = -0.5
# Copy original data, we are now going to modify
new_wave_y = np.copy(wave_y)
# Change values outside thresholds to threshold value for fill in
new_wave_y[new_wave_y > lower_th] = lower_th
# Plot function
fig, ax = plt.subplots()
ax.plot(time_x, wave_y)
ax.grid()
ax.set_ylim([-1.25, 1.25])
ax.set_ylabel('y label')
ax.set_xlim([0, 125])
ax.set_xlabel('x label')
# Fill in area under the curve and the horizontal lines
ax.fill_between(x=time_x, y1=new_wave_y, y2=lower_th, where=(new_wave_y < lower_th), color='red', interpolate=True, alpha=.75)
# Horizontal lines
ax.axhline(upper_th, linestyle='--', color='black', label="upper_th: 0.5")
ax.axhline(lower_th, linestyle='--', color='orange', label='lower_th: - 0.5')
ax.legend()
plt.show()

Related

How can I get rid of this dummy mappable object and still draw my colorbar in Matplotlib?

I have the code below to plot circles add them to an ax.
I color the circles with respect to a colorbar.
However, to add the colorbar to my plot, I'm using sc=plot.scatter(...) and putting the colorbar using this dummy sc. Because plt.colorbar(sc,...) requires a mappable argument. How can I get rid of this dummy sc and still draw my colorbar?
import matplotlib
import numpy as np
import os
import matplotlib as mpl
from matplotlib.colors import Normalize
import matplotlib.cm as matplotlib_cm
from matplotlib import pyplot as plt
print(matplotlib.__version__)
row_list=['row1', 'row2', 'row3']
column_list=[2]
maxProcessiveGroupLength=2
index = column_list.index(maxProcessiveGroupLength)
plot1,panel1 = plt.subplots(figsize=(20+1.5*len(column_list), 10+1.5*len(row_list)))
plt.rc('axes', edgecolor='lightgray')
#make aspect ratio square
panel1.set_aspect(1.0)
panel1.text(0.1, 1.2, 'DEBUG', horizontalalignment='center', verticalalignment='top', fontsize=60, fontweight='bold', fontname='Arial',transform=panel1.transAxes)
if (len(column_list) > 1):
panel1.set_xlim([1, index + 1])
panel1.set_xticks(np.arange(0, index + 2, 1))
else:
panel1.set_xlim([0, len(column_list)])
panel1.set_xticks(np.arange(0, len(column_list)+1, 1))
if (len(row_list) > 1):
panel1.set_ylim([1, len(row_list)])
else:
panel1.set_ylim([0, len(row_list)])
panel1.set_yticks(np.arange(0, len(row_list) + 1, 1))
panel1.set_facecolor('white')
panel1.grid(color='black')
for edge, spine in panel1.spines.items():
spine.set_visible(True)
spine.set_color('black')
xlabels = None
if (index is not None):
xlabels = column_list[0:index + 1]
ylabels = row_list
cmap = matplotlib_cm.get_cmap('Blues') # Looks better
v_min = 2
v_max = 20
norm = Normalize(v_min, v_max)
bounds = np.arange(v_min, v_max+1, 2)
# Plot the circles with color
for row_index, row in enumerate(row_list):
for column_index, processive_group_length in enumerate(column_list):
radius=0.35
color=10+column_index*3+row_index*3
circle = plt.Circle((column_index + 0.5, row_index + 0.5), radius,color=cmap(norm(color)), fill=True)
panel1.add_patch(circle)
# Used for scatter plot
x = []
y = []
c = []
for row_index, processiveGroupLength in enumerate(row_list):
x.append(row_index)
y.append(row_index)
c.append(0.5)
# This code defines the ticks on the color bar
# plot the scatter plot
sc = plt.scatter(x, y, s=0, c=c, cmap=cmap, vmin=v_min, vmax=v_max, edgecolors='black')
# colorbar to the bottom
cb = plt.colorbar(sc ,orientation='horizontal') # this works because of the scatter
cb.ax.set_xlabel("colorbar label", fontsize=50, labelpad=25)
# common for horizontal colorbar and vertical colorbar
cbax = cb.ax
cbax.tick_params(labelsize=40)
text_x = cbax.xaxis.label
text_y = cbax.yaxis.label
font = mpl.font_manager.FontProperties(size=40)
text_x.set_font_properties(font)
text_y.set_font_properties(font)
# CODE GOES HERE TO CENTER X-AXIS LABELS...
panel1.set_xticklabels([])
mticks = panel1.get_xticks()
panel1.set_xticks((mticks[:-1] + mticks[1:]) / 2, minor=True)
panel1.tick_params(axis='x', which='minor', length=0, labelsize=50)
if xlabels is not None:
panel1.set_xticklabels(xlabels,minor=True)
panel1.xaxis.set_ticks_position('top')
plt.tick_params(
axis='x', # changes apply to the x-axis
which='major', # both major and minor ticks are affected
bottom=False, # ticks along the bottom edge are off
top=False) # labels along the bottom edge are off
# CODE GOES HERE TO CENTER Y-AXIS LABELS...
panel1.set_yticklabels([])
mticks = panel1.get_yticks()
panel1.set_yticks((mticks[:-1] + mticks[1:]) / 2, minor=True)
panel1.tick_params(axis='y', which='minor', length=0, labelsize=50)
panel1.set_yticklabels(ylabels, minor=True) # fontsize
plt.tick_params(
axis='y', # changes apply to the x-axis
which='major', # both major and minor ticks are affected
left=False) # labels along the bottom edge are off
plt.show()
From the documentation of colorbar:
Note that one can create a ScalarMappable "on-the-fly" to generate
colorbars not attached to a previously drawn artist
In your example, the following allows for creating the same colorbar without the scatter plot:
cb = plt.colorbar(mpl.cm.ScalarMappable(norm=norm, cmap=cmap), orientation='horizontal')

Sorting out labels in subplots, created with fig.add_axes

I am new to python and am currently playing around with mathplotlib. Below is my code for the plot, shown on the bottom figure.
import matplotlib.pyplot as plt
f = plt.figure(figsize=(15, 15))
ax1 = f.add_axes([0.1, 0.5, 0.8, 0.5],
xticklabels=[])
ax2 = f.add_axes([0.1, 0.4, 0.8, 0.1])
ax1.plot(particles[0, :, 0])
ax1.plot(particles[1, :, 0])
ax2.plot(distances[:])
# Prettifying the plot
plt.xlabel("t", fontsize=25)
plt.tick_params( # modifying plot ticks
axis='x',
labelsize=20)
plt.ylabel("x", fontsize=25)
plt.tick_params( # modifying plot ticks
axis='y',
labelsize=20)
# Plot title
plt.title('Harmonic oscillator in ' + str(dim) + 'D with ' + str(num_step) + ' timesteps', fontsize=30)
# Saving the plot
#plt.savefig("results/2D_dif.png")
The two graphs have the dimensions and positions as I wish, but as you can see, the labels and the title are off. I wish to have the same label style, as was applied to the bottom plot, with the y-label of the upper plot reading "x", and the title "Harmonic oscillator ..." being on top of the first graph.
I thank you kindly for your help!
Here plt is acting on the most recently created axes instance (ax2 in this case). This is why the fonts haven't changed for ax1!
So, to get what you want you need to explicitly act on both ax1 and ax2. Something like the following should do the trick:
for ax in ax1, ax2:
# Prettifying the plot
ax.set_xlabel("t", fontsize=25)
ax.tick_params( # modifying plot ticks
axis='x',
labelsize=20)
ax.set_ylabel("x", fontsize=25)
ax.tick_params( # modifying plot ticks
axis='y',
labelsize=20)
# Plot title
ax.set_title('Harmonic oscillator in ' + str(dim) + 'D with ' + str(num_step) + ' timesteps', fontsize=30)

How to stack the graphs in such a way that the share a common scale along x-axis

The following code is for generating the 3 subplots. And on all the 3 subplots scale is mentioned. I want to stack them in such a way that x-axis and y-axis scale appear once like this. Can I get this plot with plt.subplot() or fig.add_axes is compulsory for this? I actually want to do this with subplots because in fig.add_subplot I havve to specify the width and height of each plot that I don't want.
`fig,axes = plt.figure(nrow=3, ncolmn=1)
ax1 = fig.add_subplot(311)
ax2 = fig.add_subplot(312)
ax3 = fig.add_subplot(313)
ind1 =[1,2,3]
ind2 = [4,5,6]
for i in range(len(3)):
data1=np.load(..)
data2=np.load(..)
axes[i].plot(data1, data2)`
Here is one solution using subplots_adjust where you put the space between two plots to 0 using hspace. Also, use sharex=True to have a shared x-axis
fig, axes = plt.subplots(nrows=3, ncols=1,sharex=True)
x = np.linspace(0, 2*np.pi, 100)
y = np.sin(x)
for i, ax in enumerate(axes.ravel()): # or axes.flatten() or axes.flat
ax.plot(x, y, label='File %d' %i)
ax.legend()
fig.text(0.5, 0.01, 'X-label', ha='center')
fig.text(0.01, 0.5, 'Y-label', va='center', rotation='vertical')
plt.tight_layout() # To get a better spacing between the subplots
plt.subplots_adjust(hspace=.0)

Creating figure with exact size and no padding (and legend outside the axes)

I am trying to make some figures for a scientific article, so I want my figures to have a specific size. I also see that Matplotlib by default adds a lot of padding on the border of the figures, which I don't need (since the figures will be on a white background anyway).
To set a specific figure size I simply use plt.figure(figsize = [w, h]), and I add the argument tight_layout = {'pad': 0} to remove the padding. This works perfectly, and even works if I add a title, y/x-labels etc. Example:
fig = plt.figure(
figsize = [3,2],
tight_layout = {'pad': 0}
)
ax = fig.add_subplot(111)
plt.title('title')
ax.set_ylabel('y label')
ax.set_xlabel('x label')
plt.savefig('figure01.pdf')
This creates a pdf file with exact size 3x2 (inches).
The issue I have is that when I for example add a text box outside the axis (typically a legend box), Matplotlib does not make room for the text box like it does when adding titles/axis labels. Typically the text box is cut off, or does not show in the saved figure at all. Example:
plt.close('all')
fig = plt.figure(
figsize = [3,2],
tight_layout = {'pad': 0}
)
ax = fig.add_subplot(111)
plt.title('title')
ax.set_ylabel('y label')
ax.set_xlabel('x label')
t = ax.text(0.7, 1.1, 'my text here', bbox = dict(boxstyle = 'round'))
plt.savefig('figure02.pdf')
A solution I found elsewhere on SO was to add the argument bbox_inches = 'tight' to the savefig command. The text box is now included like I wanted, but the pdf is now the wrong size. It seems like Matplotlib just makes the figure bigger, instead of reducing the size of the axes like it does when adding titles and x/y-labels.
Example:
plt.close('all')
fig = plt.figure(
figsize = [3,2],
tight_layout = {'pad': 0}
)
ax = fig.add_subplot(111)
plt.title('title')
ax.set_ylabel('y label')
ax.set_xlabel('x label')
t = ax.text(0.7, 1.1, 'my text here', bbox = dict(boxstyle = 'round'))
plt.savefig('figure03.pdf', bbox_inches = 'tight')
(This figure is 3.307x2.248)
Is there any solution to this that covers most cases with a legend just outside the axes?
So the requirements are:
Having a fixed, predefined figure size
Adding a text label or legend outside the axes
Axes and text cannot overlap
The axes, together with the title and axis labels, sits tightly agains the figure border.
So tight_layout with pad = 0, solves 1. and 4. but contradicts 2.
One could think on setting pad to a larger value. This would solve 2. However, since it's is symmetric in all directions, it would contradict 4.
Using bbox_inches = 'tight' changes the figure size. Contradicts 1.
So I think there is no generic solution to this problem.
Something I can come up with is the following: It sets the text in figure coordinates and then resizes the axes either in horizontal or in vertical direction such that there is no overlap between the axes and the text.
import matplotlib.pyplot as plt
import matplotlib.transforms
fig = plt.figure(figsize = [3,2])
ax = fig.add_subplot(111)
plt.title('title')
ax.set_ylabel('y label')
ax.set_xlabel('x label')
def text_legend(ax, x0, y0, text, direction = "v", padpoints = 3, margin=1.,**kwargs):
ha = kwargs.pop("ha", "right")
va = kwargs.pop("va", "top")
t = ax.figure.text(x0, y0, text, ha=ha, va=va, **kwargs)
otrans = ax.figure.transFigure
plt.tight_layout(pad=0)
ax.figure.canvas.draw()
plt.tight_layout(pad=0)
offs = t._bbox_patch.get_boxstyle().pad * t.get_size() + margin # adding 1pt
trans = otrans + \
matplotlib.transforms.ScaledTranslation(-offs/72.,-offs/72.,fig.dpi_scale_trans)
t.set_transform(trans)
ax.figure.canvas.draw()
ppar = [0,-padpoints/72.] if direction == "v" else [-padpoints/72.,0]
trans2 = matplotlib.transforms.ScaledTranslation(ppar[0],ppar[1],fig.dpi_scale_trans) + \
ax.figure.transFigure.inverted()
tbox = trans2.transform(t._bbox_patch.get_window_extent())
bbox = ax.get_position()
if direction=="v":
ax.set_position([bbox.x0, bbox.y0,bbox.width, tbox[0][1]-bbox.y0])
else:
ax.set_position([bbox.x0, bbox.y0,tbox[0][0]-bbox.x0, bbox.height])
# case 1: place text label at top right corner of figure (1,1). Adjust axes height.
#text_legend(ax, 1,1, 'my text here', bbox = dict(boxstyle = 'round'), )
# case 2: place text left of axes, (1, y), direction=="v"
text_legend(ax, 1., 0.8, 'my text here', margin=2., direction="h", bbox = dict(boxstyle = 'round') )
plt.savefig(__file__+'.pdf')
plt.show()
case 1 (left) and case 2 (right):
Doin the same with a legend is slightly easier, because we can directly use the bbox_to_anchor argument and don't need to control the fancy box around the legend.
import matplotlib.pyplot as plt
import matplotlib.transforms
fig = plt.figure(figsize = [3.5,2])
ax = fig.add_subplot(111)
ax.set_title('title')
ax.set_ylabel('y label')
ax.set_xlabel('x label')
ax.plot([1,2,3], marker="o", label="quantity 1")
ax.plot([2,1.7,1.2], marker="s", label="quantity 2")
def legend(ax, x0=1,y0=1, direction = "v", padpoints = 3,**kwargs):
otrans = ax.figure.transFigure
t = ax.legend(bbox_to_anchor=(x0,y0), loc=1, bbox_transform=otrans,**kwargs)
plt.tight_layout(pad=0)
ax.figure.canvas.draw()
plt.tight_layout(pad=0)
ppar = [0,-padpoints/72.] if direction == "v" else [-padpoints/72.,0]
trans2=matplotlib.transforms.ScaledTranslation(ppar[0],ppar[1],fig.dpi_scale_trans)+\
ax.figure.transFigure.inverted()
tbox = t.get_window_extent().transformed(trans2 )
bbox = ax.get_position()
if direction=="v":
ax.set_position([bbox.x0, bbox.y0,bbox.width, tbox.y0-bbox.y0])
else:
ax.set_position([bbox.x0, bbox.y0,tbox.x0-bbox.x0, bbox.height])
# case 1: place text label at top right corner of figure (1,1). Adjust axes height.
#legend(ax, borderaxespad=0)
# case 2: place text left of axes, (1, y), direction=="h"
legend(ax,y0=0.8, direction="h", borderaxespad=0.2)
plt.savefig(__file__+'.pdf')
plt.show()
Why 72? The 72 is the number of points per inch (ppi). This is a fixed typographic unit e.g. fontsizes are always given in points (like 12pt). Because matplotlib defines the padding of the text box in units relative to fontsize, which is points, we need to use 72 to transform back to inches (and then to display coordinates). The default dots per inch (dpi) is not touched here, but is accounted for in fig.dpi_scale_trans. If you want to change dpi you need to make sure the figure dpi is set when creating the figure as well as when saving it (use dpi=.. in the call to plt.figure() as well as plt.savefig()).
As of matplotlib==3.1.3, you can use constrained_layout=True to achieve the desired result. This is currently experimental, but see the docs for a very helpful guide (and the section specifically on legends). Note that the legend will steal space from the plot, but this is unavoidable. I've found that as long as the legend does not take up too much space relative to the size of the plot, then the figure gets saved without cropping anything.
import matplotlib.pyplot as plt
fig, ax = plt.subplots(figsize=(3, 2), constrained_layout=True)
ax.set_title('title')
ax.set_ylabel('y label')
ax.set_xlabel('x label')
ax.plot([0,1], [0,1], label='my text here')
ax.legend(loc='center left', bbox_to_anchor=(1.1, 0.5))
fig.savefig('figure03.pdf')

matplotlib - Draw a heatmap/pixelmap with ability to edit individual pixel colours (different colormaps by row)

I'm trying to draw a heat map/pixelmap representation of a matrix using matplotlib. I currently have the following code which gives me the pixelmap as required (adapted from Heatmap in matplotlib with pcolor?):
import matplotlib.pyplot as plt
import numpy as np
column_labels = list('ABCD')
row_labels = list('0123')
data = np.array([[0,1,2,0],
[1,0,1,1],
[1,2,0,0],
[0,0,0,1]])
fig, ax = plt.subplots()
heatmap = ax.pcolor(data, cmap=plt.cm.Blues)
# put the major ticks at the middle of each cell
ax.set_xticks(np.arange(data.shape[0])+0.5, minor=False)
ax.set_yticks(np.arange(data.shape[1])+0.5, minor=False)
# want a more natural, table-like display
ax.invert_yaxis()
ax.xaxis.tick_top()
ax.set_xticklabels(row_labels, minor=False)
ax.set_yticklabels(column_labels, minor=False)
ax.yaxis.grid(True, which='minor', linestyle='-', color='k', linewidth = 0.3, alpha = 0.5)
ax.xaxis.grid(True, which='minor', linestyle='-', color='k', linewidth = 0.3, alpha = 0.5)
# Set the location of the minor ticks to the edge of pixels for the x grid
minor_locator = AutoMinorLocator(2)
ax.xaxis.set_minor_locator(minor_locator)
# Lets turn off the actual minor tick marks though
for tickmark in ax.xaxis.get_minor_ticks():
tickmark.tick1On = tickmark.tick2On = False
# Set the location of the minor ticks to the edge of pixels for the y grid
minor_locator = AutoMinorLocator(2)
ax.yaxis.set_minor_locator(minor_locator)
# Lets turn off the actual minor tick marks though
for tickmark in ax.yaxis.get_minor_ticks():
tickmark.tick1On = tickmark.tick2On = False
plt.show()
Which gives the following plot:
However I would like to extend this such that on mouse click I can highlight a 'row' in the pixelmap in green, e.g. if the user selected row 'C' I would have (I appreciate the green highlight is not clear for pixels with a 0 value):
I know how to deal with the mouse events but I'm not sure how to modify the colour of a single row in the pixelmap. It would also help if I could set labels for individual pixels of the pixel map to be retrieved on mouse click, as opposed to using the mouse x/y location to index the label lists.
I have figured out my own problem, with help from this question:
Plotting of 2D data : heatmap with different colormaps.
The code is below and the comments should explain the steps taken clearly.
import matplotlib.pyplot as plt
import numpy as np
from numpy.ma import masked_array
import matplotlib.cm as cm
from matplotlib.ticker import AutoMinorLocator
column_labels = list('ABCD')
row_labels = list('0123')
data = np.array([[0,1,2,0],
[1,0,1,1],
[1,2,0,0],
[0,0,0,1]])
fig, ax = plt.subplots()
# List to keep track of handles for each pixel row
pixelrows = []
# Lets create a normalizer for the whole data array
norm = plt.Normalize(vmin = np.min(data), vmax = np.max(data))
# Let's loop through and plot each pixel row
for i, row in enumerate(data):
# First create a mask to ignore all others rows than the current
zerosarray = np.ones_like(data)
zerosarray[i, :] = 0
plotarray = masked_array(data, mask=zerosarray)
# If we are not on the 3rd row down let's use the red colormap
if i != 2:
pixelrows.append(ax.matshow(plotarray, norm=norm, cmap=cm.Reds))
# Otherwise if we are at the 3rd row use the green colormap
else:
pixelrows.append(ax.matshow(plotarray, norm=norm, cmap=cm.Greens))
# put the major ticks at the middle of each cell
ax.set_xticks(np.arange(data.shape[0]), minor=False)
ax.set_yticks(np.arange(data.shape[1]), minor=False)
# want a more natural, table-like display
ax.xaxis.tick_top()
ax.set_xticklabels(row_labels, minor=False)
ax.set_yticklabels(column_labels, minor=False)
ax.yaxis.grid(True, which='minor', linestyle='-', color='k', linewidth = 0.3, alpha = 0.5)
ax.xaxis.grid(True, which='minor', linestyle='-', color='k', linewidth = 0.3, alpha = 0.5)
# Set the location of the minor ticks to the edge of pixels for the x grid
minor_locator = AutoMinorLocator(2)
ax.xaxis.set_minor_locator(minor_locator)
# Lets turn of the actual minor tick marks though
for tickmark in ax.xaxis.get_minor_ticks():
tickmark.tick1On = tickmark.tick2On = False
# Set the location of the minor ticks to the edge of pixels for the y grid
minor_locator = AutoMinorLocator(2)
ax.yaxis.set_minor_locator(minor_locator)
# Lets turn of the actual minor tick marks though
for tickmark in ax.yaxis.get_minor_ticks():
tickmark.tick1On = tickmark.tick2On = False
plt.show()