2017-07-07 2 views
0

Maintenant, j'ai une image comme fig1 et une couleur différente signifie une chose différente, et je veux ajouter une légende (fig2) au bas de la fig1, comment faire cela? J'ai la valeur rgb de chaque couleur.Comment tracer une légende en fonction de sa couleur sur une image?

Figure 1: enter image description here

Figure 2: enter image description here

ce qui est le code que je suis:

# coding=utf-8 
import matplotlib 
matplotlib.use('Agg') 
import h5py 
import numpy 
from PIL import Image 
from PIL import ImageDraw 
import matplotlib.pyplot as plt 
import matplotlib.ticker as plticker 
import sys 
table={ 
    k:v for k,v,n in [ 

[ 
     127, 
     [ 
      100, 
      100, 
      100 
     ], 
     "NO DATA" 
    ], 
    [ 
     126, 
     [ 
      0, 
      0, 
      0 
     ], 
     "SPACE" 
    ], 
    [ 
     0, 
     [ 
      200, 
      255, 
      255 
     ], 
     "CLEAR" 
    ], 
    [ 
     2, 
     [ 
      0, 
      0, 
      244 
     ], 
     "WATER CLOUD" 
    ], 
    [ 
     3, 
     [ 
      32, 
      165, 
      225 
     ], 
     "ICED CLOUD" 
    ], 
    [ 
     4, 
     [ 
      33, 
      255, 
      170 
     ], 
     "MIXED CLOUD" 
    ], 
    [ 
     5, 
     [ 
      255, 
      0, 
      0 
     ], 
     "CIRRUS CLOUD" 
    ], 
    [ 
     6, 
     [ 
      180, 
      20, 
      255 
     ], 
     "Opaque cloud" 
    ], 
    [ 
     7, 
     [ 
      105, 
      255, 
      0 
     ], 
     "OVERLAP CLOUD" 
    ], 
    [ 
     9, 
     [ 
      224, 
      180, 
      0 
     ], 
     "UNKNOWN CLOUD" 
    ] 
] 
} 


def main(_,fn,out): 
    with h5py.File(fn) as f: 
     data = f['EVB1'].value 
    w,h = data.shape 
    ret = numpy.zeros((w,h,3),'u1') 
    for i in (0,2,3,4,5,6,7,9,126,127): 
     ret[data==i]=table[i] 

    Image.fromarray(ret,mode="RGB").save(out) 
    image = Image.open(out) 
    my_dpi = 100. 


    # Set up figure 
    fig = plt.figure(figsize=(float(image.size[0])/my_dpi,float(image.size[1])/my_dpi), dpi=my_dpi) 
    ax = fig.add_subplot(111) 

# Set the gridding interval: here we use the major tick interval 
    myInterval = 249.9 
    loc = plticker.MultipleLocator(base=myInterval) 
    # ax=plt.gca() 
    ax.xaxis.set_major_locator(loc) 
    ax.yaxis.set_major_locator(loc) 

    ax.set_xticklabels(['60', '70', '80', '90', '100', '110', '120', '130', '140']) 
# ax.set_xticklabels(np.arange(70,150,10)) 
    ax.set_yticklabels(('70', '60', '50', '40', '30', '20', '10', '0')) 
# 


    out1 = out.split('/')[-1].split('.')[0].split('V0001')[0] 

    ax.set_title(out1,fontsize = 20) 

# Add the grid 
    ax.grid(which='major', axis='both', linestyle='-') 

# Add the image 
    ax.imshow(image) 


# Save the figure 
    fig.savefig(out) 



if __name__ == '__main__': 
    main(*sys.argv) 
+1

