text_plain_output_1.png
from circlify import circlify, Circle

from warnings import filterwarnings

import matplotlib.lines as lines

import matplotlib.pyplot as plt

import numpy as np

import pandas as pd

import seaborn as sns

import numpy as np
import pandas as pd
import matplotlib.pyplot as plt
import matplotlib.lines as lines
import matplotlib.gridspec as gridspec
import seaborn as sns
from warnings import filterwarnings
filterwarnings('ignore')
plt.rcParams['font.family'] = 'monospace'

df = pd.read_csv('../input/predict-test-scores-of-students/test_scores.csv')

cmap0 = ['#68595b', '#7098af', '#6f636c', '#907c7b']
cmap1 = ['#484146', '#8da0b3', '#796d72', '#9fa9ba']
cmap2 = ['#545457', '#a79698', '#5284a2', '#bbbcc4']
bg_color = '#fbfbfb'
txt_color = '#5c5c5c'

# check for missing values
fig, ax = plt.subplots(tight_layout=True, figsize=(12,6))

fig.patch.set_facecolor(bg_color)
ax.set_facecolor(bg_color)

mv = df.isna()
ax = sns.heatmap(data=mv, cmap=sns.color_palette(cmap0), cbar=False, ax=ax, )

ax.set_ylabel('')
ax.set_yticks([])
ax.set_xticklabels(labels=mv.columns,rotation=45)
ax.tick_params(length=0)

fig.text(
    s=':Missing Values',
    x=0, y=1.1,
    fontsize=17, fontweight='bold',
    color=txt_color,
    va='top', ha='left'
)

fig.text(
    s='''
    we can't see any ...
    ''',
    x=0, y=1.075,
    fontsize=11, fontstyle='italic',
    color=txt_color,
    va='top', ha='left'
)

plt.show()

def despine_ax(ax, spines=['top', 'left', 'right', 'bottom']):
    for spine in spines:
        ax.spines[spine].set_visible(False)
def get_line(x=[0, 0], y=[0, 0], alpha=0.5, lw=1):
    return lines.Line2D(xdata=x, ydata=y, lw=lw, alpha=alpha, color='#aeaeae', transform=fig.transFigure, figure=fig)

fig, (ax0, ax1) = plt.subplots(2, 1, tight_layout=True, sharex=True, figsize=(12,6))
fig.patch.set_facecolor(bg_color)

mean = df['posttest'].mean()
median = df['posttest'].median()

ax0.boxplot(
    data=df, x='posttest',
    vert=False, patch_artist=True,
    boxprops=dict(facecolor=cmap0[1], lw=0, alpha=0.75),
    whiskerprops=dict(color='gray', lw=1, ls='--'),
    capprops=dict(color='gray', lw=1, ls='--'),
    medianprops=dict(color='#fff', lw=0),
    flierprops=dict(markerfacecolor=cmap0[0],alpha=0.75),
    zorder=0
)

ax1 = sns.kdeplot(
    data=df, x='posttest', shade=True, 
    color=cmap0[0], edgecolor='#000', lw=1, 
    zorder=0, alpha=0.8, ax=ax1
)

ax0.axvline(x=mean, ymin=0.4, ymax=0.6, color=bg_color, ls=':', zorder=1, label='mean')
ax1.axvline(x=mean, ymin=0, ymax=0.9, color=bg_color, ls=':', zorder=1)

ax0.axvline(x=median, ymin=0.4, ymax=0.6, color=bg_color, ls='--', zorder=1)
ax1.axvline(x=median, ymin=0, ymax=0.9, color=bg_color, ls='--', zorder=1)

ax0.axis('off')
ax0.set_facecolor(bg_color)

ax1.set_ylabel('')
ax1.set_xlabel('')
ax1.set_yticks([])
ax1.tick_params(length=0)
ax1.set_facecolor(bg_color)

despine_ax(ax1, ['top','left','right'])

fig.text(
    s=':Posttest - Distribution',
    x=0, y=1.05,
    fontsize=17, fontweight='bold',
    color=txt_color, 
    va='top', ha='left'
)

fig.text(
    s='''
    in the plot below we can see signs
    of a binominal distribution, with 
    one peak at around 57-62 and the other 
    at approx. 72-79 points.
    ''',
    x=0, y=1.02,
    fontsize=11, fontstyle='italic',
    color=txt_color,
    va='top', ha='left'
)

