Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
72 commits
Select commit Hold shift + click to select a range
1b37039
Add README with Windows and Ubuntu installation guide
Jul 6, 2025
5901c97
Update README with additional setup details
Jul 6, 2025
106804a
Update README with more additional setup details
Jul 6, 2025
8ea7a23
Update README with more additional setup details
Jul 6, 2025
f59a8b5
Update README with additional setup details
Jul 7, 2025
adc6775
✨ Abbreviation toggle, font styling, and heatmap controls implemented
Jul 21, 2025
d574b0a
🔧 Updated issues relating to overlapping labels
Jul 21, 2025
3748c49
Merge remote-tracking branch 'upstream/main' into Sudeep
Jul 24, 2025
59c26d5
Update feat_vs_anno_server.py with better readibality
Jul 24, 2025
c7ea3ea
Update feat_vs_anno_server.py with better readability for the labels
Jul 24, 2025
75731ec
Integrated datashader library into heatmaps for scatterplots and envi…
Aug 1, 2025
90c4513
Full integration: Datashader updates, utils, and heatmap UI
Aug 1, 2025
33aba4b
Update to python version to 3.9.13
Aug 1, 2025
d387d64
Moving colorcet library under pip for better organization
Aug 1, 2025
5a1be36
Update Quickstart_MacArm64.md with improved setup instructions
r0h1tK7 Aug 7, 2025
ec7b22c
Fix typo in Quickstart_MacArm64.md
r0h1tK7 Aug 7, 2025
8834bb4
feat: Add list of supported file types under the file upload button
r0h1tK7 Aug 7, 2025
47aefca
Removed mac quickstart file
r0h1tK7 Aug 7, 2025
a8706ed
Merge remote-tracking branch 'origin/Feat_vs_Anno_Labels' into font_s…
r0h1tK7 Aug 10, 2025
b061f42
feat: Add font size sliders to plot tabs
r0h1tK7 Sep 1, 2025
bc03645
add boqiang as a contributer
zhan4329 Oct 2, 2025
88e2891
sungmin
risingmin Oct 2, 2025
93acb1f
Testing
Saran-Nag Oct 2, 2025
28b5c41
Noah Lee
nlee3105 Oct 2, 2025
c7b4d23
add boqiang
zhan4329 Oct 2, 2025
83ac232
add Heaven
heaven-howard Oct 7, 2025
ef8377f
add gitignore, rm __pycache__
zhan4329 Oct 8, 2025
f989aa4
update gitignore to include .ipynb_checkpoints/
zhan4329 Oct 8, 2025
57f3da7
update README
arjunchhabra1 Oct 16, 2025
885e06a
fix(docs): replace the spac channel to solve import error
zhan4329 Oct 23, 2025
5d75f2d
fix(docker): change apt-get source from http:// to https:// to make i…
zhan4329 Oct 23, 2025
2d4f0d7
Merge branch 'test/bmc-paper-updates-pr-59'
Saran-Nag Oct 23, 2025
d5751a0
PR 59: Merge George to Purdue
Saran-Nag Oct 23, 2025
ff64951
Font Slider Testing
Saran-Nag Oct 23, 2025
da909d4
Undo Changes
Saran-Nag Oct 23, 2025
d1ba7fa
Font Slider for Annotations
Saran-Nag Oct 23, 2025
8b4322d
Boxplot Font Slider
Saran-Nag Oct 24, 2025
943c877
Merge Saran's 4 commits into merge/high-school-prs-issue-7
zhan4329 Oct 24, 2025
5eacb7c
Merge branch 'Feat_vs_Anno_Labels' of github.com:Summer2025-SPAC/SPAC…
zhan4329 Oct 24, 2025
cefa340
Merge branch 'Summer2025-SPAC-Feat_vs_Anno_Labels' into merge/high-sc…
zhan4329 Oct 24, 2025
05adb49
Revert "Feat vs anno labels"
zhan4329 Oct 24, 2025
1336f14
Merge pull request #9 from Saran-Nag/revert-1-Feat_vs_Anno_Labels
zhan4329 Oct 24, 2025
d38ad2c
Revert "Revert "Feat vs anno labels""
zhan4329 Oct 24, 2025
e7d8757
Merge pull request #10 from Saran-Nag/revert-9-revert-1-Feat_vs_Anno_…
zhan4329 Oct 24, 2025
f7448b8
Merge pull request #3 from Summer2025-SPAC/yml_instr_mac_rk
zhan4329 Oct 24, 2025
2334730
Moved Annotation UI for Render Plot
Saran-Nag Oct 28, 2025
62a1496
Features Font Slider
Saran-Nag Oct 28, 2025
f135291
Merge remote-tracking branch 'upstream/main' into merge/high-school-p…
zhan4329 Oct 29, 2025
88e6df0
Merge branch 'FNLCR-DMAP:main' into main
zhan4329 Oct 29, 2025
1996175
fix(docker): fix 'Hash Sum Mismatch' bug on mac
zhan4329 Oct 29, 2025
861b1fd
Merge branch 'fix/docker-mac-issue-12' into merge/high-school-prs-iss…
zhan4329 Oct 30, 2025
3b014f6
Added font size sliders for Sankey + Heatmap (Anno vs Anno)
arjunchhabra1 Oct 30, 2025
3b09cf1
added font sliders to scatterplot and nearest_neighbor
nlee3105 Oct 30, 2025
c6c1709
Added font sliders to Spatial and UMAP tabs
risingmin Oct 30, 2025
cefce51
Merge branch 'test/bmc-paper-updates-pr-59' of https://github.com/Sar…
risingmin Oct 30, 2025
6da5caf
Merge branch 'FNLCR-DMAP:main' into main
zhan4329 Oct 30, 2025
3aabb52
Merge pull request #13 from Saran-Nag/test/bmc-paper-updates-pr-59
arjunchhabra1 Oct 30, 2025
a309bd2
Merge Conflicts
Saran-Nag Oct 30, 2025
1491c34
Heatmap Pin for now
Saran-Nag Oct 30, 2025
dc68e72
fix(docker): python layer changed to 3.10-slim-bookworm
zhan4329 Oct 31, 2025
a0dcf09
Merge pull request #17 from Saran-Nag/fix/python-version-issue-15
zhan4329 Oct 31, 2025
2c6d95b
Merge branch 'main' into merge/high-school-prs-issue-7
zhan4329 Oct 31, 2025
a30af07
Merge branch 'font_size_rk' of github.com:Summer2025-SPAC/SPAC_Shiny …
zhan4329 Oct 31, 2025
199064a
chore(env): remove/archive redundant files for environments
zhan4329 Oct 31, 2025
8fa1aaa
Merge branch 'Summer2025-SPAC-font_size_rk' into merge/high-school-pr…
zhan4329 Oct 31, 2025
5c15b9b
chore: fix width issue in anno. tab; create a to-do for scatter_heatmap
zhan4329 Oct 31, 2025
53e8c5f
chore: small fixes and files clean-up for Pull Request #61
zhan4329 Nov 1, 2025
b2798ff
docs: add a link to the SPAC contributing guide
zhan4329 Nov 1, 2025
5111a99
docs(contri): add link to the copilot-instructions file
zhan4329 Nov 1, 2025
43a02b4
Merge branch 'FNLCR-DMAP:main' into main
zhan4329 Nov 3, 2025
730d0a1
Merge branch 'main' into merge/high-school-prs-issue-7
zhan4329 Nov 3, 2025
95d41db
chore(env): update environment.yml accordingly
zhan4329 Nov 3, 2025
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 4 additions & 1 deletion .gitignore
Original file line number Diff line number Diff line change
@@ -1,3 +1,6 @@
# Jupyter
.ipynb_checkpoints/

