【Python】数据分析 Section 2.2.6: Widget Demonstration | from Coursera “Applied Data Science with Python“

This lecture is a bit different, it's an extended topic that looks at the interactive functionality which is available within Jupyter. Jupyter has a notion of widgets, which allow you to build simple dashboards within notebooks to aid in your investigation. You can read more about the Jupyter widgets here, and please keep in mind that while everything I'm showing should work fine in your coursera system, it's quite likely that this fast moving world is already a bit out of date with the very latest!: Jupyter Widgets — Jupyter Widgets 8.1.2 documentation

# We'll be using the interact function which comes as a decorator in python.
from ipywidgets import interact
import ipywidgets as widgets

# Now, we're going to look at a small dataset which I collected of my biking data
import pandas as pd
import matplotlib.pyplot as plt

# The dataset is actually pretty important to me, because while I was biking in 2019
# I went into a roundabout - a traffic circle - a little too fast and completely wiped
# out. This makes it a great thing to visualize!
df=pd.read_csv("../assets/wipeout.csv")
df=df.set_index(pd.to_datetime(df["timestamp"]))
df.head()

The dataset is made up of time and a set of sensors I was wearing while I was riding. These sensors picked up details such as my position and elevation, my speed, my heart rate, and more. I assume everyone goes for a bike ride like this.

# Pandas has some build in support for plotting, but needs to be able to "talk" matplotlib.
# We do this by indicating that we want our pandas plots to convert automatically for us
from pandas.plotting import register_matplotlib_converters
register_matplotlib_converters()

# Not all of the columns in my dataframe are good to visualize in a line plot. So I'm going
# to iterate through my dataframe and just keep a list of the columns which are not of type
# object (e.g. the column is a number)
potential_columns=[]
for col in df.columns:
    if df[col].dtype != "object":
        potential_columns.append(col)

# Ok, now I want to write a plot wrapper function. This function is going to plot
# one or two columns, never more. If there is a single column passed in it will
# plot that in blue (default color), but if there are two it's going to plot the
# one column of data on top of the other, with the second column being in red. We're
# going to use the plt.twinx() function here to ensure the x axis is the same (it's
# going to be time, the dataframe index), but that the y axis can be unique for each
# series of data.
def plot_data(col_names):
    plt.figure(figsize=[12,8])
    plt.gcf().suptitle(str(col_names))
    if len(col_names) ==2:
        plt.plot(df[list(col_names)[0]],'b')
        ax=plt.twinx()
        ax.plot(df[list(col_names)[1]],'r')
    else:
        plt.plot(df[list(col_names)])

# Now let's just look at one example of two columns of data, say cadence versus
# speed
plot_data(["cadence","enhanced_speed"])

Ok, it's pretty messy, but we can see that there is one moment around time 21:05 where cadence and speed did drop together. But let's get to the interactive part.

# To make this interactive we can "wrap" this function with the @interact() decorator.
# A decorator in python is just a function which wraps another function, and the ipython
# team has written this one for us, it allows us to provide a new SelectMultiple widget
# and use whatever is selected there as a parameter to plot_data. We set this up by
# putting the decorator in front of the plot_data function definition, so I'm going to do
# a little copy and paste here.

# The SelectMultiple widget has three parameters, the set of options which are legal
# (so this will be our potential column names) the values we want passed in (and time
# will always be our first value we want passed in, followed by whatever other values
# are selected), and some descriptive string.
@interact(col_names=widgets.SelectMultiple(
    options=potential_columns,
    value=(potential_columns[0],),
    description='Columns'))
def plot_data(col_names):
    plt.figure(figsize=[12,8])
    plt.gcf().suptitle(str(col_names))
    if len(col_names) ==2:
        plt.plot(df[list(col_names)[0]],'b')
        ax=plt.twinx()
        ax.plot(df[list(col_names)[1]],'r')
    else:
        plt.plot(df[list(col_names)])

Nice! Now we can explore and look at any two columns we might want. Of course, SPLOMs do give us some of this with small multiples, so you shouldn't discount that. But sometimes a dashboard can engage your reader in a different way, and let them see a slightly larger view of the data.

# Lets look at one more example. Here I'm going to use a widget called an IntRangeSlider
# which allows the reader to set a lower and upper bounds for something. I've written a
# lot here and you can check the docs for more, but in this case I'm going to look at a
# plot of my heart rate, where the reader gets to see all places between 80 and 100 but
# can change this to filter based on values they are interested in. I'm also going to
# create a text widget that allows them to set the start and end time, so you can zoom
# in on a time of interest.
@interact(heart_rate_bounds=widgets.IntRangeSlider(
    value=[80, 100],
    min=0,
    max=180,
    step=1,
    description='HR Range:',
    continuous_update=False,
    readout_format='d',),
    start=widgets.Text(
    value=str(df.index[0]),
    description='Start Time:'),
    end=widgets.Text(
    value=str(df.index[-1]),
    description='End Time:'))

def plot_hr(heart_rate_bounds, start, end):
    plt.figure(figsize=[12,8])
    
    plt.xlim(left=df.index[0],right=df.index[-1])
    plt.ylim(0,max(df["heart_rate"]))
    
    ndf=df[(df["heart_rate"]>heart_rate_bounds[0]) & 
           (df["heart_rate"]<heart_rate_bounds[1]) & 
           (df.index>start) & (df.index<end)]
    plt.scatter(ndf.index,ndf["heart_rate"])

Ok, that was a pretty whirwind demo of Juptyer widgets. The ecosystem for widgets is far from finished, but functionality is being added all of the time. I wanted to include this here because it's starting to get a bit more mature, and honestly, it's visuals like plots and charts that people want to use these widgets for. I hope you'll take a look and poke around with what is available, and maybe share your findings and creations with myself and the other students in the class. 

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值