<SYSTEM_TASK:>
Given the following text description, write Python code to implement the functionality described below step by step
<END_TASK>
<USER_TASK:>
Description:
 For External users
You can open this notebook in Google Colab.
Installation
You can install from pip for the stable version
Step1:  or from GitHub for the latest version.
Step2:  Demo Starts
<ASSISTANT_TASK:>
Python Code:
!pip install meterstick
Explanation: For External users
You can open this notebook in Google Colab.
Installation
You can install from pip for the stable version
End of explanation
!git clone https://github.com/google/meterstick.git
import sys, os
sys.path.append(os.getcwd())
Explanation: or from GitHub for the latest version.
End of explanation
import itertools
import numpy as np
import pandas as pd
from meterstick import confidence_interval_display
np.random.seed(42)
metrics = ('Click', 'Latency', 'a very very very looooooooooong metric')
ctrl_id = 42
platform = ('Mobile', 'Desktop', 'Tablet')
ctrl_vals = [137, 28, 999.9, 158, 40, 6.66666, -10, -20.1, 33]
expr_ids = (42, 222, 666, 'Experiment Foo')
n_row = len(metrics) * len(platform) * len(expr_ids)
test_df = pd.DataFrame(
    itertools.product(expr_ids, platform, metrics),
    columns=[
        'Experiment_Id',
        'Platform',
        'Metric',
    ])
test_df['Control_Value'] = ctrl_vals * (n_row // len(ctrl_vals))
test_df['Ratio'] = 2 * (np.random.rand(n_row) - 0.5)
test_df['CI_Range'] = 2 * np.random.rand(n_row)
test_df['Value'] = test_df.Control_Value * (test_df.Ratio / 100 + 1)
test_df['Country'] = 'US'
ctrl_id = 42
test_df.loc[test_df.Experiment_Id == ctrl_id,
            'Value'] = test_df.loc[test_df.Experiment_Id == ctrl_id,
                                   'Control_Value']
confidence_interval_display.render(test_df, dims=['Country', 'Platform'])
# You can manually specify the columns.
test_df_copy = test_df.copy()
test_df_copy.rename(
    columns={
        'Experiment_Id': 'expr',
        'Metric': 'metric',
        'Control_Value': 'control',
        'Ratio': 'ratio',
        'CI_Range': 'ci',
        'Value': 'val'
    },
    inplace=True)
confidence_interval_display.render(
    test_df_copy,
    dims=['Country', 'Platform'],
    metric='metric',
    ratio='ratio',
    value='val',
    ci_range='ci',
    control_value='control',
    expr_id='expr')
test_df_copy = test_df.copy()
test_df_copy['Control_Id'] = None
confidence_interval_display.render(test_df_copy, dims=['Country', 'Platform'])
# If you don't want to aggregate your dimensions...
confidence_interval_display.render(
    test_df,
    dims=['Country', 'Platform'],
    aggregate_dimensions=False)
# By default we look for Dim_1, Dim2, ... as dimension columns.
test_df.rename(columns={'Country': 'Dim_1', 'Platform': 'Dim_2'}, inplace=True)
confidence_interval_display.render(test_df)
# You can set control experiment. We'll only display its Value.
confidence_interval_display.render(test_df, ctrl_id=ctrl_id)
# Hide the controls if it doesn't matter to you.
confidence_interval_display.render(test_df, ctrl_id=ctrl_id, show_control=False)
# You can also have multiple controls.
confidence_interval_display.render(
    test_df,
    ctrl_id={
        42: [222],
        666: ['Experiment Foo']
    })
# Auto determines control values if control rows are missing. Your control rows
# are supposed to have the same values in the Control_Value and Value columns.
# If not, we skip. To demonstrate, here we introduce inconsistency in 'Click'.
df = test_df.loc[test_df.Experiment_Id != 42].copy()
df.loc[(df.Experiment_Id == 222) & (df.Metric == 'Click'), 'Control_Value'] = -1
confidence_interval_display.render(
    df,
    ctrl_id=42,
    auto_decide_control_vals=True)
# You can flip the coloring scheme for some metrics.
confidence_interval_display.render(test_df, flip_color=['Latency'])
# You can add descriptions for your experiments.
test_df['Description'] = ''
test_df.loc[test_df['Experiment_Id'] == 42, 'Description'] = 'The Answer'
# You can even use raw html.
test_df.loc[test_df['Experiment_Id'] == 666,
            'Description'] = '<b>Bold</b>'
confidence_interval_display.render(test_df)
# You can customize the formatting of values. By default there are 'percent',
# 'absolute' and 'pp'. You can also provide your own formating string template.
confidence_interval_display.render(
    test_df,
    metric_formats={
        'Ratio': 'pp',
        'Value': 'percent'
    })
# You don't need Value if you don't want to show_control.
test_df2 = test_df.copy()
del test_df2['Value']
confidence_interval_display.render(test_df2, show_control=False)
# You can hide the null control values.
confidence_interval_display.render(
    test_df2, show_control=False, hide_null_ctrl=True)
# You can order and slice the metrics.
confidence_interval_display.render(test_df, metric_order=['Latency', 'Click'])
# You can customize the order of dimension slices.
confidence_interval_display.render(
    test_df,
    sort_by=[{
        'column': 'Dim_2',
        'order': ['Mobile', 'Desktop', 'Tablet']
    }])
# You can sort by values of a metric. The supported value columns are 'Value',
# 'Ratio', 'CI_Lower', 'CI_Upper'. See the doc of get_formatted_df() also.
confidence_interval_display.render(
    test_df,
    sort_by=[{
        'column': ('Ratio', 'Click'),
        'ascending': False
    }])
# Of course you can sort both by dimesnion and by values.
confidence_interval_display.render(
    test_df,
    sort_by=[{
        'column': 'Dim_2',
        'order': ['Mobile', 'Desktop', 'Tablet']
    }, {
        'column': ('CI_Lower', 'Click'),
    }])
pre_agg_df = confidence_interval_display.render(
    test_df, return_pre_agg_df=True)
mask = pre_agg_df.applymap(lambda c: bool(
    isinstance(c, list) and c[-1] and c[-2] and c[-1] - c[-2] < 1))
formatted_df = confidence_interval_display.render(
    test_df, return_formatted_df=True)
formatted_df.mask(
    mask,
    formatted_df.applymap('<div class="tight-ci">{}</div>'.format),
    inplace=True)
extra_css = '.tight-ci {border-color: purple; border-style: dotted;}'
confidence_interval_display.display_formatted_df(formatted_df, extra_css)
# Test for no dimensions.
df_no_dim = test_df.groupby(['Experiment_Id', 'Metric']).mean().reset_index()
confidence_interval_display.render(df_no_dim, ctrl_id=42)
Explanation: Demo Starts
End of explanation
<END_TASK>