2017-07-07 88 views
0

現在我得到了像fig1這樣的圖像,不同的顏色意味着不同的東西,我想在圖1的底部添加一個圖例(圖2),該怎麼做?我有每種顏色的RGB值。如何根據圖像上的顏色繪製圖例?

圖1: enter image description here

圖2: enter image description here

,這是我的代碼:

# 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

歡迎來到Stack Overflow!不幸的是,根據您提供的信息,很難幫助您。請參閱[如何創建最小,完整和可驗證示例](https://stackoverflow.com/help/mcve)。簡而言之,請向我們提供您用於生成圖像和所有相關標籤的代碼(我猜測至少matplotlib標籤丟失了) –

+0

顯示您嘗試過的內容 – eyllanesc

回答

1

我不能讓中國漢字正確顯示,但你應該得到基本的想法:

# 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() 

結果看起來是這樣的:

result of the code above

情節只是一個佔位符,因爲我沒有你的輸入數據。關鍵線是那些從表格和標籤命令產生矩形handleslabels的結果。

編輯

如果你想嚴格下面的情節的傳說,你可以這樣定義圖例的第二軸:

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

這看起來是這樣的:

fully working example output

EDIT2

我找到了一種在this answer幫助下正確顯示漢字的方法。現在該示例應該在Python 2.7和Python 3.5中工作 - 只需在每個標籤前加上u,然後除以255.0而不僅僅是255

+0

非常感謝!我得到錯誤'ValueError:to_rgba:Invalid rgba arg'<生成器對象 at 0x2adbdf447f00>「 '類型'generator'的對象在'Rectangle((0,0),1,1,color = (v/255 for v in c))for k,c,n in legend_data',並且如果可以將圖例置於圖像下? – Dawn

+0

@Dawn您使用的是什麼版本的python?我使用python 3.5 –

+0

我使用python 2.7 – Dawn