import vizro.models as vm
import plotly.graph_objects as go
import vizro.plotly.express as px
from vizro import Vizro
from vizro.tables import dash_ag_grid
from vizro.models.types import capture
from vizro.figures import kpi_card
import dash
from dash import dcc, html, Input, Output, callback, clientside_callback
import pandas as pd
import copy
df_article = pd.read_csv("./data/article_properties_17June.csv")
df_mat = pd.read_csv('data/elsevier_rsc_wiley_properties.csv')
@capture("graph")
def custom_hist(data_frame, x):
fig = px.histogram(data_frame, x=x)
fig.update_layout(#width=500, height=400,
xaxis_title=None,
xaxis=dict(tickfont=dict(size=16, color='black')),
yaxis=dict(tickfont=dict(size=16, color='black'))
)
return fig
@capture("graph")
def custom_scatter_dual(data_frame):
data_frame = data_frame.dropna(subset=['maximum_capacity']).sort_values(by='maximum_capacity', ascending=True)
fig = px.scatter(
data_frame,
x='maximum_capacity',
y='BET',
color='class',
trendline="ols",
trendline_scope='overall',
marginal_x="histogram",
marginal_y="histogram",
)
# fig.data[0].update(
# # marker=dict(size=10, color='blue'),
# customdata=data_frame[['material', 'class', 'stability', 'cycle', 'doi','url']].values,
# hovertemplate='<b>Material:</b> %{customdata[0]}<br>' +
# '<b>BET:</b> %{y}<br>' +
# '<b>Capacity:</b> %{x}<br>' +
# '<b>Class:</b> %{customdata[1]}<br>' +
# '<b>Stability:</b> %{customdata[2]}<br>' +
# '<b>Cycle:</b> %{customdata[3]}<br>' +
# '<b>DOI:</b> %{customdata[4]}<extra></extra>'
# )
for i, trace in enumerate(fig.data):
# Only update scatter plot traces (not histogram traces)
# if i < len(data_frame['class'].unique()):
if hasattr(trace, 'mode') and 'markers' in trace.mode:
# Check if this is a main plot trace (not marginal)
if (not hasattr(trace, 'xaxis') or trace.xaxis == 'x') and \
(not hasattr(trace, 'yaxis') or trace.yaxis == 'y'):
trace.update(
marker=dict(size=10),
customdata=data_frame[['material', 'class', 'stability', 'cycle', 'doi','url']].values,
hovertemplate='<b>Material:</b> %{customdata[0]}<br>' +
'<b>BET:</b> %{y}<br>' +
'<b>Capacity:</b> %{x}<br>' +
'<b>Class:</b> %{customdata[1]}<br>' +
'<b>Stability:</b> %{customdata[2]}<br>' +
'<b>Cycle:</b> %{customdata[3]}<br>' +
'<b>DOI:</b> %{customdata[4]}<extra></extra>'
)
# Update layout
fig.update_layout(
xaxis_title="Maximum capacity (mmol/g)",
yaxis_title="BET (m2/g)",
xaxis=dict(tickfont=dict(size=16, color='black')),
yaxis=dict(tickfont=dict(size=16, color='black'))
)
fig2 = copy.deepcopy(fig)
fig2.data[-3].showlegend = True
fig2.data = fig2.data[:-2]
return fig2
@capture("graph")
def custom_scatter_click(data_frame, target, info_to_show, width=500, height=400):
data_frame = data_frame.dropna(subset=[target]).sort_values(by=target, ascending=True)
fig = go.Figure()
if target=='BET':
fig.add_trace(go.Scatter(
x=list(range(len(data_frame))),
y=data_frame[target],
mode='markers',
marker=dict(size=10, color='blue'),
customdata=data_frame[info_to_show].values,
hovertemplate='<b>Material:</b> %{customdata[0]}<br>' +
'<b>BET:</b> %{y}<br>' +
'<b>Capacity:</b> %{customdata[1]}<br>' +
'<b>Class:</b> %{customdata[2]}<br>' +
'<b>Stability:</b> %{customdata[3]}<br>' +
'<b>Cycle:</b> %{customdata[4]}<br>' +
'<b>DOI:</b> %{customdata[5]}<extra></extra>'
)
)
fig.update_layout(xaxis_title="Index",
yaxis_title="BET (m2/g)",
xaxis=dict(tickfont=dict(size=16, color='black')),
yaxis=dict(tickfont=dict(size=16, color='black'))
)
if target=='maximum_capacity':
fig.add_trace(go.Scatter(
x=list(range(len(data_frame))),
y=data_frame[target],
mode='markers',
marker=dict(size=10, color='blue'),
customdata=data_frame[info_to_show].values,
hovertemplate='<b>Material:</b> %{customdata[0]}<br>' +
'<b>BET:</b> %{customdata[1]}<br>' +
'<b>Capacity:</b> %{y}<br>' +
'<b>Class:</b> %{customdata[2]}<br>' +
'<b>Stability:</b> %{customdata[3]}<br>' +
'<b>Cycle:</b> %{customdata[4]}<br>' +
'<b>DOI:</b> %{customdata[5]}<extra></extra>'
)
)
fig.update_layout(width=width, height=height, xaxis_title="Index",
yaxis_title="Capacity (mmol/g)",
xaxis=dict(tickfont=dict(size=16, color='black')),
yaxis=dict(tickfont=dict(size=16, color='black'))
)
return fig
first_page = vm.Page(
title="Article Data",
components=[
vm.AgGrid(
figure=dash_ag_grid(df_article),
),
],
)
second_page = vm.Page(
title="Material Data",
components=[
vm.AgGrid(
figure=dash_ag_grid(df_mat),
),
],
)
third_page = vm.Page(
title="Classification",
layout=vm.Grid(grid=[[0, 1,-1,-1], [2, 3,-1,-1], [4, 5,-1,-1], [6, 7,-1,-1]],
row_gap="40px", col_gap="40px",
row_min_height='450px', col_min_width='450px'),
components = [
vm.Graph(figure=custom_hist(df_article, x='Year'),title="Year"),
vm.Graph(
figure=custom_hist(df_article, x='exp_classify'),
title="Article contains experimental work"
),
vm.Graph(
figure=custom_hist(df_article, x='mat_classify'),
title="Material relevant to CO2 capture"
),
vm.Graph(
figure=custom_hist(df_article, x='source_classify'),
title="CO2 source"
),
vm.Graph(
figure=custom_hist(df_article, x='ads_classify'),
title="CO2 capture mechanism"
),
vm.Graph(figure=custom_hist(df_mat, 'class'), title="Adsorbent classification"),
vm.Graph(figure=custom_hist(df_mat, 'cycle'), title="Cyclic experiments or regenerations"),
vm.Graph(figure=custom_hist(df_mat, 'stability'), title="Stability"),
]
)
fourth_page = vm.Page(
title="Analysis",
layout=vm.Grid(grid=[[0, -1], [1, -1], [2, -1]],
row_gap="10px", col_gap="20px",
row_min_height='550px', col_min_width='550px'),
components = [
vm.Graph(figure=custom_scatter_click(df_mat, 'maximum_capacity',
['material','BET', 'class', 'stability', 'cycle', 'doi','url'],
width=550,height=500
),
title="Capacity"
),
vm.Graph(figure=custom_scatter_click(df_mat, 'BET',
['material','maximum_capacity', 'class', 'stability', 'cycle', 'doi','url']
),
title="BET"
),
vm.Graph(figure=custom_scatter_dual(df_mat),
title="Capacity vs. BET"
)
],
controls = [vm.Filter(column="class", selector=vm.Checklist())]
)
dashboard = vm.Dashboard(
pages=[first_page, second_page, third_page, fourth_page],
title = "Materials for CO2 Capture from Literatures Dashboard",
navigation=vm.Navigation(nav_selector=vm.NavBar(
items = [
vm.NavLink(label='Data', pages=["Article Data", "Material Data"], icon="database"),
vm.NavLink(label='Charts', pages=["Classification", "Analysis"], icon="bar_chart"),
]
)
)
)
Vizro().build(dashboard).run()