Skip to main content
 首页 » 编程设计

python之Pandas 堆叠多级索引图

2025年05月04日10over140

我想为一个索引水平制作一个堆叠条形图,而另一个保持未堆叠状态。下面的代码为每个索引行创建元组:

from pandas import DataFrame, MultiIndex 
from numpy import repeat 
from numpy.random import randn 
arrays = [repeat('a b'.split(),2),[True,False,True,False]] 
midx = MultiIndex.from_tuples(zip(*arrays), names=['letters','bool']) 
df = DataFrame(randn(4,2)**2+5, index=midx) 
df.plot(kind='bar', stacked=True) 
plt.legend(loc="center right", bbox_to_anchor=(1.5, 0.5), ncol=2) 

但我更希望看到 (0,1) 并排分组,就像使用此 R 代码(在 IPython 中)时一样:

%load_ext rmagic 
dr = df.stack().reset_index() 

然后

%%R -i dr 
 
library(ggplot2) 
names(dr) <- c('letters','bool','n','value') 
 
    x <- ggplot() + 
      geom_bar(data=dr, aes(y = value, x = letters, fill = bool),  
               stat="identity", position='stack') + 
      theme_bw() +  
      facet_grid( ~ n) 
 
print(x) 

现在:在 pandas 中有没有办法做到这一点,我是否应该折磨 ma​​tplotlib,我是否应该安装 ggplot for python或者我应该使用 Rmagic 在 IPython 中运行 ggplot2(就像我刚才那样)?我无法获得 rpy2 的 ggplot 类

from rpy2.robjects.lib import ggplot2 

使用我的布局(还)。

请您参考如下方法:

如果你有 R 代码,可以逐步移植到 rpy2

import rpy2.robjects as ro 
 
ro.globalenv['dr'] = dr 
 
ro.r(""" 
library(ggplot2) 
names(dr) <- c('letters','bool','n','value') 
 
x <- ggplot() + 
  geom_bar(data=dr, aes(y = value, x = letters, fill = bool),  
           stat="identity", position='stack') + 
  theme_bw() +  
  facet_grid( ~ n) 
 
print(x) 
""") 

这样做的缺点是使用了 R 的 GlobalEnv。函数可以更优雅。

make_plot = ro.r(""" 
function(dr) { 
  names(dr) <- c('letters','bool','n','value') 
 
  x <- ggplot() + 
    geom_bar(data=dr, aes(y = value, x = letters, fill = bool),  
             stat="identity", position='stack') + 
    theme_bw() +  
    facet_grid( ~ n) 
 
  print(x) 
}""") 
 
make_plot(dr) 

另一种方法是在 rpy2 中使用 ggplot2 映射,并在不写的情况下写这个 R代码:

from rpy2.robjects import Formula 
from rpy2.robjects.lib.ggplot2 import ggplot, geom_bar, aes_string, theme_bw, facet_grid 
 
## oddity with names in the examples, that can either be corrected in the Python-pandas 
## structure or with an explicit conversion into an R object and renaming there 
drr = rpy2.robjects.pandas2ri.pandas2ri(dr) 
drr.names[2] = 'n' 
drr.names[3] = 'value' 
 
p = ggplot(drr) + \ 
    geom_bar(aes_string(x="letters", y="value", fill="bool"), 
             stat="identity", position="stack") + \ 
    theme_bw() + \ 
    facet_grid(Formula('~ n')) 
 
p.plot()