# Python
__pycache__/
*.py[cod]
Expand Down Expand Up @@ -65,4 +68,4 @@ SCSAWorkflow/
# Security documentation (internal use only)
SECURITY_DOCUMENTATION.md
SECURITY_IMPLEMENTATION.md
SECURITY_FIXES.md
SECURITY_FIXES.md
7 changes: 7 additions & 0 deletions CONTRIBUTING.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
# Contributing

Contributions are welcome, and they are greatly appreciated! Every little bit helps, and credit will always be given.

Please refer to this copilot-based instructions for SPAC Shiny development: https://github.com/FNLCR-DMAP/SPAC_Shiny/blob/main/.github/copilot-instructions.md

Also refer to this contributing guide in the SPAC Package project for more information: https://github.com/FNLCR-DMAP/SCSAWorkflow/blob/main/CONTRIBUTING.md
11 changes: 10 additions & 1 deletion Dockerfile
Original file line number Diff line number Diff line change
@@ -1,9 +1,18 @@
# Use official Python image as base
FROM python:3.9.19-slim-bookworm
# Fix: python version conflicts (Issue #15 in Purdue-2025 fork)
# Error message when building docker:
# Package 'datashader' requires a different Python: 3.9.19 not in '>=3.10'
# FROM python:3.9.19-slim-bookworm
FROM python:3.10-slim-bookworm

