widget 2: a regra da alavanca

#HIDDEN
import matplotlib.pyplot as plt
import numpy as np
import matplotlib as mpl
import pickle
import ipywidgets as widgets

with open('phase_diagram_data.pickle', 'rb') as handle:
    data = pickle.load(handle)

Xs = data['Xs']
Ts = data['Ts']
Xs_solidus_alpha_alpha_melt = data['Xs_solidus_alpha_alpha_melt']
Ts_solidus_alpha_alpha_melt = data['Ts_solidus_alpha_alpha_melt']
Xs_solvus_alpha_alpha_beta = data['Xs_solvus_alpha_alpha_beta']
Ts_solvus_alpha_alpha_beta = data['Ts_solvus_alpha_alpha_beta']
Xs_solvus = data['Xs_solvus']
Ts_solvus = data['Ts_solvus']
Xs_solvus_alpha_beta_beta = data['Xs_solvus_alpha_beta_beta']
Ts_solvus_alpha_beta_beta = data['Ts_solvus_alpha_beta_beta']
Xs_solidus_beta_melt_beta = data['Xs_solidus_beta_melt_beta']
Ts_solidus_beta_melt_beta = data['Ts_solidus_beta_melt_beta']
Xs_liquidus = data['Xs_liquidus']
Ts_liquidus = data['Ts_liquidus']
Xs_solidus_tie_1 = data['Xs_solidus_tie_1']
Ts_solidus_tie_1 = data['Ts_solidus_tie_1']
Xs_liquidus_1 = data['Xs_liquidus_1']
Ts_liquidus_1 = data['Ts_liquidus_1']
Xs_tie_2_solidus = data['Xs_tie_2_solidus']
Ts_tie_2_solidus = data['Ts_tie_2_solidus']
Xs_liquidus_2 = data['Xs_liquidus_2']
Ts_liquidus_2 = data['Ts_liquidus_2']
X0_tie = data['X0_tie']
T0_tie = data['T0_tie']
Xf_tie = data['Xf_tie']
Tf_tie = data['Tf_tie']

W_silver = 107.8682
W_copper = 63.546
X_wt_euthetic = 71.9
Y_wt_euthetic = 100 - X_wt_euthetic
X_euthetic = X_wt_euthetic * 6.022 * 10**23 / W_silver / (X_wt_euthetic * 6.022 * 10**23 / W_silver + 
                                                          Y_wt_euthetic * 6.022 * 10**23 / W_copper)
Xs_tie = np.linspace(X0_tie, Xf_tie)
Ts_tie = np.linspace(T0_tie, Tf_tie)
Xs_tie_1 = np.linspace(X0_tie, X_euthetic * 100)
Ts_tie_1 = np.linspace(T0_tie, Tf_tie)

Xs_tie_2 = np.linspace(X_euthetic * 100, Xf_tie)
Ts_tie_2 = np.linspace(T0_tie, Tf_tie)

#HIDDEN
def get_zone(point, zones):
    for i, zone in enumerate(zones):
        if zone.get_paths()[0].contains_point(point):
            return i, zone