fig.text(
    s=f"Mean: {np.round(mean,1)}\nMedian: {np.round(median,1)}",
    x=0.56, y=0.925,
    fontsize=9, fontstyle='italic',
    color=txt_color,
    va='top', ha='left'
)

l1 = get_line(x=[0.55,0.55], y=[0.85,0.95])
fig.lines.extend([l1])

plt.show()

fig, ax = plt.subplots(tight_layout=True, figsize=(12,2.5))
fig.patch.set_facecolor(bg_color)

uniq_scores = df['posttest'].nunique()

ax.barh(
    y=1, width=uniq_scores, 
    color=cmap0[1], alpha=0.75,lw=1, edgecolor='white'
)
ax.barh(
    y=1, width=100-uniq_scores, left=uniq_scores,
    color=cmap1[1], alpha=0.25, lw=1, edgecolor='white'
)

ax.axis('off')

ax.annotate(
    s=f"{uniq_scores}",
    xy=(35,1.05),
    va='center', ha='center',
    fontsize=36, fontweight='bold', fontfamily='serif',
    color='#fff'
)

ax.annotate(
    s='unqiue scores',
    xy=(35,0.85),
    va='center', ha='center',
    fontsize=16, fontstyle='italic', fontfamily='serif',
    color='#fff'
)

fig.text(
    s=':Unique Number of Scores',
    x=0, y=1.25,
    fontsize=17, fontweight='bold',
    color=txt_color, 
    va='top', ha='left'
)

fig.text(
    s='''
    68 unique scores have been scored 
    from a total of 100 possible outcomes.
    ''',
    x=0, y=1.2,
    fontsize=11, fontstyle='italic',
    color=txt_color,
    va='top', ha='left'
)

l1 = get_line(x=[0.645,0.645], y=[0,1], lw=3, alpha=1)
fig.lines.extend([l1])

plt.show()

from circlify import circlify, Circle
schools_by_num_students = df.groupby('school').count()[['posttest']].reset_index().sort_values(by='posttest', ascending=False).rename(columns={'posttest': 'count'})
schools_by_num_students['ratio'] = df['school'].value_counts().values / len(df['school'])
schools_by_num_students = schools_by_num_students[:10]
fig, ax = plt.subplots(tight_layout=True, figsize=(8, 8))
fig.patch.set_facecolor(bg_color)
ax.patch.set_facecolor(bg_color)
circles = circlify(data=schools_by_num_students['count'].tolist(), show_enclosure=False, target_enclosure=Circle(x=0, y=0, r=1))
lim = max((max(abs(circle.x) + circle.r, abs(circle.y) + circle.r) for circle in circles))
ax.set_xlim(-lim, lim)
ax.set_ylim(-lim, lim)
labels = schools_by_num_students['school'][::-1]
counts = schools_by_num_students['count'][::-1]
ratios = schools_by_num_students['ratio'][::-1]
for circle, label, count, ratio in zip(circles, labels, counts, ratios):
    x, y, r = circle
    ax.add_patch(plt.Circle((x, y), r, lw=1, fill=True, alpha=1 * (ratio * 10), facecolor=cmap0[1]))
    ax.annotate(s=f'{label}', xy=(x, y), fontweight='bold', va='center', ha='center', color='#fff')
    ax.annotate(s=f'#{count} ({int(ratio * 100)}%)', xy=(x, y - 0.04), fontstyle='italic', fontsize=9, va='center', ha='center', color='#fff')
ax.axis('off')
fig.text(s=':TOP 10 - Schools', x=0, y=1, fontsize=17, fontweight='bold', color=txt_color, va='top', ha='left')
fig.text(s='\n    by number of students\n    ', x=0, y=0.985, fontsize=11, fontstyle='italic', color=txt_color, va='top', ha='left')
fig.text(s=f"{df['school'].nunique()}", x=1.04, y=0.8, fontsize=52, fontfamily='serif', color=txt_color, va='top', ha='left')
fig.text(s='\n    unique \n    schools', x=1.13, y=0.82, fontsize=11, fontfamily='serif', color=txt_color, va='top', ha='left')
fig.text(s='\n    The students are nearly \n    equally distributed\n    among the total of 23 \n    different schools\n    ', x=1, y=0.65, fontsize=11, fontstyle='italic', color=txt_color, va='top', ha='left')
l1 = get_line(x=[1, 1], y=[0.45, 0.8])
fig.lines.extend([l1])
plt.show()