# Set working directory
WORKDIR /app

# Fix: 'Hash Sum Mismatch' bug for mac device (Issue #12 in Purdue-2025 fork)
RUN echo "Acquire::http::Pipeline-Depth 0;" > /etc/apt/apt.conf.d/99custom && \
echo "Acquire::http::No-Cache true;" >> /etc/apt/apt.conf.d/99custom && \
echo "Acquire::BrokenProxy true;" >> /etc/apt/apt.conf.d/99custom

# Install system dependencies needed for scientific packages
RUN apt-get update && apt-get install -y \
gcc \
Expand Down
7 changes: 7 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -63,8 +63,15 @@ This project was a success thanks to the invaluable collaboration and support fr
* Suriya Selvarajan
* Qianyue Wang
* Andree Kolliegbo
* Sungmin Lee
* Saran Nagubandi
* Noah Lee
* Boqiang Zhang
* Heaven Golladay-Watkins
* Arjun Chhabra
* **Teaching Assistants (TAs) from Purdue's Data Mine:**
* Alex Liu
* Omar Eldaghar
* Thomas Sheeley
* Ramya Rajaram
* **Additional Support:** Kang Liu and Rui He, and the entire Data Mine staff.
40 changes: 35 additions & 5 deletions environment.yml
Original file line number Diff line number Diff line change
@@ -1,11 +1,31 @@
# Warning:
# This file may be outdated. Check with requirements.txt to get the latest environmental requirements.
# This is a file for conda users to create an environment.

# Quick Guide:
# 1. Make sure you are in the repository's directory and 'conda' is installed.
# 2. Run 'conda env create -f environment.yml' to create the conda environment.
# 3. Run 'conda activate shiny' to activate this environment.
# 4. Run 'shiny run --reload app.py' to run the app.
# The app will be available at http://127.0.0.1:8000.

# Special Reminder:
# For macOS (MacArm64) users, make these edits to the environment.yml file:
# Under dependencies, add these lines:
# - tables>=3.8.0
# - c-blosc2
# - libtiff
# Under pip, remove this line:
# - tables==3.8.0

