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

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/40467672/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-09-14 02:23:05  来源:igfitidea点击:

add dropdown list and text box in MatPlotLib and show plot according to the input

pythonpandasmatplotlib

提问by Sabid Habib

I want to add dropdown list and 2 text boxes to a matplotlib barchart to show data according to dropdown and text box inputs. the dataframe is as follows:

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

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

In the dropdown list,there will be AREA,user can select one AREA. And in the two text boxes,user will input 2 YEARS(eg. 2013 & 2015)

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

In the barchart,total number of birth will be shown for that selected area from drop down listin between the years input in the textboxesjust like this graph: enter image description here

在条形图中,将在文本框中输入年份之间的下拉列表中显示该选定区域的出生总数,如下 图所示: 在此处输入图片说明

I have written a code with constant years and areawhich is as follows:

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

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()

Now,I want to add the inputs like this: enter image description here

现在,我想添加这样的输入: 在此处输入图片说明

How can I achieve the same type of graph with a Drop down list and 2 text boxesinput from user in matplotlib? Is there any decent way for this?

如何使用下拉列表和用户在 matplotlib 中输入的2 个文本框获得相同类型的图形?有没有什么体面的方法呢?

回答by Julien Marrec

I'm not sure you're ok using a Jupyter Notebook to add interactivity to your graph, but here's a solution I came up with that will do what you want.

我不确定您是否可以使用 Jupyter Notebook 为图形添加交互性,但这是我想出的解决方案,可以满足您的需求。

Import Statements

进口报表

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

Load the sample data

加载样本数据

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=",")

From now on, df is initialized

从现在开始, df 被初始化

Prepare the interactive plot

准备交互式绘图

# 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")

Actually call the interactive plot

实际调用交互式绘图

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

Resulting graph

结果图