Richard Laurant
Richard Laurant

Reputation: 657

Laying out several plots in matplotlib + numpy

I am pretty new to python and want to plot a dataset using a histogram and a heatmap below. However, I am a bit confused about

  1. How to put a title above both plots and
  2. How to insert some text into bots plots
  3. How to reference the upper and the lower plot

For my first task I used the title instruction, which inserted a caption in between both plots instead of putting it above both plots

For my second task I used the figtext instruction. However, I could not see the text anywhere in the plot. I played a bit with the x, y and fontsize parameters without any success.

Here is my code:

def drawHeatmap(xDim, yDim, plot, threshold, verbose):
global heatmapList
stableCells = 0

print("\n[I] - Plotting Heatmaps ...")
for currentHeatmap in heatmapList:
    if -1 in heatmapList[currentHeatmap]:
        continue
    print("[I] - Plotting heatmap for PUF instance", currentHeatmap,"(",len(heatmapList[currentHeatmap])," values)")
    # Convert data to ndarray
    #floatMap = list(map(float, currentHeatmap[1]))
    myArray = np.array(heatmapList[currentHeatmap]).reshape(xDim,yDim)

    # Setup two plots per page
    fig, ax = plt.subplots(2)

    # Histogram        
    weights = np.ones_like(heatmapList[currentHeatmap]) / len(heatmapList[currentHeatmap])
    hist, bins = np.histogram(heatmapList[currentHeatmap], bins=50, weights=weights)
    width = 0.7 * (bins[1] - bins[0])
    center = (bins[:-1] + bins[1:]) / 2
    ax[0].bar(center, hist, align='center', width=width)
    stableCells = calcPercentageStable(threshold, verbose)
    plt.figtext(100,100,"!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!", fontsize=40)


    heatmap = ax[1].pcolor(myArray, cmap=plt.cm.Blues, alpha=0.8, vmin=0, vmax=1)
    cbar = fig.colorbar(heatmap, shrink=0.8, aspect=10, fraction=.1,pad=.01)
    #cbar.ax.tick_params(labelsize=40) 
    for y in range(myArray.shape[0]):
        for x in range(myArray.shape[1]):
            plt.text(x + 0.5, y + 0.5, '%.2f' % myArray[y, x],
             horizontalalignment='center',
             verticalalignment='center',
             fontsize=(xDim/yDim)*5
             )

    #fig = plt.figure()
    fig = matplotlib.pyplot.gcf()
    fig.set_size_inches(60.5,55.5)
    plt.savefig(dataDirectory+"/"+currentHeatmap+".pdf", dpi=800, papertype="a3", format="pdf")
    #plt.title("Heatmap for PUF instance "+str(currentHeatmap[0][0])+" ("+str(numberOfMeasurements)+" measurements; "+str(sizeOfMeasurements)+" bytes)")
    if plot:
        plt.show()
    print("\t[I] - Done ...") 

And here is my current output:output

Upvotes: 3

Views: 397

Answers (1)

wflynny
wflynny

Reputation: 18521

Perhaps this example will make things easier to understand. Things to note are:

  • Use fig.suptitle to add a title to the top of a figure.
  • Use ax[i].text(x, y, str) to add text to an Axes object
  • Each Axes object, ax[i] in your case, holds all the information about a single plot. Use them instead of calling plt, which only really works well with one subplot per figure or to modify all subplots at once. For example, instead of calling plt.figtext, call ax[0].text to add text to the top plot.

Try following the example code below, or at least read through it to get a better idea how to use your ax list.


import numpy as np
import matplotlib.pyplot as plt

histogram_data = np.random.rand(1000)
heatmap_data = np.random.rand(10, 100)

# Set up figure and axes
fig = plt.figure()
fig.suptitle("These are my two plots")
top_ax = fig.add_subplot(211) #2 rows, 1 col, 1st plot
bot_ax = fig.add_subplot(212) #2 rows, 1 col, 2nd plot
# This is the same as doing 'fig, (top_ax, bot_ax) = plt.subplots(2)'

# Histogram
weights = np.ones_like(histogram_data) / histogram_data.shape[0]
hist, bins = np.histogram(histogram_data, bins=50, weights=weights)
width = 0.7 * (bins[1] - bins[0])
center = (bins[:-1] + bins[1:]) / 2

# Use top_ax to modify anything with the histogram plot
top_ax.bar(center, hist, align='center', width=width)
# ax.text(x, y, str). Make sure x,y are within your plot bounds ((0, 1), (0, .5))
top_ax.text(0.5, 0.5, "Here is text on the top plot", color='r')

# Heatmap
heatmap_params = {'cmap':plt.cm.Blues, 'alpha':0.8, 'vmin':0, 'vmax':1}

# Use bot_ax to modify anything with the heatmap plot
heatmap = bot_ax.pcolor(heatmap_data, **heatmap_params)
cbar = fig.colorbar(heatmap, shrink=0.8, aspect=10, fraction=.1,pad=.01)

# See how it looks
plt.show()

enter image description here

Upvotes: 2

Related Questions