Home > other >  Matplotlib, plot a vector of numbers as a rectangle filled with numbers
Matplotlib, plot a vector of numbers as a rectangle filled with numbers

Time:01-20

So let's say I have a vector of numbers.

np.random.randn(5).round(2).tolist()

[2.05, -1.57, 1.07, 1.37, 0.32]

I want a draw a rectangle that shows this elements as numbers in a rectangle. Something like this:

enter image description here

Is there an easy way to do this in matplotlib?

CodePudding user response:

We can add rectangles , and annotate them in a for loop.

from matplotlib import pyplot as plt
import numpy as np

# Our numbers
nums = np.random.randn(5).round(2).tolist()

# rectangle_size
rectangle_size = 2

# We want rectangles look squared, you can change if you want
plt.rcParams["figure.figsize"] = [rectangle_size * len(nums), rectangle_size]
plt.rcParams["figure.autolayout"] = True

fig = plt.figure()
ax = fig.add_subplot(111)

for i in range(len(nums)):
    # We are adding rectangles
    # You can change colors as you wish
    plt.broken_barh([(rectangle_size * i, rectangle_size)], (0, rectangle_size), facecolors='white', edgecolor='black'
                    ,linewidth = 1)

    # We are calculating where to annotate numbers
    cy = rectangle_size / 2.0
    cx = rectangle_size * i   cy

    # Annotation You can change color,font, etc ..
    ax.annotate(str(nums[i]), (cx, cy), color='black', weight='bold', fontsize=20, ha='center', va='center')

# For squared look
plt.xlim([0, rectangle_size*len(nums)])
plt.ylim([0, rectangle_size])

# We dont want to show ticks
plt.axis('off')

plt.show()

CodePudding user response:

A bit convoluted but you could take advantage of seaborn.heatmap, creating a white colormap:

import seaborn as sns
import numpy as np
import matplotlib.pyplot as plt
from matplotlib.colors import LinearSegmentedColormap

data = np.random.randn(5).round(2).tolist()

linewidth = 2

ax = sns.heatmap([data], annot=True, cmap=LinearSegmentedColormap.from_list('', ['w', 'w'], N=1),
            linewidths=linewidth, linecolor='black', square=True,
            cbar=False, xticklabels=False, yticklabels=False)

plt.tight_layout()
plt.show()

In this case, the external lines won't be as thick as the internal ones. If needed, this can be fixed with:

ax.axhline(y=0, color='black', lw=linewidth*2)
ax.axhline(y=1, color='black', lw=linewidth*2)
ax.axvline(x=0, color='black', lw=linewidth*2)
ax.axvline(x=len(data), color='black', lw=linewidth*2)

Output:

enter image description here

CodePudding user response:

One way using the enter image description here

  • Related