name: shiny
channels:
- ohsu-comp-bio
- conda-forge
- leej3
- https://fnlcr-dmap.github.io/scimap/
dependencies:
- python=3.9.13
- python=3.10.19 # To support datashader, need python>=3.10
- numpy=1.26.4
- pandas=1.5.3
- anndata=0.10.9
Expand All @@ -18,20 +38,24 @@ dependencies:
- squidpy=1.2.2
- scikit-image=0.19.3
- scipy=1.10.1
# For macOS (MacArm64) users, uncomment the following three lines
# - tables>=3.8.0
# - c-blosc2
# - libtiff
- pip
- pip:
- ipykernel==6.29.5
- ipython==8.18.0
- ipython-genutils==0.2.0
- ipywidgets==8.1.3
- ipywidgets==8.1.7 # To be consistent with requirement.txt
- jsonschema-specifications==2023.12.1
- jupyter-events==0.10.0
- jupyter_client==7.4.9
- jupyter_core==5.7.2
- jupyter_server==2.14.1
- jupyter_server_terminals==0.5.3
- jupyterlab_pygments==0.3.0
- jupyterlab_widgets==3.0.11
- jupyterlab_widgets==3.0.15 # To be consistent with requirement.txt
- nbclient==0.10.0
- nbconvert==7.16.4
- nbformat==5.10.4
Expand All @@ -50,7 +74,7 @@ dependencies:
- shinyswatch==0.6.1
- shinywidgets==0.7.0
- sinfo==0.3.4
- tables==3.8.0
- tables==3.8.0 # For macOS (MacArm64) users, comment out this line.
- tinycss2==1.3.0
- tqdm==4.66.4
- typeguard==4.3.0
Expand All @@ -60,5 +84,11 @@ dependencies:
- websockets==12.0
- zipp==3.19.2
- tifffile
- shapely==2.0.7 # To be consistent with requirement.txt
- sag-py-execution-time-decorator @ git+https://github.com/SamhammerAG/sag_py_execution_time_decorator.git@976c9683d561aadc0166495117c42cc1762633d7
- spac @ git+https://github.com/FNLCR-DMAP/SCSAWorkflow.git@76f381316acd57ff9fbe3e5bea4e37b0a9ae3dd9#egg=spac
# Added: packages for heatmap mode in scatterplot
- colorcet
- git+https://github.com/holoviz/datashader.git
# SPAC package pinned to specific commit for template compatibility (dev branch as of 2025-10-15)
- spac @ git+https://github.com/FNLCR-DMAP/SCSAWorkflow.git@c2a248826b91880c62308e85e60cae9361c275d0#egg=spac

3 changes: 3 additions & 0 deletions requirements.txt
Original file line number Diff line number Diff line change
Expand Up @@ -52,5 +52,8 @@ zipp==3.19.2
tifffile
shapely==2.0.7
sag-py-execution-time-decorator @ git+https://github.com/SamhammerAG/sag_py_execution_time_decorator.git@976c9683d561aadc0166495117c42cc1762633d7
# Added: packages for heatmap mode in scatterplot
colorcet
git+https://github.com/holoviz/datashader.git
# SPAC package pinned to specific commit for template compatibility (dev branch as of 2025-10-15)
spac @ git+https://github.com/FNLCR-DMAP/SCSAWorkflow.git@c2a248826b91880c62308e85e60cae9361c275d0#egg=spac
22 changes: 22 additions & 0 deletions server/anno_vs_anno_server.py
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,15 @@ def spac_Sankey():
source_annotation=input.sk1_anno1(),
target_annotation=input.sk1_anno2()
)

font_size = input.sankey_font_size()

# Modified...
# Applying font size directly to the Sankey trace for node and
# label text, as the global layout font can sometimes be ignored.
fig.update_layout(font=dict(size=font_size))
fig.update_traces(textfont=dict(size=font_size), selector=dict(type='sankey'))

return fig
return None

Expand All @@ -40,6 +49,19 @@ def spac_Relational():
target_annotation=input.rhm_anno2()
)
shared['df_relational'].set(result['data'])

font_size = input.heatmap_font_size()

# Modified...
# Applying font size directly to the heatmap axes and color bar,
# as these elements often have their own font settings.
result['figure'].update_layout(
font=dict(size=font_size),
xaxis=dict(tickfont=dict(size=font_size)),
yaxis=dict(tickfont=dict(size=font_size))
)
result['figure'].update_coloraxes(colorbar_tickfont_size=font_size)

return result['figure']
return None

Expand Down
62 changes: 37 additions & 25 deletions server/annotations_server.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
from shiny import ui, render, reactive
import numpy as np
import spac.visualization
# Added...
import matplotlib.pyplot as plt

def annotations_server(input, output, session, shared):
@output
Expand All @@ -11,30 +13,38 @@ def spac_Histogram_2():
if adata is None:
return None

