在MatPlotLib中添加下拉列表和文本框,并根据inpu显示绘图

2024-03-29 00:36:30 发布

您现在位置:Python中文网/ 问答频道 /正文

我想在matplotlib条形图中添加下拉列表和2个文本框,以便根据下拉列表和文本框输入显示数据。 数据帧如下:

Year        Sex    Area    Count
2015         W      Dhaka    6
2015         M      Dhaka    3
2015         W      Khulna   1
2015         M      Khulna   8
2014         M      Dhaka    13
2014         W      Dhaka    20
2014         M      Khulna   9
2014         W      Khulna   6
2013         W      Dhaka    11
2013         M      Dhaka    2
2013         W      Khulna    8
2013         M      Khulna    5
2012         M      Dhaka    12
2012         W      Dhaka    4
2012         W      Khulna    7
2012         M      Khulna    1

在下拉列表中,将有一个区域,用户可以选择一个区域。在这两个文本框中,用户将输入2年(如2013年和2015年)

在条形图中,在文本框中输入的年之间,将显示下拉列表中所选区域的出生总数 就像这张图: enter image description here

我编写了一个具有固定年数和面积的代码,如下所示:

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

df = pd.read_csv('stats.csv', delimiter=',', encoding="utf-8-sig")
df=df.loc[df['"Year"']<=2015]
df=df.loc[df['"Year"']>=2011]
df=df.loc[df['Area']=="Rathaus"]
agg_df = df.groupby(['"Year"','Sex']).sum()

agg_df.reset_index(inplace=True)

piv_df = agg_df.pivot(index='"Year"', columns='Sex', values='Count')
fig = plt.figure(1)
ax1 = fig.add_subplot(211)

piv_df.plot.bar(stacked=True,ax=ax1)

plt.show()

现在,我想添加如下输入: enter image description here

如何使用matplotlib中的一个下拉列表和两个文本框从用户输入来实现相同类型的图形?有什么好办法吗?


Tags: 用户import区域df列表matplotlibasplt
1条回答
网友
1楼 · 发布于 2024-03-29 00:36:30

我不确定你是否可以使用Jupyter笔记本来为你的图形添加交互性,但这里有一个解决方案,我想出的,将做你想要的。

导入语句

import pandas as pd
import numpy as np
import matplotlib as mpl # optional (here)
import matplotlib.pyplot as plt
import seaborn as sns # Optional, will only affect the color of bars and the grid

from ipywidgets import widgets, interactive

加载样本数据

from io import StringIO

testdata=StringIO("""Year,Sex,Area,Count
2015,W,Dhaka,6
2015,M,Dhaka,3
2015,W,Khulna,1
2015,M,Khulna,8
2014,M,Dhaka,13
2014,W,Dhaka,20
2014,M,Khulna,9
2014,W,Khulna,6
2013,W,Dhaka,11
2013,M,Dhaka,2
2013,W,Khulna,8
2013,M,Khulna,5
2012,M,Dhaka,12
2012,W,Dhaka,4
2012,W,Khulna,7
2012,M,Khulna,1
    """)

df = pd.read_csv(testdata, sep=",")

从现在开始,df被初始化

准备交互式绘图

# Create two bounded text box that allow only numbers between the min year (2012) and the max year (2015)
start_year = widgets.BoundedFloatText(
    value=df.Year.min(),
    min=df.Year.min(),
    max=df.Year.max(),
    step=1,
    description='Start Year:',
    disabled=False,
    color='black'
)
end_year = widgets.BoundedFloatText(
    value=df.Year.max(),
    min=df.Year.min(),
    max=df.Year.max(),
    step=1,
    description='End Year:',
    disabled=False,
    color='black'
)

# Make a dropdown to select the Area, or "All"
area = widgets.Dropdown(
    options=['All'] + list(df['Area'].unique()),
    value='All',
    description='Area:',
)

def plotit(area, start_year, end_year):
    """
    Filters and plot the dataframe as a stacked bar chart of count of Male versus Women

    Args:
    -----
        * area (str): the area to filter on, or "All" to display all Areas

        * start_year, end_year (int, as float): the start and ends years, inclusive

        Note: the dataframe to plot is globally defined here as `df`

    Returns:
    --------
        A matplotlib stacked bar chart

    """
    if start_year > end_year:
        print("You must select a start year that is prior to end year")
    else:
        df2 = df.copy()
        if area != 'All':
            df2 = df2[df2.Area == area]

        # Filter between min and max years (inclusive)
        df2 = df2[(df2.Year >= start_year) & (df2.Year <= end_year)]


        # Plot it (only if there's data to plot)
        if len(df2) > 0:
            df2.groupby(['Year', 'Sex']).sum()['Count'].unstack().plot(kind='bar', stacked=True, title="Area = {}".format(area))
            plt.show();
        else:
            print("No data to show for current selection")

实际调用交互图

interactive(plotit, area=area, start_year=start_year, end_year=end_year)

Resulting graph

相关问题 更多 >