2017-04-12 96 views
0

我想在網格中繪製一系列的seaborn座標圖。我知道小區的數量(可以是奇數或偶數)。 熱圖將顯示「星期幾」(y軸)和「一小時」(x軸)的平均「佔有率」,例如,他們都共享相同的x/y域。共享座標軸並移除未使用的matplotlib子圖

這裏是我當前的代碼:

df2 = df[['name','openLots','occupationRatio','DoW','Hour']] 
fig, axs = plt.subplots(figsize=(24,24), nrows=7, ncols=6) 
axs = axs.flatten() 
locations = df2['name'].sort_values().unique() 


def occupation_heatmap (name, ax): 
    dfn = df2[df2['name'] == name] 
    dfn = dfn.groupby(['DoW', 'Hour']).mean()['occupationRatio'].unstack() 
    dfn = dfn.reindex(['Mon', 'Tue', 'Wed','Thu','Fri','Sat','Sun']) 
    sns.heatmap(data=dfn, cmap="coolwarm", vmin=0, vmax=1.0, ax= ax) 
    ax.set_title(name) 


i = 0 
for n in locations: 
    occupation_heatmap (n, axs[i]) 
    i = i+1 

plt.tight_layout() 

它看起來幾乎像什麼,我想(最後幾行): note axis labels, legend and "empty" subplots 但是要我要:

  • 有y軸的標籤(DoW)每行只有一次(最左邊的圖)
  • 只在每行最右邊的圖上有colormap圖例(或者不要完全,顏色是很好的自我explainatory)
  • 刪除「空陰謀」的最後一排,因爲奇數總數的

非常感謝任何提示

+1

只是爲了幫助提高你怎麼心智模型事情正在起作用,這些不是「seaborn subplots」,它們是matplotlib subplots,你碰巧使用seaborn函數來繪製數據。 – mwaskom

回答

1

你可以更加靈活只爲每個現名軸,像這樣:

import matplotlib.pyplot as plt 
import pandas as pd 
import numpy as np 
import seaborn as sns 
import string 

days = ['Mon','Tue','Wed','Thurs','Fri','Sat','Sun'] 
names = [string.lowercase[i] for i in range(22)] 

nItems = 1000 

df = pd.DataFrame() 
df['name'] = [names[i] for i in np.random.randint(0,len(names),nItems)] 
df['openLots'] = np.random.randint(0,100,nItems) 
df['occupationRatio'] = np.random.randint(0,100,nItems) 
df['DoW'] = [days[i] for i in np.random.randint(0,7,nItems)] 
df['Hour'] = np.random.randint(0,12,nItems) 




fig = plt.figure(figsize=(12,12)) 
for index, name in enumerate(names): 
    ax = fig.add_subplot(4,6,index+1) 
    dfn = df.loc[df.name==name] 
    dfn = dfn.groupby(['DoW','Hour']).mean()['occupationRatio'].unstack() 
    dfn = dfn.reindex(days) 

    # Now we can operate on each plot axis individually 
    if index%6!=5: #i.e. 
     # Don't draw a colorbar 
     sns.heatmap(data = dfn, cmap='coolwarm', ax=ax, cbar=False) 
    else: 
     sns.heatmap(data = dfn, cmap='coolwarm', ax=ax) 

    if index%6!=0: 
     # Remove the y-axis label 
     ax.set_ylabel('') 
     ax.set_yticks(()) 

    ax.set_title(name) 

fig.tight_layout() 
fig.show() 

結果: enter image description here 你也可以玩與x軸(例如刪除啦貝爾和蜱蟲,除了最下面一排)。

+0

謝謝,這對我來說工作得非常好......除了我有一些數據片是完整的NaN,所以不得不包裝sns.heatmap(...)變成 '嘗試: ... 除了ValueError: pass ' –

1
  • 有y軸標籤(DOW)每行(最左邊的圖)只有一次
    這可以使用sharey = True作爲參數傳遞給plt.subplots完成。
  • 只有每行最右邊的圖中的顏色表傳奇(或離開它完全,顏色是很好的自我explainatory)
    使用cbar = False參數seaborn.heatmap爲了不顯示彩條。這可以根據子圖的實際數量作爲繪圖函數的輸入給出。
  • 除去最後一排的「空陰謀」,因爲奇數總數的
    循環創建情節您可以添加另一個循環刪除未使用的軸之後。

    for j in range(len(locations), ncols*nrows): 
        axs[j].axis("off") 
    

下面是一個完整的例子(在這裏我借了鱈魚,以從@Robbie一個數據幀):

import matplotlib.pyplot as plt 
import pandas as pd 
import numpy as np 
import seaborn as sns 

days = ['Mon','Tue','Wed','Thurs','Fri','Sat','Sun'] 
names = ["Parkhaus {:02}".format(i+1) for i in range(22)] 

nItems = 1000 

df = pd.DataFrame() 
df['name'] = [names[i] for i in np.random.randint(0,len(names),nItems)] 
df['openLots'] = np.random.randint(0,100,nItems) 
df['occupationRatio'] = np.random.rand(nItems) 
df['DoW'] = [days[i] for i in np.random.randint(0,7,nItems)] 
df['Hour'] = np.random.randint(0,12,nItems) 

df2 = df[['name','openLots','occupationRatio','DoW','Hour']] 
nrows = 4; ncols=6 
fig, axs = plt.subplots(nrows=nrows, ncols=ncols, figsize=(15,9), sharey=True) 
axs = axs.flatten() 
locations = df2['name'].sort_values().unique() 


def occupation_heatmap (name, ax, cbar=False, ylabel=False): 
    dfn = df2[df2['name'] == name] 
    dfn = dfn.groupby(['DoW', 'Hour']).mean()['occupationRatio'].unstack() 
    dfn = dfn.reindex(['Mon', 'Tue', 'Wed','Thu','Fri','Sat','Sun']) 
    sns.heatmap(data=dfn, cmap="coolwarm", vmin=0, vmax=1.0, ax=ax, cbar=cbar) 
    ax.set_title(name) 
    plt.setp(ax.get_yticklabels(), rotation=0) 
    if not ylabel: ax.set_ylabel("") 


for i, n in enumerate(locations): 
    occupation_heatmap (n, axs[i], cbar=i%ncols==ncols-1, ylabel=i%ncols==0) 
for j in range(len(locations), ncols*nrows): 
    axs[j].axis("off") 

plt.tight_layout() 
plt.show() 

enter image description here

相關問題