def html_ticks(ticks, id, ticks_pos=None):
    html_str = f'''
                <style>
                .ruler{id} {{
                 position: relative;
                 width: 100%;
                 margin-top: 20px;
                 height: 14px;
                }}
                .ruler{id} .cm{id},
                .ruler{id} .mm{id} {{
                 position: absolute;
                 border-left: 1px solid #555;
                 height: 14px;
                }}
                .ruler{id} .cm{id}:after {{
                 position: absolute;
                 bottom: -15px;
                 font: 11px/1 sans-serif;
                }}
                .ruler{id} .cm{id}:nth-of-type(1) {{
                 left: 0%;
                }}
                .ruler{id} .cm{id}:nth-of-type(1):after {{
                 content: "0";
                }}
                '''
    for i, tick in enumerate(ticks[1:]):
        if not ticks_pos:
            html_str += f'\n .ruler{id} .cm{id}:nth-of-type({i+2}) {{left: {(i+1) * 100 / (len(ticks) - 1)}%;}}'
            html_str += f'\n .ruler{id} .cm{id}:nth-of-type({i+2}):after {{content: "{ticks[i+1]}";}}'
        else:
            html_str += f'\n .ruler{id} .cm{id}:nth-of-type({i+2}) {{left: {ticks_pos[i+1]}%;}}'
            html_str += f'\n .ruler{id} .cm{id}:nth-of-type({i+2}):after {{content: "{ticks[i+1]}";}}'

    html_str += '\n</style>'

    html_str += f"\n<div class='ruler{id}'>"
    for i in range(len(ticks)):
        html_str += f"\n<div class='cm{id}'></div>"

    end_str = '</div>'
    html_str += end_str
    return html_str

