Plotnine:按列分面
Plotnine: facet by column
我的数据框 MedComp
具有以下结构:
我现在想做一个堆叠条形图,每个 Name
一个(有两个不同的),按 Type
堆叠(目前使用颜色完成)。 y 轴是剩余的列,由于范围非常不同,每列都有一个单独的图。对于 Name
中的一种 Crops,我还想显示总数的误差条,目前在一个名为 FarmQuant
的单独数据框中计算,如下所示:
到目前为止,我只使用循环进行管理,因此每列创建一个图形:
Midpoint = [['GHG', 'Total climate change [kg CO2e]'],
['Acid', 'Freshwater & ter. acidification [mol H+-Eq]'],
['Terra Eutro', 'Terrestrial eutrophication [mol N-Eq]'],
['Toxicity', 'Freshwater ecotoxicity [CTU]'],
['Marine Eutro', 'Marine eutrophication [kg N-Eq]' ],
]
for MPID in range(0, len(Midpoint)):
print(MPID+1, len(Midpoint), ' ', end='')
q = (ggplot(Farm_Quant))
+ geom_col(MedComb, aes('Name', Midpoint[MPID][0], fill='Type'))
+ scale_fill_brewer(type='div', palette=2)
+ geom_point(Farm_Quant, aes(x=1, y=Farm_Quant.loc['q2',Midpoint[MPID][0]]))
+ geom_errorbar(aes(x=1,ymin = Farm_Quant.loc['q1',Midpoint[MPID][0]], ymax = Farm_Quant.loc['q3',Midpoint[MPID][0]]))
+ theme_matplotlib()
+ theme(figure_size=(2.2, 4), legend_position = (1.25, 0.5),
axis_title_x =element_blank(),
axis_ticks_major_x=element_blank())
+ scale_y_continuous(name=Midpoint[MPID][1])
+ labs(title = Midpoint[MPID][0])
)
fig = q.draw()
fig.show()
但是,我想使用 facet 来做到这一点,将所有内容都集中在一个只有一个图例的图形中。有人知道如何使用吗?
请仅提供 matplotlib(据我所知不支持分面)或 plotnine 的示例,因为我已经完成了其他几个绘图,并且希望保持相同的外观。加上我最熟悉的那些。
编辑:
现在这里还有一些测试数据可以使用:
MedComb = pd.DataFrame({
'Name' : ['Crop1', 'Crop1', 'Crop1', 'Crop1', 'Crop2', 'Crop2', 'Crop2', 'Crop2'],
'Type' : ['Area', 'Diesel', 'Fert', 'Pest', 'Area', 'Diesel', 'Fert', 'Pest'],
'GHG': [14.9, 0.0007, 0.145, 0.1611, 2.537, 0.011, 0.1825, 0.115],
'Acid': [0.0125, 0.0005, 0.0029, 0.0044, 0.013, 0.00014, 0.0033, 0.0055],
'Terra Eutro': [0.053, 0.0002, 0.0077, 0.0001, 0.0547, 0.00019, 0.0058, 0.0002]
})
Farm_Quant = pd.DataFrame({
'Amount': [0.388, 0.4129, 0.1945],
'GHG': [8.029, 20.61, 44.32],
'Acid': [0.009, 0.019, 0.044],
'Terra Eutro': [0.039, 0.077, 0.0177]},
index = ['q1', 'q2', 'q3']
)
当您的 geom
美学在他们自己的专栏中时,Plotnine 效果最好,因此您可以通过 melt
使用您的数据框来实现分面。此外,如果您将 Farm_Quant
数据框连接到您融化的 MedComb 数据框,那么您可以只引用该单个数据框并删除您的 for 循环。
# Sample Data
MedComb = pd.DataFrame({
'Name' : ['Crop1', 'Crop1', 'Crop1', 'Crop1', 'Crop2', 'Crop2', 'Crop2', 'Crop2'],
'Type' : ['Area', 'Diesel', 'Fert', 'Pest', 'Area', 'Diesel', 'Fert', 'Pest'],
'GHG': [14.9, 0.0007, 0.145, 0.1611, 2.537, 0.011, 0.1825, 0.115],
'Acid': [0.0125, 0.0005, 0.0029, 0.0044, 0.013, 0.00014, 0.0033, 0.0055],
'Terra Eutro': [0.053, 0.0002, 0.0077, 0.0001, 0.0547, 0.00019, 0.0058, 0.0002]
})
Farm_Quant = pd.DataFrame({
'Amount': [0.388, 0.4129, 0.1945],
'GHG': [8.029, 20.61, 44.32],
'Acid': [0.009, 0.019, 0.044],
'Terra Eutro': [0.039, 0.077, 0.0177]},
index = ['q1', 'q2', 'q3']
)
# melt the MedComb df from wide to long
med_comb_long = pd.melt(MedComb,id_vars=['Name','Type'],
var_name='midpoint',value_name='value')
# Basically transpose the Farm_Quant df in two steps to join with med_comb_long
# convert the Farm_Quant df from wide to long and make the quarters a column
midpoint_long = pd.melt(Farm_Quant.reset_index().drop(columns=['Amount']),
id_vars=['index'],var_name='midpoint',value_name='error_bar')
# make long farm quant df wide again, but with the quarters as the columns and facet names as index
midpoint_reshape = pd.pivot(midpoint_long,index='midpoint',columns='index',
values='error_bar')
# Join the data for the bar charts and error bars/points into single df
plot_data = med_comb_long.join(midpoint_reshape,on='midpoint')
# make the plot
q2 = (ggplot(plot_data)
+ geom_col(aes('Name','value',fill='Type'))
+ scale_fill_brewer(type='div', palette=2)
+ facet_wrap('midpoint',scales='free')
+ geom_errorbar(aes(x=1,ymin='q1',ymax='q3'))
+ geom_point(aes(x=1,y='q2'))
+ theme_matplotlib()
# + theme(figure_size=(2.2, 4), legend_position = (1.25, 0.5),
# axis_title_x =element_blank(),
# axis_ticks_major_x=element_blank())
+ scale_y_continuous(name=Midpoint[MPID][1])
+ labs(title = Midpoint[MPID][0])
)
q2
我的数据框 MedComp
具有以下结构:
我现在想做一个堆叠条形图,每个 Name
一个(有两个不同的),按 Type
堆叠(目前使用颜色完成)。 y 轴是剩余的列,由于范围非常不同,每列都有一个单独的图。对于 Name
中的一种 Crops,我还想显示总数的误差条,目前在一个名为 FarmQuant
的单独数据框中计算,如下所示:
到目前为止,我只使用循环进行管理,因此每列创建一个图形:
Midpoint = [['GHG', 'Total climate change [kg CO2e]'],
['Acid', 'Freshwater & ter. acidification [mol H+-Eq]'],
['Terra Eutro', 'Terrestrial eutrophication [mol N-Eq]'],
['Toxicity', 'Freshwater ecotoxicity [CTU]'],
['Marine Eutro', 'Marine eutrophication [kg N-Eq]' ],
]
for MPID in range(0, len(Midpoint)):
print(MPID+1, len(Midpoint), ' ', end='')
q = (ggplot(Farm_Quant))
+ geom_col(MedComb, aes('Name', Midpoint[MPID][0], fill='Type'))
+ scale_fill_brewer(type='div', palette=2)
+ geom_point(Farm_Quant, aes(x=1, y=Farm_Quant.loc['q2',Midpoint[MPID][0]]))
+ geom_errorbar(aes(x=1,ymin = Farm_Quant.loc['q1',Midpoint[MPID][0]], ymax = Farm_Quant.loc['q3',Midpoint[MPID][0]]))
+ theme_matplotlib()
+ theme(figure_size=(2.2, 4), legend_position = (1.25, 0.5),
axis_title_x =element_blank(),
axis_ticks_major_x=element_blank())
+ scale_y_continuous(name=Midpoint[MPID][1])
+ labs(title = Midpoint[MPID][0])
)
fig = q.draw()
fig.show()
但是,我想使用 facet 来做到这一点,将所有内容都集中在一个只有一个图例的图形中。有人知道如何使用吗?
请仅提供 matplotlib(据我所知不支持分面)或 plotnine 的示例,因为我已经完成了其他几个绘图,并且希望保持相同的外观。加上我最熟悉的那些。
编辑: 现在这里还有一些测试数据可以使用:
MedComb = pd.DataFrame({
'Name' : ['Crop1', 'Crop1', 'Crop1', 'Crop1', 'Crop2', 'Crop2', 'Crop2', 'Crop2'],
'Type' : ['Area', 'Diesel', 'Fert', 'Pest', 'Area', 'Diesel', 'Fert', 'Pest'],
'GHG': [14.9, 0.0007, 0.145, 0.1611, 2.537, 0.011, 0.1825, 0.115],
'Acid': [0.0125, 0.0005, 0.0029, 0.0044, 0.013, 0.00014, 0.0033, 0.0055],
'Terra Eutro': [0.053, 0.0002, 0.0077, 0.0001, 0.0547, 0.00019, 0.0058, 0.0002]
})
Farm_Quant = pd.DataFrame({
'Amount': [0.388, 0.4129, 0.1945],
'GHG': [8.029, 20.61, 44.32],
'Acid': [0.009, 0.019, 0.044],
'Terra Eutro': [0.039, 0.077, 0.0177]},
index = ['q1', 'q2', 'q3']
)
当您的 geom
美学在他们自己的专栏中时,Plotnine 效果最好,因此您可以通过 melt
使用您的数据框来实现分面。此外,如果您将 Farm_Quant
数据框连接到您融化的 MedComb 数据框,那么您可以只引用该单个数据框并删除您的 for 循环。
# Sample Data
MedComb = pd.DataFrame({
'Name' : ['Crop1', 'Crop1', 'Crop1', 'Crop1', 'Crop2', 'Crop2', 'Crop2', 'Crop2'],
'Type' : ['Area', 'Diesel', 'Fert', 'Pest', 'Area', 'Diesel', 'Fert', 'Pest'],
'GHG': [14.9, 0.0007, 0.145, 0.1611, 2.537, 0.011, 0.1825, 0.115],
'Acid': [0.0125, 0.0005, 0.0029, 0.0044, 0.013, 0.00014, 0.0033, 0.0055],
'Terra Eutro': [0.053, 0.0002, 0.0077, 0.0001, 0.0547, 0.00019, 0.0058, 0.0002]
})
Farm_Quant = pd.DataFrame({
'Amount': [0.388, 0.4129, 0.1945],
'GHG': [8.029, 20.61, 44.32],
'Acid': [0.009, 0.019, 0.044],
'Terra Eutro': [0.039, 0.077, 0.0177]},
index = ['q1', 'q2', 'q3']
)
# melt the MedComb df from wide to long
med_comb_long = pd.melt(MedComb,id_vars=['Name','Type'],
var_name='midpoint',value_name='value')
# Basically transpose the Farm_Quant df in two steps to join with med_comb_long
# convert the Farm_Quant df from wide to long and make the quarters a column
midpoint_long = pd.melt(Farm_Quant.reset_index().drop(columns=['Amount']),
id_vars=['index'],var_name='midpoint',value_name='error_bar')
# make long farm quant df wide again, but with the quarters as the columns and facet names as index
midpoint_reshape = pd.pivot(midpoint_long,index='midpoint',columns='index',
values='error_bar')
# Join the data for the bar charts and error bars/points into single df
plot_data = med_comb_long.join(midpoint_reshape,on='midpoint')
# make the plot
q2 = (ggplot(plot_data)
+ geom_col(aes('Name','value',fill='Type'))
+ scale_fill_brewer(type='div', palette=2)
+ facet_wrap('midpoint',scales='free')
+ geom_errorbar(aes(x=1,ymin='q1',ymax='q3'))
+ geom_point(aes(x=1,y='q2'))
+ theme_matplotlib()
# + theme(figure_size=(2.2, 4), legend_position = (1.25, 0.5),
# axis_title_x =element_blank(),
# axis_ticks_major_x=element_blank())
+ scale_y_continuous(name=Midpoint[MPID][1])
+ labs(title = Midpoint[MPID][0])
)
q2