2016-11-30 7 views
0

J'ai une donnée qui ressemble à (exemple)parcelle personnalisée de correspondance de couleurs en utilisant les numéros fixes en utilisant matplotlib

x y d 
0 0 -2 
1 0 0 
0 1 1 
1 1 3 

Et je veux en faire un terrain coloumap qui ressemble à un de ces:

enter image description here

où x et y sont dans la table et la couleur est donnée par 'd'. Cependant, je veux une couleur prédéterminée pour chaque numéro, par exemple:

-2 - orange 
0 - blue 
1 - red 
3 - yellow 

pas nécessairement ces couleurs, mais je dois répondre à un certain nombre à une couleur et les chiffres ne sont pas dans l'ordre ou l'ordre, les justes sont un ensemble de cinq ou six nombres aléatoires qui se répètent sur l'ensemble du tableau.

Toutes les idées, je n'ai pas de code pour ça car je ne sais pas par où commencer. Je l'ai cependant regardé les exemples ici, tels que:

Matplotlib python change single color in colormap

Cependant, ils ne montrent que la façon de définir les couleurs et non comment lier ces couleurs à une valeur spécifique.

Répondre

1

Il s'avère que c'est plus difficile que je ne le pensais, alors peut-être que quelqu'un a un moyen plus facile de le faire.

Puisque nous avons besoin de créer une image des données, nous allons les stocker dans un tableau 2D. Nous pouvons ensuite mapper les données aux entiers 0 .. number of different data values et attribuer une couleur à chacun d'eux. La raison en est que nous voulons que la palette de couleurs finale soit équidistante. Alors

valeur -2 -> entier 0 -> couleur orange
valeur 0 -> entier 1 -> couleur blue et ainsi de suite. Avec des entiers bien espacés, nous pouvons utiliser un ListedColormap sur l'image des valeurs entières nouvellement créées.

import matplotlib.pyplot as plt 
import numpy as np 
import matplotlib.colors 

# define the image as a 2D array 
d = np.array([[-2,0],[1,3]]) 

# create a sorted list of all unique values from d 
ticks = np.unique(d.flatten()).tolist() 
# create a new array of same shape as d 
# we will later use this to store values from 0 to number of unique values 
dc = np.zeros(d.shape) 
#fill the array dc 
for i in range(d.shape[0]): 
    for j in range(d.shape[1]): 
     dc[i,j] = ticks.index(d[i,j]) 

# now we need n (= number of unique values) different colors   
colors= ["orange", "blue", "red", "yellow"] 
# and put them to a listed colormap 
colormap = matplotlib.colors.ListedColormap(colors) 


plt.figure(figsize=(5,3)) 
#plot the newly created array, shift the colorlimits, 
# such that later the ticks are in the middle 
im = plt.imshow(dc, cmap=colormap, interpolation="none", vmin=-0.5, vmax=len(colors)-0.5) 
# create a colorbar with n different ticks 
cbar = plt.colorbar(im, ticks=range(len(colors))) 
#set the ticklabels to the unique values from d 
cbar.ax.set_yticklabels(ticks) 
#set nice tickmarks on image 
plt.gca().set_xticks(range(d.shape[1])) 
plt.gca().set_yticks(range(d.shape[0])) 

plt.show() 

enter image description here


Comme il ne peut pas être intuitivement clair comment obtenir le tableau d sous la forme nécessaire pour tracer avec imshow, soit sous forme de tableau 2D, voici deux façons de convertir l'entrée colonnes de données:

import numpy as np 

x = np.array([0,1,0,1]) 
y = np.array([ 0,0,1,1]) 
d_original = np.array([-2,0,1,3]) 

#### Method 1 #### 
# Intuitive method. 
# Assumption: 
# * Indexing in x and y start at 0 
# * every index pair occurs exactly once. 
# Create an empty array of shape (n+1,m+1) 
# where n is the maximum index in y and 
#   m is the maximum index in x 
d = np.zeros((y.max()+1 , x.max()+1), dtype=np.int) 
for k in range(len(d_original)) : 
    d[y[k],x[k]] = d_original[k] 
print d 

#### Method 2 #### 
# Fast method 
# Additional assumption: 
# indizes in x and y are ordered exactly such 
# that y is sorted ascendingly first, 
# and for each index in y, x is sorted. 
# In this case the original d array can bes simply reshaped 
d2 = d_original.reshape((y.max()+1 , x.max()+1)) 
print d2 
+0

Hey mate, cela ressemble exactement à ce que je voulais faire. Juste une question cependant. Mes données sont une longue liste de nombres (comme une centaine). J'ai les positions x et y que vous n'avez pas l'air d'utiliser. Mais comment puis-je utiliser une longue liste de valeurs dans le tableau 2D, ce qui serait votre d? – Mac

+0

Je suppose que je devrais créer un tableau, dire si mes données donnent un graphique de couleurs de 10 x 10, j'ai besoin d'un tableau de 10 x 10, est-ce exact? – Mac

+1

J'ai édité la réponse pour inclure comment faire le tableau requis de la structure de colonne que vous avez. Il est en effet vrai, que pour tracer un graphique 10x10, vous avez besoin d'un tableau 10x10. L'indexation est faite implicitement, la première colonne, la première ligne de ce tableau est l'index 0,0. Dernière colonne, la dernière rangée aurait l'index 9,9. – ImportanceOfBeingErnest