如何在Pyviz Panel应用程序中成功生成马赛克图?

时间:2019-12-19 16:20:40

标签: python-3.x pandas pyviz mosaic-plot panel-pyviz

我创建了以下数据框df

设置:

import pandas as pd
import numpy as np
import random
import copy
import feather
import matplotlib.pyplot as plt
from statsmodels.graphics.mosaicplot import mosaic
import plotly.graph_objects as go
import plotly.express as px
import panel as pn
import holoviews as hv
import geoviews as gv
import geoviews.feature as gf
import cartopy
import cartopy.feature as cf
from geoviews import opts
from cartopy import crs as ccrs
import hvplot.pandas
import colorcet as cc
from colorcet.plotting import swatch
#pn.extension() # commented out as this causes an intermittent javascript error
gv.extension("bokeh")
cols = {"name":["Jim","Alice","Bob","Julia","Fern","Bill","Jordan","Pip","Shelly","Mimi"], 
         "age":[19,26,37,45,56,71,20,36,37,55], 
         "sex":["Male","Female","Male","Female","Female","Male","Male","Male","Female","Female"],
         "age_band":["18-24","25-34","35-44","45-54","55-64","65-74","18-24","35-44","35-44","55-64"],
         "insurance_renew_month":[1,2,3,3,3,4,5,5,6,7],
         "postcode_prefix":["EH","M","G","EH","EH","M","G","EH","M","EH"],
         "postcode_order":[3,2,1,3,3,2,1,3,2,3],
         "local_authority_district":["S12000036","E08000003","S12000049","S12000036","S12000036","E08000003","S12000036","E08000003","S12000049","S12000036"],
         "blah1":[3,None,None,8,8,None,1,None,None,None],
         "blah2":[None,None,None,33,5,None,66,3,22,3],
         "blah3":["A",None,"A",None,"C",None,None,None,None,None],
         "blah4":[None,None,None,None,None,None,None,None,None,1]}
df = pd.DataFrame.from_dict(cols)
df
Out[2]: 
     name  age     sex age_band  ...  blah1 blah2  blah3 blah4
0     Jim   19    Male    18-24  ...    3.0   NaN      A   NaN
1   Alice   26  Female    25-34  ...    NaN   NaN   None   NaN
2     Bob   37    Male    35-44  ...    NaN   NaN      A   NaN
3   Julia   45  Female    45-54  ...    8.0  33.0   None   NaN
4    Fern   56  Female    55-64  ...    8.0   5.0      C   NaN
5    Bill   71    Male    65-74  ...    NaN   NaN   None   NaN
6  Jordan   20    Male    18-24  ...    1.0  66.0   None   NaN
7     Pip   36    Male    35-44  ...    NaN   3.0   None   NaN
8  Shelly   37  Female    35-44  ...    NaN  22.0   None   NaN
9    Mimi   55  Female    55-64  ...    NaN   3.0   None   1.0

[10 rows x 12 columns]
df[["sex","age_band","postcode_prefix"]] = df[["sex","age_band","postcode_prefix"]].astype("category")
df.info()
<class 'pandas.core.frame.DataFrame'>
RangeIndex: 10 entries, 0 to 9
Data columns (total 12 columns):
name                        10 non-null object
age                         10 non-null int64
sex                         10 non-null category
age_band                    10 non-null category
insurance_renew_month       10 non-null int64
postcode_prefix             10 non-null category
postcode_order              10 non-null int64
local_authority_district    10 non-null object
blah1                       4 non-null float64
blah2                       6 non-null float64
blah3                       3 non-null object
blah4                       1 non-null float64
dtypes: category(3), float64(3), int64(3), object(3)
memory usage: 1.3+ KB

问题:

我可以使用以下代码成功创建镶嵌图:

fig,ax = plt.subplots(figsize=(15,10))
mosaic(df,["sex", "age_band"],ax=ax);

enter image description here

但是,当我尝试使用pn.interact创建相应的应用程序时遇到了问题:

categoric_cols = df.select_dtypes(include="category")
cat_atts = categoric_cols.columns.tolist()
cat_atts
Out[4]: ['sex', 'age_band', 'postcode_prefix']
def bivar_cat(x="sex",y="age_band"):
    if x in cat_atts and y in cat_atts:
        fig,ax = plt.subplots(figsize=(15,10))
        return mosaic(df,[x,y],ax=ax);

app_df_cat = pn.interact(bivar_cat,x=cat_atts,y=cat_atts)
app_df_cat

结果如下:

enter image description here

上面绘制的镶嵌图似乎对应于x和y的默认值(即sexage_band)。当从下拉列表中为x或y选择新属性时,镶嵌图上方的文本会更改(此文本似乎是该图的字符串表示形式),但是镶嵌图本身不会。

我的问题是否可能与必须注释掉pn.extension()有关?我发现当未注释掉pn.extension()时,它会导致间歇性javascript错误,从而有时不会引发错误,有时会出现错误,但是我的面板应用仍然加载并且有时会出现错误并且崩溃我的浏览器。 (我在这里省略了j​​avascript错误,因为它可能非常大-如果有帮助,可以将其添加到我的帖子中。)我想说的是,错误发生的频率比没有错误的发生频率高。

奇怪的是,我没有观察到我创建的其他应用程序的任何区别,在这些应用程序中我省略了pn.extension()与包含它。 但是,由于文档始终指定要包括它,因此我希望我必须为所有绘图设置适当的扩展名才能正常工作? (我已经成功地在其他带有或不带有pn.extension()和pn.extension(“ plotly”)的其他应用程序中绘制了hvplot,holoviews和geoviews地块。)

是否可以基于镶嵌图制作面板应用程序?

谢谢


软件信息:

os x                      Catalina 
browser                   Firefox
python                    3.7.5
notebook                  6.0.2 
pandas                    0.25.3
panel                     0.7.0
plotly                    4.3.0 
plotly_express            0.4.1 
holoviews                 1.12.6
geoviews                  1.6.5 
hvplot                    0.5.2 

1 个答案:

答案 0 :(得分:1)

Statsmodels函数mosaic()返回带有图形的元组并进行调整。

您现在通过交互看到的是该元组。使用下拉菜单时,该元组也会在您的代码中更新。

您在下面看到的图是jupyter自动绘制一次的图。这个没有更新。

解决方案有两个:
1)只返回数字,而不返回元组
2)使用plt.close()

防止jupyter自动绘制图形

在代码中:

def bivar_cat(x='sex', y='age_band'):
    fig, ax = plt.subplots(figsize=(15,10))
    mosaic(df, [x,y], ax=ax)
    plt.close()
    return fig

app_df_cat = pn.interact(
    bivar_cat, 
    x=cat_atts, 
    y=cat_atts,
)

app_df_cat