The basic example shows how to plot the shaping to average quality level plot from the IFIP Networking 2016 publication.
Remove warnings and show plots inline:
In [1]:
import warnings
warnings.filterwarnings("ignore")
%matplotlib inline
Import the required modules:
In [2]:
import numpy as np
import pandas as pd
import matplotlib.pylab as plt
import scipy.stats
Read the dataset:
In [3]:
data = pd.read_csv("../data/ifip_networking.csv.gz")
Convert the shaping to Mbps:
In [4]:
data.loc[:,'shaping_mbps'] = data.loc[:,'net_avg_shaping_rate']*8/1000/1000
data.loc[:,'shaping_mbps_rounded'] = data.loc[:,'shaping_mbps'].round(1)
Dict for translating itags to quality levels and vice-versa:
In [5]:
ITAG_TO_QL = {160: 0,
133: 1,
134: 2,
135: 3,
136: 4}
QL_TO_ITAG = {v: k for k, v in ITAG_TO_QL.items()}
VIDDEF = {160: {'label': '144p', 'color': 'green', 'resolution': '256x144'},
133: {'label': '240p', 'color': 'red' , 'resolution': '320x240'},
134: {'label': '360p', 'color': 'blue' , 'resolution': '480x360'},
135: {'label': '480p', 'color': 'grey' , 'resolution': '640x480'},
136: {'label': '720p', 'color': 'cyan' , 'resolution': '1280x720'}}
Confidence Interval:
In [6]:
def confintv_yerr(values):
n, min_max, mean, var, skew, kurt = scipy.stats.describe(values)
std = np.sqrt(var)
intv = scipy.stats.t.interval(0.95,len(values)-1,loc=mean,scale=std/np.sqrt(len(values)))
yerr = ((intv[1] - intv[0]) / 2)
return yerr
The subsequent plot shows the fraction of time the video spent on the a certain quality level and the overall average quality level for a specific network shaping value. For example, at 2.2 Mbps, the player spends nearly 100% of the time on the highest quality level (480p).
In [7]:
fig = plt.figure(figsize=(9, 7))
plt.hold(True)
ax1 = fig.add_subplot(111)
by_shaping = data.groupby('shaping_mbps').mean()
y_offset = 0
cmap = plt.get_cmap('copper')
colors = iter(cmap(np.linspace(0,1,len(QL_TO_ITAG))))
for ql,itag in list(QL_TO_ITAG.items())[0:4]:
idx_itag = 'pl_time_spent_norm_itag%d' % itag
ax1.fill_between(by_shaping.index,
y_offset,
by_shaping[idx_itag],
alpha=0.35,
facecolor=next(colors))
y_offset = by_shaping[idx_itag]
plt.annotate(s=VIDDEF[QL_TO_ITAG[0]]['label'], xy=(0.46, 0.014))
plt.annotate(s=VIDDEF[QL_TO_ITAG[1]]['label'], xy=(0.65, 0.42))
plt.annotate(s=VIDDEF[QL_TO_ITAG[2]]['label'], xy=(1.05, 0.42))
plt.annotate(s=VIDDEF[QL_TO_ITAG[3]]['label'], xy=(1.6, 0.42))
plt.ylabel(r"Relative Playback Time $T_{fq}$")
plt.xlabel(r"Bandwidth $f$ (Mbps)")
ax2 = ax1.twinx()
ax2_data = pd.DataFrame(columns=['shaping', 'avg_ql', 'yerr'])
for shaping,group in data.groupby('shaping_mbps'):
ql_median = group['pl_avg_pl_quality_ql'].mean()
ql_yerr = confintv_yerr(group['pl_avg_pl_quality_ql'])
ax2_data = ax2_data.append(pd.DataFrame([[shaping, ql_median, ql_yerr]], columns=ax2_data.columns))
ax2_data.reset_index(drop=True)
ax2.errorbar(ax2_data['shaping'], ax2_data['avg_ql'], yerr=list(ax2_data['yerr']), color='black')
plt.ylabel(r"Average Quality $J_f$")
max_mbps = 2.2
tl = [""]*int(2.2/0.1)
tl[1] = "0.5"
tl[6] = "1.0"
tl[11] = "1.5"
tl[16] = "2.0"
plt.xticks(np.arange(by_shaping.index.min(), max_mbps, 0.1), tl)
plt.xlim([by_shaping.index.min(), max_mbps])
_ = plt.ylim([0, 3])
Export notebook to HTML:
In [8]:
!ipython nbconvert avg_quality.ipynb --to html