Obtenir une image matricielle des valeurs du tableau numpy - Grille avec des valeurs de pixels à l'intérieur (pas des couleurs)

9

J'ai cherché en ligne et je n'ai rien trouvé à ce sujet qui fasse ce que je veux.

Je voudrais enregistrer un tableau numpy en tant qu'image, mais au lieu d'avoir une image colorée, je veux une représentation en noir et blanc des valeurs des pixels dans leur emplacement de grille correspondant.

Par exemple:

import numpy as np
x = np.array([[1,2],[3,4]])
print(x)
# [[1 2]
#  [3 4]]

Je voudrais l'enregistrer en tant qu'image (.PNG) qui ressemble à ceci:

production attendue

Mon code actuel crée une grille et place les chiffres à l'intérieur mais il est très difficile de tout ajuster pour le rendre présentable dans un document de recherche.

Donc, plutôt que de publier mon code trop complexe, je me demandais s'il y avait une fonction intégrée pour gérer cela en quelques lignes de code.

lbragile
la source
1
On dirait que ce tableserait un bon point de départ. Je ne l'ai pas suffisamment utilisé pour donner une bonne réponse.
Warren Weckesser
1
Voir 'Table Demo' pour un exemple qui utilise table.
Warren Weckesser
4
J'utiliserais LaTeX pour une table que vous essayez de mettre dans un papier, par opposition à une image raster.
alcasm
@alkasm, le problème est que mes matrices réelles sont beaucoup plus grandes (14x14 ou 28x28) et j'ai besoin de faire beaucoup d'images pour elles, donc le faire manuellement dans LaTex semble être une méthode très inefficace.
lbragile
5
Au contraire, la pixellisation des images ressemble à la méthode inefficace. Les tableaux de données ne sont pas des images et ne doivent donc pas être traités comme tels. Vous pouvez générer automatiquement LaTeX, même manuellement, extrêmement facilement.
alcasm

Réponses:

12

J'utiliserais LaTeX pour générer les tableaux, car ils ont l'air fantaisistes et vous pouvez soit générer une image ou les mettre directement dans votre document. J'ai utilisé le code suivant pour y parvenir:

#!/usr/bin/env
import numpy as np
import os

x = np.array([[1,2],[3,4]])

def generateLatexTable(x):
    start = [r'\documentclass[preview]{standalone}', r'\begin{document}', r'\begin{tabular}{%s}' % ('{1}{0}{1}'.format('|'.join(['r'] * x.shape[1]), '|')), r'\hline']
    tab = [' & '.join(['%d' % val for val in row]) + r' \\ \hline' for row in x]
    end = [r'\end{tabular}', r'\end{document}']
    text = '\n'.join(start + tab + end)

    return text

with open('table.tex', 'w') as f:
    f.write(generateLatexTable(x))
os.system("pdflatex table.tex")

Ici, la classe de document previewest utilisée qui renvoie une image redimensionnée au contenu du document, c'est-à-dire juste la table. Seul un tabularenvironnement est utilisé pour présenter les données. Il y a des barres horizontales et verticales entre les cellules, mais il est très facile de changer cela. Dans la variable, tables données sont traitées pour chaque ligne et converties en chaîne. Notez que vous devez spécifier le format de sortie à cette position. Je l'ai défini pour %dque tout soit converti en entiers.

Si vous souhaitez utiliser le tableau directement dans une source latex, vous devez supprimer documentclasset \begin{document}ainsi que \end{document}dans les variables de startet end. Enfin, tout est rassemblé dans une source latex qui est ensuite stockée sur le disque sous table.tex. Si vous voulez juste l'image à la fin, le fichier résultant est compilé table.pdf.

Voici à quoi ressemble la sortie. Mais comme je l'ai dit, il est très facile de changer l'apparence puisque c'est LaTeX :)

table

Voici un autre exemple avec une grande matrice (14 x 14), remplie de nombres aléatoires allant de 0 à 100:

Tableau 2

Solvalou
la source
8

Vous pouvez utiliser la tablefonction de matplotpour tracer le tableau simple. De plus, vous pouvez enregistrer le tracé au format PNG. Voici le code simple pour vos besoins:

import numpy as np
import matplotlib.pyplot as plt

x = np.array([[1,2],[3,4]])

plt.figure()
plt.table(cellText=x,cellLoc='center',loc='center')
plt.axis('off')
plt.savefig('table.png')

La taille du tracé ou de l'image peut être ajustée en modifiant les figsizeparamètres de la ligne:plt.figure(figsize=(x,y))

Pour une meilleure apparence, il peut être modifié comme ci-dessous:

import numpy as np
import matplotlib.pyplot as plt

x = np.array([[1,2],[3,4]])

fig = plt.figure(figsize=(2,2))
plt.axis('off')
plt.axis('tight')
plt.table(cellText=x,cellLoc='center',loc='center')
#plt.subplots_adjust(hspace=0.5)
fig.tight_layout()
plt.savefig('table.png')
Ashwin Geet D'Sa
la source
3
Je ferais presque quelque chose commefig = plt.figure(figsize = x.shape)
Daniel F
4

Peut-être que cela aidera:

from matplotlib import pyplot as plt
import numpy as np

w  = 10
h  = 10 
img = np.random.randint(255, size=(w, h))
plt.figure(figsize=(5,8))
plt.imshow(img, interpolation='nearest')
plt.axis('off')

cellTextimg =  []
for j in range(0,h):
    cellTextimg.append(img[j,:])

the_table = plt.table(cellText= cellTextimg, loc='bottom')
Ivan
la source