# Added...
# Note: This assumes your UI file has a slider with the id 'annotations_font_size'.
# Please ensure this ID matches the one in your annotations_ui.py file.
font_size = input.annotations_font_size()
plt.rcParams.update({'font.size': font_size})
rotation = input.anno_slider()

# 1) If "Group By" is UNCHECKED, show a simple annotation histogram
if not input.h2_group_by_check():
fig, ax, df = spac.visualization.histogram(
adata,
annotation=input.h2_anno()
).values()
shared['df_histogram2'].set(df)
ax.tick_params(axis='x', rotation=input.anno_slider(), labelsize=10)
shared['df_histogram2'].set(df)
# Modified...
ax.tick_params(axis='x', rotation=rotation, labelsize=font_size)
return fig

# 2) If "Group By" is CHECKED, we must always supply a
# 2) If "Group By" is CHECKED, we must always supply a
# valid multiple parameter
else:
# If user also checked "Plot Together", use their selected
# If user also checked "Plot Together", use their selected
# stack type
if input.h2_together_check():
# e.g. 'stack', 'dodge', etc.
multiple_param = input.h2_together_drop()
multiple_param = input.h2_together_drop()

together_flag = True
else:
# If grouping by but not "plot together", pick a default layout
# or 'dodge' or any valid string
multiple_param = "layer"
multiple_param = "layer"
together_flag = False

fig, ax, df = spac.visualization.histogram(
Expand All @@ -44,13 +54,15 @@ def spac_Histogram_2():
together=together_flag,
multiple=multiple_param
).values()
shared['df_histogram2'].set(df)
shared['df_histogram2'].set(df)
axes = ax if isinstance(ax, (list, np.ndarray)) else [ax]
for ax in axes:
ax.tick_params(
axis='x',
rotation=input.anno_slider(),
labelsize=10
# Modified... (renamed loop variable to avoid shadowing)
for current_ax in axes:
# Modified...
current_ax.tick_params(
axis='x',
rotation=rotation,
labelsize=font_size
)
return fig
return None
Expand All @@ -61,16 +73,16 @@ def spac_Histogram_2():
def download_histogram_button_ui():
if shared['df_histogram2'].get() is not None:
return ui.download_button(
"download_histogram2_df",
"Download Data",
"download_histogram2_df",
"Download Data",
class_="btn-warning"
)
return None


@render.download(filename="annotation_histogram_data.csv")
def download_histogram2_df():
df = shared['df_histogram2'].get()
df = shared['df_human_histogram2'].get()
if df is not None:
csv_string = df.to_csv(index=False)
csv_bytes = csv_string.encode("utf-8")
Expand All @@ -86,8 +98,8 @@ def histogram_reactivity_2():

if btn and not ui_initialized:
dropdown = ui.input_select(
"h2_anno_1",
"Select an Annotation",
"h2_anno_1",
"Select an Annotation",
choices=shared['obs_names'].get()
)
ui.insert_ui(
Expand All @@ -97,8 +109,8 @@ def histogram_reactivity_2():
)

together_check = ui.input_checkbox(
"h2_together_check",
"Plot Together",
"h2_together_check",
"Plot Together",
value=True
)
ui.insert_ui(
Expand All @@ -120,18 +132,18 @@ def histogram_reactivity_2():
def update_stack_type_dropdown():
if input.h2_together_check():
dropdown_together = ui.input_select(
"h2_together_drop",
"Select Stack Type",
choices=['stack', 'layer', 'dodge', 'fill'],
"h2_together_drop",
"Select Stack Type",
choices=['stack', 'layer', 'dodge', 'fill'],
selected='stack'
)
ui.insert_ui(
ui.div({
"id": "inserted-dropdown_together-1"},
"id": "inserted-dropdown_together-1"},
dropdown_together
),
selector="#main-h2_together_drop",
where="beforeEnd"
)
)
else:
ui.remove_ui("#inserted-dropdown_together-1")
ui.remove_ui("#inserted-dropdown_together-1")
Loading