#HIDDEN
def f(x, T, overlay):
    fig = plt.figure(figsize=(6, 5))

    gs = mpl.gridspec.GridSpec(3, 4, width_ratios=[1, 100, 100, 1], height_ratios=[1, 1, 1.75])
    ax1 = plt.subplot(gs[0:2, 1:3])
    ax2 = plt.subplot(gs[2:, 0:4])
    axs = [ax1, ax2]

    axs[0].plot(Xs, Ts, c='k')
    axs[0].plot(Xs_tie, Ts_tie, c='k')
    a_color = 'navy'
    b_color = 'orangered'
    L_color = 'palegreen'
    a_b_color = 'violet'

    zone_a = axs[0].fill_between(Xs_solidus_alpha_alpha_melt,
                     Ts_solidus_alpha_alpha_melt,
                     np.interp(Xs_solidus_alpha_alpha_melt, Xs_solvus_alpha_alpha_beta, Ts_solvus_alpha_alpha_beta),
                    color=a_color, alpha =1)

    zone_ab = axs[0].fill_between(Xs_solvus,
                     0,
                     Ts_solvus, color=a_b_color, alpha =1)

    zone_b = axs[0].fill_between(Xs_solvus_alpha_beta_beta,
                     Ts_solvus_alpha_beta_beta,
                     np.interp(Xs_solvus_alpha_beta_beta, Xs_solidus_beta_melt_beta, Ts_solidus_beta_melt_beta),
                    color=b_color, alpha =1)

    zone_L = axs[0].fill_between(Xs_liquidus,
                     Ts_liquidus,
                     1100, color=L_color, alpha =1)

    zone_aL = axs[0].fill_between(Xs_solidus_tie_1,
                      Ts_solidus_tie_1,
                      np.interp(Xs_solidus_tie_1, Xs_liquidus_1, Ts_liquidus_1),
                      color='teal', alpha =1)

    zone_bL = axs[0].fill_between(Xs_tie_2_solidus,
                               Ts_tie_2_solidus,
                               np.interp(Xs_tie_2_solidus, Xs_liquidus_2, Ts_liquidus_2),
                               color='goldenrod', alpha =1)

    zones = [zone_a, zone_ab, zone_b, zone_L, zone_aL, zone_bL]

    axs[0].text(1., 810, r'$\alpha$', fontsize=11, color='w')
    axs[0].text(94.2, 750, r'$\beta$', fontsize=11, color='w')
    axs[0].text(50, 425, r'$\alpha + \beta$', ha='center', fontsize=11, color='k')
    axs[0].text(20, 840, r'$\alpha + L$', ha='center', fontsize=11, color='k')
    axs[0].text(82, 800, r'$\beta + L$', ha='center', fontsize=11, color='k')
    axs[0].text(50, 925, r'Líquido ($L$)', ha='center', fontsize=11, color='k')

    axs[0].set_xlim(0, 100)
    axs[0].set_xticks(np.arange(0, 105, 20))

    xtl = axs[0].get_xticks().tolist()
    xtl[0] = '0\n(Cu)'
    xtl[-1] = '100\n(Ag)'

    axs[0].set_xticklabels(xtl)
    axs[0].set_ylim(0, 1100)
    axs[0].set_xlabel('Composição [at% Ag]',  labelpad=-5)
    axs[0].set_ylabel('Temperatura [°C]')
    # plt.grid(ls=':')
    vl = axs[0].axvline(x, c='k', zorder=14)
    hl = axs[0].axhline(T, c='k', zorder=14)
    axs[0].scatter(x, T, zorder=14, ec='k', color='y')

    ZOI_i, ZOI = get_zone((x, T+1e-6), zones)
    axs[0].plot(ZOI.get_paths()[0].vertices[:, 0],
                ZOI.get_paths()[0].vertices[:, 1],
                zorder=12, c='goldenrod')

    if ZOI_i == 0:
        b1 = axs[1].bar([x], [100], fc=a_color, label=r'$\alpha$:'+f'\n{x:4.1f}at% Ag\n{100 - x:4.1f}at% Cu', width=6, ec='k', zorder=10)
        axs[1].bar_label(b1, labels=[r'$\alpha$'], fontsize=13, label_type='center', c='w', zorder=13)
        axs[1].bar_label(b1, labels=[r'$F_\alpha$ = ' + f'{x:,.1f}%' for x in b1.datavalues], c='dodgerblue', zorder=13,
                         bbox=dict(facecolor='white', alpha=0.925, boxstyle='round,pad=0.1', edgecolor='black'))
        axs[1].legend(loc='upper left', bbox_to_anchor=(1., 1.05))

    elif ZOI_i == 1:
        idx = np.argwhere(np.diff(np.sign(zone_ab.get_paths()[0].vertices[:, 1]- T))).flatten()
        axs[0].scatter(*zone_ab.get_paths()[0].vertices[idx[0]], zorder=14, fc='w', ec='k', marker='^', label=r'$C_\alpha$')
        axs[0].scatter(*zone_ab.get_paths()[0].vertices[idx[1]], zorder=14, fc='w', ec='k', marker='v', label=r'$C_\beta$')
        axs[0].legend(title=r'$F_\alpha = \frac{C_\beta - x}{C_\beta - C_\alpha}$' +
                     '\n' + r'$F_\beta = \frac{x - C_\alpha}{C_\beta - C_\alpha}$', fontsize=12,
                      loc='upper left', bbox_to_anchor=(1., 1.05), title_fontsize=14)
        C_a = min([zone_ab.get_paths()[0].vertices[idx[0]][0], zone_ab.get_paths()[0].vertices[idx[1]][0]])
        C_b = max([zone_ab.get_paths()[0].vertices[idx[0]][0], zone_ab.get_paths()[0].vertices[idx[1]][0]])
        f_a = (C_b - x) / (C_b - C_a)
        b1 = axs[1].bar([C_a], [f_a * 100], fc=a_color, label=r'$\alpha$:'+f'\n{C_a:4.1f}at% Ag\n{100 - C_a:4.1f}at% Cu', width=6, ec='k', zorder=10)
        b2 = axs[1].bar([C_b], [(1 - f_a) * 100], fc=b_color, label=r'$\beta$:'+f'\n{C_b:4.1f}at% Ag\n{100 - C_b:4.1f}at% Cu', width=6, ec='k', zorder=10)
        axs[1].bar_label(b1, labels=[r'$\alpha$'], fontsize=13, label_type='center', c='w', zorder=13)
        axs[1].bar_label(b1, labels=[r'$F_\alpha$ = ' + f'{x:,.1f}%' for x in b1.datavalues], c='dodgerblue', zorder=13,
                         bbox=dict(facecolor='white', alpha=0.925, boxstyle='round,pad=0.1', edgecolor='black'))

        axs[1].bar_label(b2, labels=[r'$\beta$'], fontsize=13, label_type='center', c='w', zorder=13)
        axs[1].bar_label(b2, labels=[r'$F_\beta$ = ' + f'{x:,.1f}%' for x in b2.datavalues], c='dodgerblue', zorder=13,
                         bbox=dict(facecolor='white', alpha=0.925, boxstyle='round,pad=0.1', edgecolor='black'))
        axs[1].legend(loc='upper left', bbox_to_anchor=(1., 1.05))

    elif ZOI_i == 2:
        b1 = axs[1].bar([x], [100], fc=b_color, label=r'$\beta$:'+f'\n{x:4.1f}at% Ag\n{100 - x:4.1f}at% Cu', width=6, ec='k', zorder=10)
        axs[1].bar_label(b1, labels=[r'$\beta$'], fontsize=13, label_type='center', c='w', zorder=13)
        axs[1].bar_label(b1, labels=[r'$F_\beta$ = ' + f'{x:,.1f}%' for x in b1.datavalues], c='dodgerblue', zorder=13,
                        bbox=dict(facecolor='white', alpha=0.925, boxstyle='round,pad=0.1', edgecolor='black'))
        axs[1].legend(loc='upper left', bbox_to_anchor=(1., 1.05))

    elif ZOI_i == 3:
        b1 = axs[1].bar([x], [100], fc=L_color, label=r'$L$:'+f'\n{x:4.1f}at% Ag\n{100 - x:4.1f}at% Cu', width=6, ec='k', zorder=10)
        labels = [v.get_height() if v.get_height() > 0 else '' for v in b1]
        axs[1].bar_label(b1, labels=[r'$L$'], fontsize=13, label_type='center', c='k', zorder=13)
        axs[1].bar_label(b1, labels=[r'$F_L$ = ' + f'{x:,.1f}%' for x in b1.datavalues], c='dodgerblue', zorder=13,
                         bbox=dict(facecolor='white', alpha=0.85, boxstyle='round,pad=0.1', edgecolor='black'))
        axs[1].legend(loc='upper left', bbox_to_anchor=(1., 1.05))

    elif ZOI_i == 4:
        idx = np.argwhere(np.diff(np.sign(zone_aL.get_paths()[0].vertices[:, 1]- T))).flatten()
        axs[0].scatter(*zone_aL.get_paths()[0].vertices[idx[0]], zorder=14, label=r'$C_\alpha$', fc='w', ec='k', marker='^')
        axs[0].scatter(*zone_aL.get_paths()[0].vertices[idx[1]], zorder=14, label=r'$C_L$', fc='w', ec='k', marker='v')
        axs[0].legend(title=r'$F_\alpha = \frac{C_L - x}{C_L - C_\alpha}$' +
                     '\n' + r'$F_L = \frac{x - C_\alpha}{C_L - C_\alpha}$', fontsize=12,
                      loc='upper left', bbox_to_anchor=(1., 1.05), title_fontsize=14)

        C_a = min([zone_aL.get_paths()[0].vertices[idx[0]][0], zone_aL.get_paths()[0].vertices[idx[1]][0]])
        C_L = max([zone_aL.get_paths()[0].vertices[idx[0]][0], zone_aL.get_paths()[0].vertices[idx[1]][0]])
        f_a = (C_L - x) / (C_L - C_a)
        b1 = axs[1].bar([C_a], [f_a * 100], fc=a_color, label=r'$\alpha$:'+f'\n{C_a:4.1f}at% Ag\n{100 - C_a:4.1f}at% Cu', width=6, ec='k', zorder=10)
        b2 = axs[1].bar([C_L], [(1 - f_a) * 100], fc=L_color, label=r'$L$:'+f'\n{C_L:4.1f}at% Ag\n{100 - C_L:4.1f}at% Cu', width=6, ec='k', zorder=10)
        axs[1].bar_label(b1, labels=[r'$\alpha$'], fontsize=13, label_type='center', c='w', zorder=13)
        axs[1].bar_label(b1, labels=[r'$F_\alpha$ = ' + f'{x:,.1f}%' for x in b1.datavalues], c='dodgerblue', zorder=13,
                         bbox=dict(facecolor='white', alpha=0.925, boxstyle='round,pad=0.1', edgecolor='black'))

        axs[1].bar_label(b2, labels=[r'$L$'], fontsize=13, label_type='center', c='k', zorder=13)
        axs[1].bar_label(b2, labels=[r'$F_L$ = ' + f'{x:,.1f}%' for x in b2.datavalues], c='dodgerblue', zorder=13,
                         bbox=dict(facecolor='white', alpha=0.925, boxstyle='round,pad=0.1', edgecolor='black'))
        axs[1].legend(loc='upper left', bbox_to_anchor=(1., 1.05))

    elif ZOI_i == 5:
        idx = np.argwhere(np.diff(np.sign(zone_bL.get_paths()[0].vertices[:, 1]- T))).flatten()
        axs[0].scatter(*zone_bL.get_paths()[0].vertices[idx[1]], zorder=14, label=r'$C_L$', fc='w', ec='k', marker='^')
        axs[0].scatter(*zone_bL.get_paths()[0].vertices[idx[0]], zorder=14, label=r'$C_\beta$', fc='w', ec='k', marker='v')
        axs[0].legend(title=r'$F_L = \frac{C_\beta - x}{C_\beta - C_L}$' +
                     '\n' + r'$F_\beta = \frac{x - C_L}{C_L - C_\beta}$', fontsize=12,
                      loc='upper left', bbox_to_anchor=(1., 1.05), title_fontsize=14)
        C_L = min([zone_bL.get_paths()[0].vertices[idx[0]][0], zone_bL.get_paths()[0].vertices[idx[1]][0]])
        C_b = max([zone_bL.get_paths()[0].vertices[idx[0]][0], zone_bL.get_paths()[0].vertices[idx[1]][0]])
        f_L = (C_b - x) / (C_b - C_L)
        b1 = axs[1].bar([C_L], [f_L * 100], fc=L_color, label=r'$L$:'+f'\n{C_L:4.1f}at% Ag\n{100 - C_L:4.1f}at% Cu', width=6, ec='k', zorder=10)
        b2 = axs[1].bar([C_b], [(1 - f_L) * 100], fc=b_color, label=r'$\beta$:'+f'\n{C_b:4.1f}at% Ag\n{100 - C_b:4.1f}at% Cu', width=6, ec='k', zorder=10)
        axs[1].bar_label(b1, labels=[r'$L$'], fontsize=13, label_type='center', c='k', zorder=13)
        axs[1].bar_label(b1, labels=[r'$F_L$ = ' + f'{x:,.1f}%' for x in b1.datavalues], c='dodgerblue', zorder=13,
                         bbox=dict(facecolor='white', alpha=0.925, boxstyle='round,pad=0.1', edgecolor='black'))

        axs[1].bar_label(b2, labels=[r'$\beta$'], fontsize=13, label_type='center', c='k', zorder=13)
        axs[1].bar_label(b2, labels=[r'$F_\beta$ = ' + f'{x:,.1f}%' for x in b2.datavalues], c='dodgerblue', zorder=13,
                         bbox=dict(facecolor='white', alpha=0.925, boxstyle='round,pad=0.1', edgecolor='black'))
        axs[1].legend(loc='upper left', bbox_to_anchor=(1., 1.05))
    if overlay:
        for zone in zones:
            if zone != ZOI:
                p = axs[0].add_patch(mpl.patches.PathPatch(zone.get_paths()[0],
                                                       fc='w',
                                           zorder=10, alpha=0.7))

    axs[1].axhline(0, xmin=0, xmax=1, c='k')

    axs[1].scatter(x, -5, marker='^', c='goldenrod', ec='k', s=90, zorder=5)

    axs[1].set_xlim(-5, 105)
    axs[1].set_ylim(-10, 115)
    axs[1].set_xlabel('Composição [at% Ag]')
    axs[1].set_ylabel('Fração da Fase [%]', c='dodgerblue')
    axs[1].tick_params(axis='y', colors='dodgerblue')
    # plt.axis('off')
    axs[1].grid(ls=':')
    # plt.tight_layout()
    plt.subplots_adjust(hspace=0.7)
    fig.patch.set_facecolor((1.0, 0.0, 0.0, 0.0))