Bienvenue dans Stack Overflow! Malheureusement, avec les informations que vous nous fournissez, il est très difficile de vous aider. Reportez-vous à [Comment créer un exemple minimal, complet et vérifiable] (https://stackoverflow.com/help/mcve). En bref, veuillez nous fournir le code que vous avez utilisé pour générer votre image et toutes les balises pertinentes (je suppose qu'il manque au moins la balise 'matplotlib'.) –

+0

Montrez ce que vous avez essayé – eyllanesc

Répondre

1

Je ne pouvais pas les caractères chinois pour afficher correctement, mais vous devriez avoir l'idée de base:

# coding=utf-8 
from matplotlib import pyplot as plt 
from matplotlib.patches import Rectangle 
import numpy as np 

x = np.linspace(0,1,100) 
y = np.linspace(0,1,100) 

X,Y = np.meshgrid(x,y) 

array = np.sin(X)*np.cos(Y) 

plt.imshow(array) 

legend_data = [ 
    [ 
    127, 
    [ 
     100, 
     100, 
     100 
    ], 
    "无数据区" 
], 
[ 
    126, 
    [ 
     0, 
     0, 
     0 
    ], 
    "外太空" 
], 
[ 
    0, 
    [ 
     200, 
     255, 
     255 
    ], 
    "晴空" 
], 
[ 
    2, 
    [ 
     0, 
     0, 
     244 
    ], 
    "水云" 
], 
[ 
    3, 
    [ 
     32, 
     165, 
     225 
    ], 
    "过冷水云" 
], 
[ 
    4, 
    [ 
     33, 
     255, 
     170 
    ], 
    "混合云" 
], 
[ 
    5, 
    [ 
     255, 
     0, 
     0 
    ], 
    "厚冰云" 
], 
[ 
    6, 
    [ 
     180, 
     20, 
     255 
    ], 
    "卷云" 
], 
[ 
    7, 
    [ 
     105, 
     255, 
     0 
    ], 
    "多层云" 
], 
[ 
    9, 
    [ 
     224, 
     180, 
     0 
    ], 
    "不确定" 
] 
]  
handles = [ 
    Rectangle((0,0),1,1, color = (v/255 for v in c)) for k,c,n in legend_data 
] 
labels = [n for k,c,n in legend_data] 

plt.legend(handles,labels) 
plt.show() 

Le résultat ressemble à ceci:

result of the code above

L'intrigue est juste un espace réservé, comme je n'ai pas vos données d'entrée. Les lignes cruciales sont celles qui produisent les rectangles handles et labels de votre table et la commande label à la fin.

EDIT:

Si vous voulez la légende strictement inférieure à l'intrigue, vous pouvez pour en définissant un second axe pour la légende:

from matplotlib import pyplot as plt 
from matplotlib.patches import Rectangle 
from matplotlib.gridspec import GridSpec 
import numpy as np 

from matplotlib.font_manager import FontProperties 
ChineseFont = FontProperties('SimHei') 

x = np.linspace(0,1,100) 
y = np.linspace(0,1,100) 

X,Y = np.meshgrid(x,y) 

array = np.sin(X)*np.cos(Y) 

gs = GridSpec(6,1) 

fig = plt.figure(figsize = (4,6)) 
ax1 = fig.add_subplot(gs[:-1,:]) ##for the plot 
ax2 = fig.add_subplot(gs[-1,:]) ##for the legend 

ax1.imshow(array) 

legend_data =[ 
[ 
     127, 
     [ 
      100, 
      100, 
      100 
     ], 
     u"无数据区" 
    ], 
... 
] 
handles = [ 
    Rectangle((0,0),1,1, color = tuple((v/255 for v in c))) for k,c,n in legend_data 
] 
labels = [n for k,c,n in legend_data] 

ax2.legend(handles,labels, mode='expand', ncol=3, prop=ChineseFont) 
ax2.axis('off') 
plt.show() 

Cela ressemble à ceci:

fully working example output

EDIT2:

J'ai trouvé un moyen d'afficher les caractères chinois correctement avec l'aide de this answer. L'exemple devrait maintenant fonctionner dans Python 2.7 et Python 3.5 - juste ajouter un u à chaque étiquette et diviser par 255.0 au lieu de seulement 255.

+0

Merci beaucoup! J'ai l'erreur 'ValueError: to_rgba: Invalid rgba arg " à 0x2adbdf447f00>" objet de type' generator 'n'a pas len()' at 'Rectangle ((0, 0), 1, 1, color = (v/255 pour v dans c)) pour k, c, n dans legend_data ', et s'il est possible de mettre la légende sous l'image? – Dawn

+0

@Dawn quelle version de python utilisez-vous? J'utilise python 3.5 –

+0

I utilisez python 2.7 – Dawn