from urllib import request
import requests
import io
from typing import Optional, cast
import pandas as pd
import plotly.express as px
import plotly.io as pio
import solara
import solara.express as solara_px
import solara.lab
from solara.components.columns import Columns
import json
theme = pio.templates["plotly_dark"]
theme["layout"]["plot_bgcolor"] = "rgb(17,17,17)"
theme["layout"]["paper_bgcolor"] = "rgb(27,27,27)"
theme["layout"]["geo"]["bgcolor"] = "rgb(30,30,30)"
theme["layout"]["shapedefaults"]["line"]["width"] = 0.1
## Get sample data
dataurl = "https://www.astro.rug.nl/~balbinot/files/Euclid/lightDEARs_noextra.csv"
dataurl = "https://github.com/balbinot/OU-EXT-QA/raw/main/sample.csv.gz"
df_sample = pd.read_csv(dataurl)
#response = requests.get(dataurl)
#content = response.content
#df_sample = pd.read_csv(
# io.BytesIO(content), sep=",", compression="gzip", index_col=0, quotechar='"',
#)
geojsonurl = "https://www.astro.rug.nl/~balbinot/files/Euclid/tiles.json"
with request.urlopen(geojsonurl) as url:
regions = json.load(url)
# Local stuff
# df_sample = pd.read_csv("../protoTV/lightDEARs_noextra.csv.gz")
# regions = json.load(open("../protoTV/tiles.json", "r"))
class State:
dataset = solara.reactive(cast(Optional[str], None))
metric = solara.reactive(cast(Optional[str], 'ap_image_depth10_MEGACAM_r'))
band = solara.reactive(cast(Optional[str], None))
df = solara.reactive(cast(Optional[pd.DataFrame], None))
filter = solara.reactive(None)
@staticmethod
def load_sample():
State.filter.value = None
State.df.value = df_sample
@solara.component
def Page():
solara.Title("Euclid OU-EXT TileViewer")
def makeHist():
fig2 = px.histogram(
df, x=metric, nbins=30, height=600, width=600, template=theme
)
return fig2
def makeFigure():
_fig = px.choropleth(
df,
geojson=regions,
locations="tileid",
color=metric,
color_continuous_scale="Cividis",
template=theme,
custom_data=["tileid", "DataSetRelease"],
hover_data=["tileid", "DataSetRelease"],
)
_fig.update_geos(
projection_type="orthographic",
lonaxis={"showgrid": True, "tick0": 0, "dtick": 15, "gridwidth": 0.3},
lataxis={"showgrid": True, "tick0": 90, "dtick": 30, "gridwidth": 0.3},
showland=False,
showocean=False,
visible=False,
showframe=True,
framewidth=2,
projection_rotation={'lon':270, 'lat': 70},
projection_scale=2
)
## This is not passed along by solara_px!
_fig.update_traces(
marker_line_width=0.1,
selector=dict(type="choropleth"),
)
_fig.update_layout(width=900, height=900)
return _fig
def selection_fn(a):
State.filter.value = a["points"]["point_indexes"]
def filter_df():
print("filter updated")
print(filter)
if filter is not None and df is not None:
return df.loc[filter]
else:
return df
solara.use_memo(lambda: State.load_sample())
df = State.df.value
filter, _set_filter = solara.use_cross_filter(id(df))
dff = solara.use_memo(filter_df, dependencies=[df, filter])
# dark_effective = solara.lab.use_dark_effective()
with solara.AppBar():
solara.lab.ThemeToggle()
with solara.Sidebar():
with solara.Card("Controls", margin=0, elevation=0):
with solara.Column(style={"max-width": "600px"}):
if df is not None:
solara.Select(
"DataSetRelease",
values=df["DataSetRelease"].unique().tolist(),
value=State.dataset,
)
nice_cols = [col for col in df.columns if "depth" in col]
solara.Select("Metric", values=nice_cols, value=State.metric)
if filter is None:
solara.Info(
"If you select points in the scatter plot, you can download the points here."
)
else:
def get_data():
return dff.to_csv(index=False)
solara.FileDownload(
get_data,
label=f"Download {len(dff):,} selected points",
filename="selected.csv",
)
with Columns():
solara.CrossFilterDataFrame(
dff.dropna(axis=1, how="all").round(2), items_per_page=15
)
with Columns():
if State.metric.value is None:
metric = "ap_image_depth10_MEGACAM_r"
else:
metric = State.metric.value
fig = solara.use_memo(
makeFigure,
dependencies=[metric],
)
fig2 = solara.use_memo(makeHist, dependencies=[df, metric])
solara_px.CrossFilteredFigurePlotly(fig)
## When using this all properties for fig are properly shown
solara.FigurePlotly(
fig,
on_selection=selection_fn,
)
#solara_px.CrossFilteredFigurePlotly(fig2)
# solara.FigurePlotly(fig2)
with solara.Column(style={"max-width": "400px"}):
solara.Button(
label="View source",
icon_name="mdi-github-circle",
attributes={"href": "http://balbinot.github.io", "target": "_blank"},
text=True,
outlined=True,
)
@solara.component
def Layout(children):
route, routes = solara.use_route()
dark_effective = solara.lab.use_dark_effective()
return solara.AppLayout(
children=children, toolbar_dark=dark_effective, color=None
) # if dark_effective else "primary")