x_slider_base = widgets.FloatSlider(value=50,
                                    min=0,
                                    max=100,
                                    step=0.1,
                                    readout=False,
                                    readout_format='.2f',
                                    style= {'description_width': '0px'})
T_slider_base = widgets.FloatSlider(value=1000,
                                    min=0,
                                    max=1100-1e-6,
                                    step=0.5,
                                    readout=False,
                                    description=r'',
                                    readout_format='.2f',
                                    style= {'description_width': '0px'})

overlay_button = widgets.ToggleButton(False, description='Ativar Destaque')

interactive_plot = widgets.interactive(f, x=x_slider_base, T=T_slider_base,
                                       overlay=overlay_button)

x_slider_base.layout = widgets.Layout(width='445px')
T_slider_base.layout = widgets.Layout(width='445px')

x_slider_display = widgets.HTML(value=str(x_slider_base.value))
T_slider_display = widgets.HTML(value=str(T_slider_base.value))

x_slider =  widgets.VBox([x_slider_base,
                          x_slider_display])
T_slider =  widgets.VBox([T_slider_base,
                          T_slider_display])
x_slider_display.layout = widgets.Layout(margin='8px 0 4px 0')
T_slider_display.layout = widgets.Layout(margin='8px 0 0 0')
x_slider.layout = widgets.Layout(align_items='center', margin='-15px 0 0 -85px')
T_slider.layout = widgets.Layout(align_items='center', margin='-15px 0 0 -85px')
overlay_button.layout = widgets.Layout(margin='0 0 0 -70px')

