2013-10-27 29 views
3

我正在製作一系列具有兩個分類變量和一個數字的數據柱狀圖。我所擁有的是以下內容,但是我想要做的是由facet_wrapggplot中的一個分類變量構成。我有一個有點工作的例子,但是我得到了錯誤的繪圖類型(線條而不是線條),並且我在循環中對數據進行了子集化 - 這不是最好的方法。pandas/matplotlib:分麪條圖

## first try--plain vanilla 
import pandas as pd 
import numpy as np 
N = 100 

## generate toy data 
ind = np.random.choice(['a','b','c'], N) 
cty = np.random.choice(['x','y','z'], N) 
jobs = np.random.randint(low=1,high=250,size=N) 

## prep data frame 
df_city = pd.DataFrame({'industry':ind,'city':cty,'jobs':jobs}) 
df_city_grouped = df_city.groupby(['city','industry']).jobs.sum().unstack() 
df_city_grouped.plot(kind='bar',stacked=True,figsize=(9, 6)) 

這給了這樣的事情:

city industry jobs 
0 z  b 180 
1 z  c 121 
2 x  a 33 
3 z  a 121 
4 z  c 236 

firstplot

不過,我想看到的是這樣的:

## R code 
library(plyr) 
df_city<-read.csv('/home/aksel/Downloads/mockcity.csv',sep='\t') 

## summarize 
df_city_grouped <- ddply(df_city, .(city,industry), summarise, jobstot = sum(jobs)) 

## plot 
ggplot(df_city_grouped, aes(x=industry, y=jobstot)) + 
    geom_bar(stat='identity') + 
    facet_wrap(~city) 

enter image description here

我matplotlib得到最接近的是這樣的:

cols =df_city.city.value_counts().shape[0] 
fig, axes = plt.subplots(1, cols, figsize=(8, 8)) 

for x, city in enumerate(df_city.city.value_counts().index.values): 
    data = df_city[(df_city['city'] == city)] 
    data = data.groupby(['industry']).jobs.sum() 
    axes[x].plot(data) 

enter image description here

所以兩個問題:

  1. 我可以做吧地塊(他們的情節線,如下所示)使用AxesSubplot對象,並以沿着從ggplot示例的facet_wrap示例的行結束的東西;
  2. 在循環生成圖表,如這種嘗試,我分別在每個數據子集。我無法想象這是做這種刻面的「正確」方式?
+0

你爲什麼不在你的循環中使用'bar'? – tacaswell

+0

@tcaswell,很好的建議。繪製條形圖的訣竅是什麼?這兩個參數似乎都需要作爲數字。先轉換分類變量?有沒有更規範的方法? – ako

+0

查看http://matplotlib.org/api/axes_api.html#matplotlib.axes.Axes.bar – tacaswell

回答

3

第二個例子在這裏:http://pandas.pydata.org/pandas-docs/dev/visualization.html#bar-plots

不管怎麼說,你總是可以做到這一點的手,像你一樣自己。

編輯: BTW,你可以隨時使用rpy2在Python,所以你可以做所有的相同的事情R.

而且,看看這個:http://pandas.pydata.org/pandas-docs/stable/rplot.html 我不知道,但它應該有助於在許多面板上創建繪圖,但可能需要進一步閱讀。

+0

我想這是但是我真的很喜歡它們在單獨的面板中,因爲'ggplot'就是這樣做的,特別是因爲隨着更多維度的添加,這是靈活的。當然,這個例子並不喜歡數據框變量是非數字的。有沒有一個很好的方法來解決這個問題? – ako

+0

請參閱編輯答案。 – Phlya

+0

這看起來完全像我正在尋找的開箱即用 - 無需在每個循環中對數據進行子集分類。剩下的就是讓我理解在情節中繪製分類變量的「正確」方式。 – ako

1

@tcasell建議在循環中調用bar。這是一個工作的,如果不是優雅的例子。

## second try--facet by county 

N = 100 
industry = ['a','b','c'] 
city = ['x','y','z'] 
ind = np.random.choice(industry, N) 
cty = np.random.choice(city, N) 
jobs = np.random.randint(low=1,high=250,size=N) 
df_city =pd.DataFrame({'industry':ind,'city':cty,'jobs':jobs}) 

## how many panels do we need? 
cols =df_city.city.value_counts().shape[0] 
fig, axes = plt.subplots(1, cols, figsize=(8, 8)) 

for x, city in enumerate(df_city.city.value_counts().index.values): 
    data = df_city[(df_city['city'] == city)] 
    data = data.groupby(['industry']).jobs.sum() 
    print (data) 
    print type(data.index) 
    left= [k[0] for k in enumerate(data)] 
    right= [k[1] for k in enumerate(data)] 

    axes[x].bar(left,right,label="%s" % (city)) 
    axes[x].set_xticks(left, minor=False) 
    axes[x].set_xticklabels(data.index.values) 

    axes[x].legend(loc='best') 
    axes[x].grid(True) 
    fig.suptitle('Employment By Industry By City', fontsize=20) 

enter image description here

+0

1個微妙的區別是,這裏所有3個地塊有不同的規模,這使得很難跨面板比較 –