Obter imagem matricial de valores numéricos de matriz - Grade com valores de pixel dentro (não cores)

9

Eu pesquisei online e não consegui encontrar nada sobre isso que faça o que eu quero.

Gostaria de salvar uma matriz numpy como uma imagem, mas em vez de ter uma imagem colorida, quero uma representação em preto e branco dos valores de pixel no local da grade correspondente.

Por exemplo:

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

Gostaria de salvar isso como uma imagem (.PNG) parecida com a seguinte:

resultado esperado

Meu código atual cria uma grade e coloca os números dentro, mas é muito difícil ajustar tudo para torná-lo apresentável em um trabalho de pesquisa.

Então, em vez de postar meu código excessivamente complexo, fiquei pensando se há uma função integrada para lidar com isso em algumas linhas de código.

lbragile
fonte
11
Parece que tableseria um bom lugar para começar. Não usei o suficiente para dar uma boa resposta.
Warren Weckesser 27/11/19
11
Veja 'Table Demo' para um exemplo que usa table.
Warren Weckesser 27/11/19
4
Eu usaria o LaTeX para uma mesa que você está tentando colocar em um papel, em vez de uma imagem rasterizada.
alkasm
@alkasm o problema é que minhas matrizes reais são muito maiores (14x14 ou 28x28) e preciso criar muitas imagens para elas, portanto, fazê-lo manualmente no LaTex parece um método muito ineficiente.
Lbragile
5
Pelo contrário, rasterizar para imagens soa como o método ineficiente. As tabelas de dados não são imagens e, portanto, não devem ser tratadas como tal. Você pode gerar automaticamente o LaTeX, mesmo manualmente, com extrema facilidade.
alkasm

Respostas:

12

Eu usaria o LaTeX para gerar as tabelas, uma vez que elas parecem elegantes e você pode gerar uma imagem ou colocá-las diretamente em seu documento. Eu usei o seguinte código para conseguir isso:

#!/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")

Aqui, previewé usada a classe de documento que retorna uma imagem redimensionada para o conteúdo do documento, ou seja, apenas a tabela. Somente um tabularambiente é usado para apresentar os dados. Existem barras horizontais e verticais entre as células, mas é muito fácil mudar isso. Na variável, tabos dados são processados ​​para cada linha e convertidos em uma sequência. Observe que você precisa especificar o formato de saída nesta posição. Eu configurei para%d que tudo seja convertido em números inteiros.

Se você deseja usar a tabela diretamente em uma fonte de látex, é necessário remover documentclasse \begin{document}também \end{document}as variáveis ​​de starte end. Finalmente, tudo é reunido em uma fonte de látex que é então armazenada no disco como table.tex. Se você deseja apenas a imagem no final, o arquivo resultante é compilado paratable.pdf .

Aqui está a aparência da saída. Mas como eu disse, é muito fácil mudar a aparência, pois é o LaTeX :)

mesa

Aqui está outro exemplo com uma matriz grande (14 x 14), preenchida com números aleatórios que variam de 0 a 100:

mesa 2

Solvalou
fonte
8

Você pode usar a tablefunção de matplotpara plotar a tabela simples. Além disso, você pode salvar o gráfico como PNG. Abaixo está o código simples para seus requisitos:

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')

O tamanho da plotagem ou imagem pode ser ajustado alterando os figsizeparâmetros na linha:plt.figure(figsize=(x,y))

Para uma melhor aparência, pode ser modificado como abaixo:

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
fonte
3
Eu quase faria algo comofig = plt.figure(figsize = x.shape)
Daniel F
4

Pode ser que isso ajude:

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
fonte