x_slider_ticks_HTML_str = html_ticks(np.arange(0, 105, 20), 'x')
x_slider_ticks = widgets.HTML(x_slider_ticks_HTML_str)
x_slider_ticks.layout = widgets.Layout(width='424px', margin='0 0 -13px -77px',
                                     pad='0 0 0 0', position='absolute')
x_slider_ticked = widgets.VBox([x_slider_ticks, x_slider])
x_slider_ticked.layout = widgets.Layout(align_items='center', width='100%')

T_slider_ticks_HTML_str = html_ticks(np.arange(0, 1150, 200), 'T',
                                     ticks_pos=[0, 200/1100 * 100, 400/1100 * 100,
                                                600/1100 * 100, 800/1100 * 100,
                                                1000/1100 * 100])
T_slider_ticks = widgets.HTML(T_slider_ticks_HTML_str)
T_slider_ticks.layout = widgets.Layout(width='424px', margin='0 0 -13px -77px',
                                     pad='0 0 0 0', position='absolute')
T_slider_ticked = widgets.VBox([T_slider_ticks, T_slider])
T_slider_ticked.layout = widgets.Layout(align_items='center', width='100%')


output = widgets.VBox([interactive_plot.children[-1],
                      x_slider_ticked,
                      T_slider_ticked,
                      overlay_button])
def x_slider_callback(x_sli, T_sli):
    x_slider_display.value =  f"X = {x_sli:.2f} at% Ag"
    T_slider_display.value =  f"T = {T_sli:.1f}°C"


widgets.interactive_output(
    x_slider_callback, 
    {"x_sli": x_slider_base,
    "T_sli": T_slider_base})

output.layout = widgets.Layout(display='flex',
                               flex_flow='column',
                               align_items='center',
                               align_content='center',
                               justify_content='center',
                               width='100%',
                               height='100%')
interactive_plot.update()
output
 

metadados

comentários: