web-dev-qa-db-fra.com

Comment puis-je dessiner un graphique imshow normalisé avec une barre de couleur représentant les données brutes dans matplotlib

J'utilise matplotlib pour tracer des images normalisées au journal, mais j'aimerais que les données d'image brutes d'origine soient représentées dans la barre de couleurs plutôt que dans l'intervalle [0-1]. J'ai l'impression qu'il existe un moyen plus matplotlib'y de le faire en utilisant une sorte d'objet de normalisation et en ne transformant pas les données au préalable ... dans tous les cas, il pourrait y avoir des valeurs négatives dans l'image brute.

import matplotlib.pyplot as plt
import numpy as np

def log_transform(im):
    '''returns log(image) scaled to the interval [0,1]'''
    try:
        (min, max) = (im[im > 0].min(), im.max())
        if (max > min) and (max > 0):
            return (np.log(im.clip(min, max)) - np.log(min)) / (np.log(max) - np.log(min))
    except:
        pass
    return im

a = np.ones((100,100))
for i in range(100): a[i] = i
f = plt.figure()
ax = f.add_subplot(111)
res = ax.imshow(log_transform(a))
# the colorbar drawn shows [0-1], but I want to see [0-99]
cb = f.colorbar(res)

J'ai essayé d'utiliser cb.set_array, mais cela ne semblait rien faire, et cb.set_clim, mais cela redimensionne complètement les couleurs.

27
Adam Fraser

Oui il y a! Utilisez LogNorm. Voici un extrait de code d'un utilitaire que j'ai écrit pour afficher les matrices de confusion sur une échelle logarithmique.

from pylab import figure, cm
from matplotlib.colors import LogNorm
# C = some matrix
f = figure(figsize=(6.2,5.6))
ax = f.add_axes([0.17, 0.02, 0.72, 0.79])
axcolor = f.add_axes([0.90, 0.02, 0.03, 0.79])
im = ax.matshow(C, cmap=cm.gray_r, norm=LogNorm(vmin=0.01, vmax=1))
t = [0.01, 0.1, 0.2, 0.4, 0.6, 0.8, 1.0]
f.colorbar(im, cax=axcolor, ticks=t, format='$%.2f$')
f.show()
39
Steve Tjoa

Si vous souhaitez simplement que l'image soit normalisée au journal (pour améliorer les détails), mais pas les données (pour conserver les valeurs physiques), vous devez alors appliquer la transformation sur la palette de couleurs elle-même. Vous pouvez le faire avec la fonction cmap_map () donnée dans le livre de recettes: https://scipy-cookbook.readthedocs.io/items/Matplotlib_ColormapTransformations.html

7
Gilles