spacr 0.2.61__py3-none-any.whl → 0.2.65__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- spacr/__init__.py +1 -3
- spacr/gui_core.py +136 -137
- spacr/gui_elements.py +301 -1
- spacr/gui_utils.py +39 -2
- spacr/plot.py +4 -4
- spacr/sequencing.py +4 -8
- spacr/utils.py +1 -1
- {spacr-0.2.61.dist-info → spacr-0.2.65.dist-info}/METADATA +1 -1
- {spacr-0.2.61.dist-info → spacr-0.2.65.dist-info}/RECORD +13 -13
- {spacr-0.2.61.dist-info → spacr-0.2.65.dist-info}/LICENSE +0 -0
- {spacr-0.2.61.dist-info → spacr-0.2.65.dist-info}/WHEEL +0 -0
- {spacr-0.2.61.dist-info → spacr-0.2.65.dist-info}/entry_points.txt +0 -0
- {spacr-0.2.61.dist-info → spacr-0.2.65.dist-info}/top_level.txt +0 -0
spacr/__init__.py
CHANGED
@@ -17,7 +17,6 @@ from . import gui_utils
|
|
17
17
|
from . import gui_elements
|
18
18
|
from . import gui_core
|
19
19
|
from . import gui
|
20
|
-
from . import gui
|
21
20
|
from . import app_make_masks
|
22
21
|
from . import app_mask
|
23
22
|
from . import app_measure
|
@@ -35,7 +34,7 @@ __all__ = [
|
|
35
34
|
"plot",
|
36
35
|
"measure",
|
37
36
|
"sim",
|
38
|
-
"sequencing"
|
37
|
+
"sequencing",
|
39
38
|
"timelapse",
|
40
39
|
"deep_spacr",
|
41
40
|
"app_annotate",
|
@@ -43,7 +42,6 @@ __all__ = [
|
|
43
42
|
"gui_elements",
|
44
43
|
"gui_core",
|
45
44
|
"gui",
|
46
|
-
"gui",
|
47
45
|
"app_make_masks",
|
48
46
|
"app_mask",
|
49
47
|
"app_measure",
|
spacr/gui_core.py
CHANGED
@@ -83,12 +83,22 @@ def toggle_settings(button_scrollable_frame):
|
|
83
83
|
def process_fig_queue():
|
84
84
|
global canvas, fig_queue, canvas_widget, parent_frame, uppdate_frequency, figures, figure_index
|
85
85
|
|
86
|
+
from .gui_elements import standardize_figure
|
86
87
|
try:
|
87
88
|
while not fig_queue.empty():
|
88
89
|
fig = fig_queue.get_nowait()
|
90
|
+
|
91
|
+
if fig is None:
|
92
|
+
print("Warning: Retrieved a None figure from fig_queue.")
|
93
|
+
continue # Skip processing if the figure is None
|
94
|
+
|
95
|
+
# Standardize the figure appearance before adding it to the list
|
96
|
+
standardize_figure(fig)
|
97
|
+
|
89
98
|
figures.append(fig)
|
90
|
-
figure_index
|
91
|
-
|
99
|
+
if figure_index == len(figures) - 2:
|
100
|
+
figure_index += 1
|
101
|
+
display_figure(fig)
|
92
102
|
except Exception as e:
|
93
103
|
traceback.print_exc()
|
94
104
|
finally:
|
@@ -98,8 +108,23 @@ def process_fig_queue():
|
|
98
108
|
def display_figure(fig):
|
99
109
|
global canvas, canvas_widget
|
100
110
|
|
111
|
+
from .gui_elements import modify_figure_properties, save_figure_as_format, modify_figure
|
112
|
+
|
113
|
+
# Apply the dark style to the context menu
|
114
|
+
style_out = set_dark_style(ttk.Style())
|
115
|
+
bg_color = style_out['bg_color']
|
116
|
+
fg_color = style_out['fg_color']
|
117
|
+
|
118
|
+
# Initialize the scale factor for zooming
|
119
|
+
scale_factor = 1.0
|
120
|
+
|
121
|
+
# Save the original x and y limits of the first axis (assuming all axes have the same limits)
|
122
|
+
original_xlim = [ax.get_xlim() for ax in fig.get_axes()]
|
123
|
+
original_ylim = [ax.get_ylim() for ax in fig.get_axes()]
|
124
|
+
|
101
125
|
# Clear previous canvas content
|
102
|
-
canvas
|
126
|
+
if canvas:
|
127
|
+
canvas.get_tk_widget().destroy()
|
103
128
|
|
104
129
|
# Create a new canvas for the figure
|
105
130
|
new_canvas = FigureCanvasTkAgg(fig, master=canvas_widget.master)
|
@@ -109,154 +134,141 @@ def display_figure(fig):
|
|
109
134
|
# Update the global canvas and canvas_widget references
|
110
135
|
canvas = new_canvas
|
111
136
|
canvas_widget = new_canvas.get_tk_widget()
|
112
|
-
|
113
|
-
# Apply the dark style to the context menu
|
114
|
-
style_out = set_dark_style(ttk.Style())
|
115
|
-
bg_color = style_out['bg_color']
|
116
|
-
fg_color = style_out['fg_color']
|
117
|
-
|
118
|
-
# Define the save functions for the context menu
|
119
|
-
def save_figure_as_format(format):
|
120
|
-
file_path = filedialog.asksaveasfilename(defaultextension=f".{format}", filetypes=[(f"{format.upper()} files", f"*.{format}"), ("All files", "*.*")])
|
121
|
-
if file_path:
|
122
|
-
fig.savefig(file_path, format=format)
|
123
|
-
|
124
|
-
def modify_figure():
|
125
|
-
def apply_modifications():
|
126
|
-
try:
|
127
|
-
x_width = float(x_width_var.get())
|
128
|
-
y_height = float(y_height_var.get())
|
129
|
-
line_width = float(line_width_var.get())
|
130
|
-
font_size = int(font_size_var.get())
|
131
|
-
modify_figure_properties(fig, x_width=x_width, y_height=y_height, line_width=line_width)
|
132
|
-
for ax in fig.get_axes():
|
133
|
-
for label in ax.get_xticklabels() + ax.get_yticklabels():
|
134
|
-
label.set_fontsize(font_size)
|
135
|
-
ax.title.set_fontsize(font_size)
|
136
|
-
ax.xaxis.label.set_fontsize(font_size)
|
137
|
-
ax.yaxis.label.set_fontsize(font_size)
|
138
|
-
canvas.draw_idle() # Redraw the canvas after modifications
|
139
|
-
except ValueError:
|
140
|
-
print("Invalid input; please enter numeric values.")
|
141
|
-
|
142
|
-
# Create a new window for user input
|
143
|
-
modify_window = tk.Toplevel()
|
144
|
-
modify_window.title("Modify Figure Properties")
|
145
|
-
|
146
|
-
# Apply dark style to the popup window
|
147
|
-
modify_window.configure(bg=bg_color)
|
148
|
-
|
149
|
-
# Create and style the input fields
|
150
|
-
tk.Label(modify_window, text="X Axis Width:", bg=bg_color, fg=fg_color).grid(row=0, column=0, padx=10, pady=5)
|
151
|
-
x_width_var = tk.StringVar()
|
152
|
-
tk.Entry(modify_window, textvariable=x_width_var, bg=bg_color, fg=fg_color).grid(row=0, column=1, padx=10, pady=5)
|
153
|
-
|
154
|
-
tk.Label(modify_window, text="Y Axis Height:", bg=bg_color, fg=fg_color).grid(row=1, column=0, padx=10, pady=5)
|
155
|
-
y_height_var = tk.StringVar()
|
156
|
-
tk.Entry(modify_window, textvariable=y_height_var, bg=bg_color, fg=fg_color).grid(row=1, column=1, padx=10, pady=5)
|
157
|
-
|
158
|
-
tk.Label(modify_window, text="Line Width:", bg=bg_color, fg=fg_color).grid(row=2, column=0, padx=10, pady=5)
|
159
|
-
line_width_var = tk.StringVar()
|
160
|
-
tk.Entry(modify_window, textvariable=line_width_var, bg=bg_color, fg=fg_color).grid(row=2, column=1, padx=10, pady=5)
|
161
|
-
|
162
|
-
tk.Label(modify_window, text="Font Size:", bg=bg_color, fg=fg_color).grid(row=3, column=0, padx=10, pady=5)
|
163
|
-
font_size_var = tk.StringVar()
|
164
|
-
tk.Entry(modify_window, textvariable=font_size_var, bg=bg_color, fg=fg_color).grid(row=3, column=1, padx=10, pady=5)
|
165
|
-
|
166
|
-
# Apply button
|
167
|
-
apply_button = tk.Button(modify_window, text="Apply", command=apply_modifications, bg=bg_color, fg=fg_color)
|
168
|
-
apply_button.grid(row=4, column=0, columnspan=2, pady=10)
|
137
|
+
canvas_widget.configure(bg=bg_color)
|
169
138
|
|
170
139
|
# Create the context menu
|
171
140
|
context_menu = tk.Menu(canvas_widget, tearoff=0, bg=bg_color, fg=fg_color)
|
172
|
-
context_menu.add_command(label="Save Figure as PDF", command=lambda: save_figure_as_format('pdf'))
|
173
|
-
context_menu.add_command(label="Save Figure as PNG", command=lambda: save_figure_as_format('png'))
|
174
|
-
context_menu.add_command(label="Modify Figure", command=modify_figure)
|
141
|
+
context_menu.add_command(label="Save Figure as PDF", command=lambda: save_figure_as_format(fig, 'pdf'))
|
142
|
+
context_menu.add_command(label="Save Figure as PNG", command=lambda: save_figure_as_format(fig, 'png'))
|
143
|
+
context_menu.add_command(label="Modify Figure", command=lambda: modify_figure(fig))
|
144
|
+
context_menu.add_command(label="Reset Zoom", command=lambda: reset_zoom(fig)) # Add Reset Zoom option
|
145
|
+
|
146
|
+
def reset_zoom(fig):
|
147
|
+
global scale_factor
|
148
|
+
scale_factor = 1.0 # Reset the scale factor
|
149
|
+
|
150
|
+
for i, ax in enumerate(fig.get_axes()):
|
151
|
+
ax.set_xlim(original_xlim[i])
|
152
|
+
ax.set_ylim(original_ylim[i])
|
153
|
+
fig.canvas.draw_idle()
|
175
154
|
|
176
155
|
def on_right_click(event):
|
177
156
|
context_menu.post(event.x_root, event.y_root)
|
178
157
|
|
179
|
-
|
158
|
+
def on_hover(event):
|
159
|
+
widget_width = event.widget.winfo_width()
|
160
|
+
x_position = event.x
|
161
|
+
|
162
|
+
if x_position < widget_width / 2:
|
163
|
+
canvas_widget.config(cursor="hand2")
|
164
|
+
else:
|
165
|
+
canvas_widget.config(cursor="hand2")
|
166
|
+
|
167
|
+
def on_leave(event):
|
168
|
+
canvas_widget.config(cursor="arrow")
|
169
|
+
|
170
|
+
def flash_feedback(side):
|
171
|
+
flash = tk.Toplevel(canvas_widget.master)
|
172
|
+
flash.overrideredirect(True)
|
173
|
+
flash_width = int(canvas_widget.winfo_width() / 2)
|
174
|
+
flash_height = canvas_widget.winfo_height()
|
175
|
+
flash.configure(bg='white')
|
176
|
+
flash.attributes('-alpha', 0.9)
|
177
|
+
|
178
|
+
if side == "left":
|
179
|
+
flash.geometry(f"{flash_width}x{flash_height}+{canvas_widget.winfo_rootx()}+{canvas_widget.winfo_rooty()}")
|
180
|
+
else:
|
181
|
+
flash.geometry(f"{flash_width}x{flash_height}+{canvas_widget.winfo_rootx() + flash_width}+{canvas_widget.winfo_rooty()}")
|
182
|
+
|
183
|
+
flash.lift()
|
184
|
+
|
185
|
+
# Ensure the flash covers the correct area only
|
186
|
+
flash.update_idletasks()
|
187
|
+
flash.after(100, flash.destroy)
|
188
|
+
|
189
|
+
def on_click(event):
|
190
|
+
widget_width = event.widget.winfo_width()
|
191
|
+
x_position = event.x
|
192
|
+
|
193
|
+
if x_position < widget_width / 2:
|
194
|
+
#flash_feedback("left")
|
195
|
+
show_previous_figure()
|
196
|
+
else:
|
197
|
+
#flash_feedback("right")
|
198
|
+
show_next_figure()
|
199
|
+
|
200
|
+
def zoom(event):
|
201
|
+
nonlocal scale_factor
|
202
|
+
|
203
|
+
zoom_speed = 0.1 # Adjust the zoom speed for smoother experience
|
204
|
+
|
205
|
+
# Adjust zoom factor based on the operating system and mouse event
|
206
|
+
if event.num == 4 or event.delta > 0: # Scroll up
|
207
|
+
scale_factor *= (1 + zoom_speed)
|
208
|
+
elif event.num == 5 or event.delta < 0: # Scroll down
|
209
|
+
scale_factor /= (1 + zoom_speed)
|
210
|
+
|
211
|
+
# Get mouse position relative to the figure
|
212
|
+
x_mouse, y_mouse = event.x, event.y
|
213
|
+
x_ratio = x_mouse / canvas_widget.winfo_width()
|
214
|
+
y_ratio = y_mouse / canvas_widget.winfo_height()
|
215
|
+
|
216
|
+
for ax in fig.get_axes():
|
217
|
+
xlim = ax.get_xlim()
|
218
|
+
ylim = ax.get_ylim()
|
219
|
+
|
220
|
+
# Calculate the new limits
|
221
|
+
x_center = xlim[0] + x_ratio * (xlim[1] - xlim[0])
|
222
|
+
y_center = ylim[0] + (1 - y_ratio) * (ylim[1] - ylim[0])
|
223
|
+
|
224
|
+
x_range = (xlim[1] - xlim[0]) * scale_factor
|
225
|
+
y_range = (ylim[1] - ylim[0]) * scale_factor
|
226
|
+
|
227
|
+
ax.set_xlim([x_center - x_range * x_ratio, x_center + x_range * (1 - x_ratio)])
|
228
|
+
ax.set_ylim([y_center - y_range * (1 - y_ratio), y_center + y_range * y_ratio])
|
229
|
+
|
230
|
+
# Redraw the figure
|
231
|
+
fig.canvas.draw_idle()
|
232
|
+
|
233
|
+
# Bind events for hover, click interactions, and zoom
|
234
|
+
canvas_widget.bind("<Motion>", on_hover)
|
235
|
+
canvas_widget.bind("<Leave>", on_leave)
|
236
|
+
canvas_widget.bind("<Button-1>", on_click)
|
237
|
+
canvas_widget.bind("<Button-3>", on_right_click)
|
238
|
+
|
239
|
+
# Bind mouse wheel for zooming (cross-platform)
|
240
|
+
canvas_widget.bind("<MouseWheel>", zoom) # Windows
|
241
|
+
canvas_widget.bind("<Button-4>", zoom) # Linux/macOS Scroll Up
|
242
|
+
canvas_widget.bind("<Button-5>", zoom) # Linux/macOS Scroll Down
|
180
243
|
|
181
244
|
def clear_unused_figures():
|
182
245
|
global figures, figure_index
|
183
246
|
|
184
247
|
lower_bound = max(0, figure_index - 20)
|
185
248
|
upper_bound = min(len(figures), figure_index + 20)
|
186
|
-
|
187
249
|
# Clear figures outside of the +/- 20 range
|
188
250
|
figures = deque([fig for i, fig in enumerate(figures) if lower_bound <= i <= upper_bound])
|
189
|
-
|
190
251
|
# Update the figure index after clearing
|
191
252
|
figure_index = min(max(figure_index, 0), len(figures) - 1)
|
192
253
|
|
193
254
|
def show_previous_figure():
|
194
|
-
global figure_index, figures
|
255
|
+
global figure_index, figures, fig_queue
|
195
256
|
if figure_index is not None and figure_index > 0:
|
196
257
|
figure_index -= 1
|
197
258
|
display_figure(figures[figure_index])
|
198
259
|
clear_unused_figures()
|
199
260
|
|
200
261
|
def show_next_figure():
|
201
|
-
global figure_index, figures
|
262
|
+
global figure_index, figures, fig_queue
|
202
263
|
if figure_index is not None and figure_index < len(figures) - 1:
|
203
264
|
figure_index += 1
|
204
265
|
display_figure(figures[figure_index])
|
205
266
|
clear_unused_figures()
|
206
|
-
|
207
|
-
|
208
|
-
|
209
|
-
|
210
|
-
|
211
|
-
fig.savefig(file_path, format=file_format)
|
212
|
-
print(f"Figure saved as {file_format.upper()} at {file_path}")
|
213
|
-
except Exception as e:
|
214
|
-
print(f"Error saving figure: {e}")
|
215
|
-
|
216
|
-
def modify_figure_properties(fig, x_width=None, y_height=None, line_width=None):
|
217
|
-
"""
|
218
|
-
Modifies the properties of the figure, including axis dimensions and line widths.
|
219
|
-
|
220
|
-
Parameters:
|
221
|
-
- fig: The matplotlib figure object to modify.
|
222
|
-
- x_width: Desired width for the x-axis (optional).
|
223
|
-
- y_height: Desired height for the y-axis (optional).
|
224
|
-
- line_width: Desired line width for all lines (optional).
|
225
|
-
"""
|
226
|
-
for ax in fig.get_axes():
|
227
|
-
# Scaling the figure
|
228
|
-
if x_width is not None or y_height is not None:
|
229
|
-
# Get the current axis limits
|
230
|
-
current_xlim = ax.get_xlim()
|
231
|
-
current_ylim = ax.get_ylim()
|
232
|
-
|
233
|
-
# Set new limits
|
234
|
-
if x_width is not None:
|
235
|
-
scale_factor_x = x_width / (current_xlim[1] - current_xlim[0])
|
236
|
-
else:
|
237
|
-
scale_factor_x = 1
|
238
|
-
|
239
|
-
if y_height is not None:
|
240
|
-
scale_factor_y = y_height / (current_ylim[1] - current_ylim[0])
|
241
|
-
else:
|
242
|
-
scale_factor_y = 1
|
243
|
-
|
244
|
-
# Adjust the figure size and elements proportionally
|
245
|
-
fig.set_size_inches(fig.get_size_inches() * scale_factor_x * scale_factor_y, forward=True)
|
246
|
-
ax.set_xlim(left=current_xlim[0] * scale_factor_x, right=current_xlim[1] * scale_factor_x)
|
247
|
-
ax.set_ylim(bottom=current_ylim[0] * scale_factor_y, top=current_ylim[1] * scale_factor_y)
|
248
|
-
|
249
|
-
# Adjust line width and other elements if specified
|
250
|
-
if line_width is not None:
|
251
|
-
for line in ax.get_lines():
|
252
|
-
line.set_linewidth(line_width)
|
253
|
-
for spine in ax.spines.values(): # Modify width of spines (e.g., scale bars)
|
254
|
-
spine.set_linewidth(line_width)
|
255
|
-
ax.tick_params(width=line_width) # Modify width of ticks
|
256
|
-
for text in ax.get_xticklabels() + ax.get_yticklabels():
|
257
|
-
text.set_fontsize(ax.get_xticklabels()[0].get_fontsize())
|
258
|
-
|
259
|
-
fig.canvas.draw_idle()
|
267
|
+
elif figure_index == len(figures) - 1 and not fig_queue.empty():
|
268
|
+
fig = fig_queue.get_nowait()
|
269
|
+
figures.append(fig)
|
270
|
+
figure_index += 1
|
271
|
+
display_figure(fig)
|
260
272
|
|
261
273
|
def set_globals(thread_control_var, q_var, console_output_var, parent_frame_var, vars_dict_var, canvas_var, canvas_widget_var, scrollable_frame_var, fig_queue_var, figures_var, figure_index_var, progress_bar_var, usage_bars_var, fig_memory_limit_var, figure_current_memory_usage_var):
|
262
274
|
global thread_control, q, console_output, parent_frame, vars_dict, canvas, canvas_widget, scrollable_frame, fig_queue, figures, figure_index, progress_bar, usage_bars, fig_memory_limit, figure_current_memory_usage
|
@@ -416,7 +428,7 @@ def setup_plot_section(vertical_container):
|
|
416
428
|
plot_frame.grid_columnconfigure(0, weight=1)
|
417
429
|
|
418
430
|
canvas.draw()
|
419
|
-
canvas.figure = figure
|
431
|
+
canvas.figure = figure # Ensure that the figure is linked to the canvas
|
420
432
|
style_out = set_dark_style(ttk.Style())
|
421
433
|
|
422
434
|
figure.patch.set_facecolor(style_out['bg_color'])
|
@@ -425,19 +437,6 @@ def setup_plot_section(vertical_container):
|
|
425
437
|
widgets = [canvas_widget]
|
426
438
|
style = ttk.Style(vertical_container)
|
427
439
|
_ = set_dark_style(style, containers=containers, widgets=widgets)
|
428
|
-
|
429
|
-
# Add navigation buttons using spacrButton
|
430
|
-
button_frame = tk.Frame(plot_frame, bg=style_out['bg_color'])
|
431
|
-
button_frame.grid(row=1, column=0, sticky='ew', pady=5)
|
432
|
-
|
433
|
-
size_dict = set_element_size()
|
434
|
-
|
435
|
-
btn_size = int(size_dict['btn_size']*0.75)
|
436
|
-
prev_button = spacrButton(button_frame, text="Previous", command=show_previous_figure, bg=style_out['bg_color'], show_text=False, size=btn_size, animation=False)
|
437
|
-
prev_button.pack(side='left', padx=5)
|
438
|
-
|
439
|
-
next_button = spacrButton(button_frame, text="Next", command=show_next_figure, bg=style_out['bg_color'], show_text=False, size=btn_size, animation=False)
|
440
|
-
next_button.pack(side='right', padx=5)
|
441
440
|
|
442
441
|
return canvas, canvas_widget
|
443
442
|
|
@@ -842,7 +841,7 @@ def initiate_root(parent, settings_type='mask'):
|
|
842
841
|
from .gui_utils import setup_frame
|
843
842
|
from .settings import descriptions
|
844
843
|
|
845
|
-
uppdate_frequency =
|
844
|
+
uppdate_frequency = 100
|
846
845
|
|
847
846
|
# Start tracemalloc and initialize global variables
|
848
847
|
tracemalloc.start()
|
spacr/gui_elements.py
CHANGED
@@ -2,6 +2,7 @@ import os, threading, time, sqlite3, webbrowser, pyautogui
|
|
2
2
|
import tkinter as tk
|
3
3
|
from tkinter import ttk
|
4
4
|
import tkinter.font as tkFont
|
5
|
+
from tkinter import filedialog
|
5
6
|
from tkinter import font
|
6
7
|
from queue import Queue
|
7
8
|
from tkinter import Label, Frame, Button
|
@@ -16,6 +17,7 @@ from skimage.draw import polygon, line
|
|
16
17
|
from skimage.transform import resize
|
17
18
|
from scipy.ndimage import binary_fill_holes, label
|
18
19
|
from tkinter import ttk, scrolledtext
|
20
|
+
fig = None
|
19
21
|
|
20
22
|
def set_element_size():
|
21
23
|
|
@@ -2081,6 +2083,7 @@ class AnnotateApp:
|
|
2081
2083
|
print(f"median threshold measurement: {np.median(df[self.measurement])}")
|
2082
2084
|
df = df[df[f'threshold_measurement_{idx}'] > thd]
|
2083
2085
|
after = len(df)
|
2086
|
+
|
2084
2087
|
elif isinstance(self.measurement, list):
|
2085
2088
|
df['threshold_measurement'] = df[self.measurement[0]]/df[self.measurement[1]]
|
2086
2089
|
print(f"mean threshold measurement: {np.mean(df['threshold_measurement'])}")
|
@@ -2089,6 +2092,7 @@ class AnnotateApp:
|
|
2089
2092
|
after = len(df)
|
2090
2093
|
self.measurement = 'threshold_measurement'
|
2091
2094
|
print(f'Removed: {before-after} rows, retained {after}')
|
2095
|
+
|
2092
2096
|
else:
|
2093
2097
|
print(f"mean threshold measurement: {np.mean(df[self.measurement])}")
|
2094
2098
|
print(f"median threshold measurement: {np.median(df[self.measurement])}")
|
@@ -2370,4 +2374,300 @@ def create_menu_bar(root):
|
|
2370
2374
|
app_menu.add_command(label="Exit", command=root.quit)
|
2371
2375
|
|
2372
2376
|
# Configure the menu for the root window
|
2373
|
-
root.config(menu=menu_bar)
|
2377
|
+
root.config(menu=menu_bar)
|
2378
|
+
|
2379
|
+
def standardize_figure(fig):
|
2380
|
+
from .gui_elements import set_dark_style
|
2381
|
+
from matplotlib.font_manager import FontProperties
|
2382
|
+
|
2383
|
+
style_out = set_dark_style(ttk.Style())
|
2384
|
+
bg_color = style_out['bg_color']
|
2385
|
+
fg_color = style_out['fg_color']
|
2386
|
+
font_size = style_out['font_size']
|
2387
|
+
font_loader = style_out['font_loader']
|
2388
|
+
|
2389
|
+
# Get the custom font path from the font loader
|
2390
|
+
font_path = font_loader.font_path
|
2391
|
+
font_prop = FontProperties(fname=font_path, size=font_size)
|
2392
|
+
|
2393
|
+
"""
|
2394
|
+
Standardizes the appearance of the figure:
|
2395
|
+
- Font size: from style
|
2396
|
+
- Font color: from style
|
2397
|
+
- Font family: custom OpenSans from font_loader
|
2398
|
+
- Removes top and right spines
|
2399
|
+
- Figure and subplot background: from style
|
2400
|
+
- Line width: 1
|
2401
|
+
- Line color: from style
|
2402
|
+
"""
|
2403
|
+
|
2404
|
+
for ax in fig.get_axes():
|
2405
|
+
# Set font properties for title and labels
|
2406
|
+
ax.title.set_fontsize(font_size)
|
2407
|
+
ax.title.set_color(fg_color)
|
2408
|
+
ax.title.set_fontproperties(font_prop)
|
2409
|
+
|
2410
|
+
ax.xaxis.label.set_fontsize(font_size)
|
2411
|
+
ax.xaxis.label.set_color(fg_color)
|
2412
|
+
ax.xaxis.label.set_fontproperties(font_prop)
|
2413
|
+
|
2414
|
+
ax.yaxis.label.set_fontsize(font_size)
|
2415
|
+
ax.yaxis.label.set_color(fg_color)
|
2416
|
+
ax.yaxis.label.set_fontproperties(font_prop)
|
2417
|
+
|
2418
|
+
# Set font properties for tick labels
|
2419
|
+
for label in ax.get_xticklabels() + ax.get_yticklabels():
|
2420
|
+
label.set_fontsize(font_size)
|
2421
|
+
label.set_color(fg_color)
|
2422
|
+
label.set_fontproperties(font_prop)
|
2423
|
+
|
2424
|
+
# Remove top and right spines
|
2425
|
+
ax.spines['top'].set_visible(False)
|
2426
|
+
ax.spines['right'].set_visible(False)
|
2427
|
+
ax.spines['left'].set_visible(True)
|
2428
|
+
ax.spines['bottom'].set_visible(True)
|
2429
|
+
|
2430
|
+
# Set spine line width and color
|
2431
|
+
for spine in ax.spines.values():
|
2432
|
+
spine.set_linewidth(1)
|
2433
|
+
spine.set_edgecolor(fg_color)
|
2434
|
+
|
2435
|
+
# Set line width and color
|
2436
|
+
for line in ax.get_lines():
|
2437
|
+
line.set_linewidth(1)
|
2438
|
+
line.set_color(fg_color)
|
2439
|
+
|
2440
|
+
# Set subplot background color
|
2441
|
+
ax.set_facecolor(bg_color)
|
2442
|
+
|
2443
|
+
# Adjust the grid if needed
|
2444
|
+
ax.grid(True, color='gray', linestyle='--', linewidth=0.5)
|
2445
|
+
|
2446
|
+
# Set figure background color
|
2447
|
+
fig.patch.set_facecolor(bg_color)
|
2448
|
+
|
2449
|
+
fig.canvas.draw_idle()
|
2450
|
+
|
2451
|
+
def modify_figure_properties(fig, scale_x=None, scale_y=None, line_width=None, font_size=None, x_lim=None, y_lim=None, grid=False, legend=None, title=None, x_label_rotation=None, remove_axes=False, bg_color=None, text_color=None, line_color=None):
|
2452
|
+
"""
|
2453
|
+
Modifies the properties of the figure, including scaling, line widths, font sizes, axis limits, x-axis label rotation, background color, text color, line color, and other common options.
|
2454
|
+
|
2455
|
+
Parameters:
|
2456
|
+
- fig: The Matplotlib figure object to modify.
|
2457
|
+
- scale_x: Scaling factor for the width of subplots (optional).
|
2458
|
+
- scale_y: Scaling factor for the height of subplots (optional).
|
2459
|
+
- line_width: Desired line width for all lines (optional).
|
2460
|
+
- font_size: Desired font size for all text (optional).
|
2461
|
+
- x_lim: Tuple specifying the x-axis limits (min, max) (optional).
|
2462
|
+
- y_lim: Tuple specifying the y-axis limits (min, max) (optional).
|
2463
|
+
- grid: Boolean to add grid lines to the plot (optional).
|
2464
|
+
- legend: Boolean to show/hide the legend (optional).
|
2465
|
+
- title: String to set as the title of the plot (optional).
|
2466
|
+
- x_label_rotation: Angle to rotate the x-axis labels (optional).
|
2467
|
+
- remove_axes: Boolean to remove or show the axes labels (optional).
|
2468
|
+
- bg_color: Color for the figure and subplot background (optional).
|
2469
|
+
- text_color: Color for all text in the figure (optional).
|
2470
|
+
- line_color: Color for all lines in the figure (optional).
|
2471
|
+
"""
|
2472
|
+
if fig is None:
|
2473
|
+
print("Error: The figure provided is None.")
|
2474
|
+
return
|
2475
|
+
|
2476
|
+
for ax in fig.get_axes():
|
2477
|
+
# Rescale subplots if scaling factors are provided
|
2478
|
+
if scale_x is not None or scale_y is not None:
|
2479
|
+
bbox = ax.get_position()
|
2480
|
+
width = bbox.width * (scale_x if scale_x else 1)
|
2481
|
+
height = bbox.height * (scale_y if scale_y else 1)
|
2482
|
+
new_bbox = [bbox.x0, bbox.y0, width, height]
|
2483
|
+
ax.set_position(new_bbox)
|
2484
|
+
|
2485
|
+
# Set axis limits if provided
|
2486
|
+
if x_lim is not None:
|
2487
|
+
ax.set_xlim(x_lim)
|
2488
|
+
if y_lim is not None:
|
2489
|
+
ax.set_ylim(y_lim)
|
2490
|
+
|
2491
|
+
# Set grid visibility only
|
2492
|
+
ax.grid(grid)
|
2493
|
+
|
2494
|
+
# Adjust line width and color if specified
|
2495
|
+
if line_width is not None or line_color is not None:
|
2496
|
+
for line in ax.get_lines():
|
2497
|
+
if line_width is not None:
|
2498
|
+
line.set_linewidth(line_width)
|
2499
|
+
if line_color is not None:
|
2500
|
+
line.set_color(line_color)
|
2501
|
+
for spine in ax.spines.values(): # Modify width and color of spines (e.g., scale bars)
|
2502
|
+
if line_width is not None:
|
2503
|
+
spine.set_linewidth(line_width)
|
2504
|
+
if line_color is not None:
|
2505
|
+
spine.set_edgecolor(line_color)
|
2506
|
+
ax.tick_params(width=line_width, colors=text_color if text_color else 'black')
|
2507
|
+
|
2508
|
+
# Adjust font size if specified
|
2509
|
+
if font_size is not None:
|
2510
|
+
for label in ax.get_xticklabels() + ax.get_yticklabels():
|
2511
|
+
label.set_fontsize(font_size)
|
2512
|
+
ax.title.set_fontsize(font_size)
|
2513
|
+
ax.xaxis.label.set_fontsize(font_size)
|
2514
|
+
ax.yaxis.label.set_fontsize(font_size)
|
2515
|
+
if ax.legend_:
|
2516
|
+
for text in ax.legend_.get_texts():
|
2517
|
+
text.set_fontsize(font_size)
|
2518
|
+
|
2519
|
+
# Rotate x-axis labels if rotation is specified
|
2520
|
+
if x_label_rotation is not None:
|
2521
|
+
for label in ax.get_xticklabels():
|
2522
|
+
label.set_rotation(x_label_rotation)
|
2523
|
+
if 0 <= x_label_rotation <= 90:
|
2524
|
+
label.set_ha('center')
|
2525
|
+
|
2526
|
+
# Toggle axes labels visibility without affecting the grid or spines
|
2527
|
+
if remove_axes:
|
2528
|
+
ax.xaxis.set_visible(False)
|
2529
|
+
ax.yaxis.set_visible(False)
|
2530
|
+
else:
|
2531
|
+
ax.xaxis.set_visible(True)
|
2532
|
+
ax.yaxis.set_visible(True)
|
2533
|
+
|
2534
|
+
# Set text color if specified
|
2535
|
+
if text_color:
|
2536
|
+
ax.title.set_color(text_color)
|
2537
|
+
ax.xaxis.label.set_color(text_color)
|
2538
|
+
ax.yaxis.label.set_color(text_color)
|
2539
|
+
ax.tick_params(colors=text_color)
|
2540
|
+
for label in ax.get_xticklabels() + ax.get_yticklabels():
|
2541
|
+
label.set_color(text_color)
|
2542
|
+
|
2543
|
+
# Set background color for subplots if specified
|
2544
|
+
if bg_color:
|
2545
|
+
ax.set_facecolor(bg_color)
|
2546
|
+
|
2547
|
+
# Set figure background color if specified
|
2548
|
+
if bg_color:
|
2549
|
+
fig.patch.set_facecolor(bg_color)
|
2550
|
+
|
2551
|
+
fig.canvas.draw_idle()
|
2552
|
+
|
2553
|
+
def save_figure_as_format(fig, file_format):
|
2554
|
+
file_path = filedialog.asksaveasfilename(defaultextension=f".{file_format}", filetypes=[(f"{file_format.upper()} files", f"*.{file_format}"), ("All files", "*.*")])
|
2555
|
+
if file_path:
|
2556
|
+
try:
|
2557
|
+
fig.savefig(file_path, format=file_format)
|
2558
|
+
print(f"Figure saved as {file_format.upper()} at {file_path}")
|
2559
|
+
except Exception as e:
|
2560
|
+
print(f"Error saving figure: {e}")
|
2561
|
+
|
2562
|
+
def modify_figure(fig):
|
2563
|
+
from .gui_core import display_figure
|
2564
|
+
def apply_modifications():
|
2565
|
+
try:
|
2566
|
+
# Only apply changes if the fields are filled
|
2567
|
+
scale_x = float(scale_x_var.get()) if scale_x_var.get() else None
|
2568
|
+
scale_y = float(scale_y_var.get()) if scale_y_var.get() else None
|
2569
|
+
line_width = float(line_width_var.get()) if line_width_var.get() else None
|
2570
|
+
font_size = int(font_size_var.get()) if font_size_var.get() else None
|
2571
|
+
x_lim = eval(x_lim_var.get()) if x_lim_var.get() else None
|
2572
|
+
y_lim = eval(y_lim_var.get()) if y_lim_var.get() else None
|
2573
|
+
title = title_var.get() if title_var.get() else None
|
2574
|
+
bg_color = bg_color_var.get() if bg_color_var.get() else None
|
2575
|
+
text_color = text_color_var.get() if text_color_var.get() else None
|
2576
|
+
line_color = line_color_var.get() if line_color_var.get() else None
|
2577
|
+
x_label_rotation = int(x_label_rotation_var.get()) if x_label_rotation_var.get() else None
|
2578
|
+
|
2579
|
+
modify_figure_properties(
|
2580
|
+
fig,
|
2581
|
+
scale_x=scale_x,
|
2582
|
+
scale_y=scale_y,
|
2583
|
+
line_width=line_width,
|
2584
|
+
font_size=font_size,
|
2585
|
+
x_lim=x_lim,
|
2586
|
+
y_lim=y_lim,
|
2587
|
+
grid=grid_var.get(),
|
2588
|
+
legend=legend_var.get(),
|
2589
|
+
title=title,
|
2590
|
+
x_label_rotation=x_label_rotation,
|
2591
|
+
remove_axes=remove_axes_var.get(),
|
2592
|
+
bg_color=bg_color,
|
2593
|
+
text_color=text_color,
|
2594
|
+
line_color=line_color
|
2595
|
+
)
|
2596
|
+
display_figure(fig)
|
2597
|
+
except ValueError:
|
2598
|
+
print("Invalid input; please enter numeric values.")
|
2599
|
+
|
2600
|
+
def toggle_spleens():
|
2601
|
+
for ax in fig.get_axes():
|
2602
|
+
if spleens_var.get():
|
2603
|
+
ax.spines['top'].set_visible(False)
|
2604
|
+
ax.spines['right'].set_visible(False)
|
2605
|
+
ax.spines['left'].set_visible(True)
|
2606
|
+
ax.spines['bottom'].set_visible(True)
|
2607
|
+
ax.spines['top'].set_linewidth(2)
|
2608
|
+
ax.spines['right'].set_linewidth(2)
|
2609
|
+
else:
|
2610
|
+
ax.spines['top'].set_visible(True)
|
2611
|
+
ax.spines['right'].set_visible(True)
|
2612
|
+
display_figure(fig)
|
2613
|
+
|
2614
|
+
# Create a new window for user input
|
2615
|
+
modify_window = tk.Toplevel()
|
2616
|
+
modify_window.title("Modify Figure Properties")
|
2617
|
+
|
2618
|
+
# Apply dark style to the popup window
|
2619
|
+
style = ttk.Style()
|
2620
|
+
style.configure("TCheckbutton", background="#2E2E2E", foreground="white", selectcolor="blue")
|
2621
|
+
|
2622
|
+
modify_window.configure(bg="#2E2E2E")
|
2623
|
+
|
2624
|
+
# Create and style the input fields
|
2625
|
+
scale_x_var = tk.StringVar()
|
2626
|
+
scale_y_var = tk.StringVar()
|
2627
|
+
line_width_var = tk.StringVar()
|
2628
|
+
font_size_var = tk.StringVar()
|
2629
|
+
x_lim_var = tk.StringVar()
|
2630
|
+
y_lim_var = tk.StringVar()
|
2631
|
+
title_var = tk.StringVar()
|
2632
|
+
bg_color_var = tk.StringVar()
|
2633
|
+
text_color_var = tk.StringVar()
|
2634
|
+
line_color_var = tk.StringVar()
|
2635
|
+
x_label_rotation_var = tk.StringVar()
|
2636
|
+
remove_axes_var = tk.BooleanVar()
|
2637
|
+
grid_var = tk.BooleanVar()
|
2638
|
+
legend_var = tk.BooleanVar()
|
2639
|
+
spleens_var = tk.BooleanVar()
|
2640
|
+
|
2641
|
+
options = [
|
2642
|
+
("Rescale X:", scale_x_var),
|
2643
|
+
("Rescale Y:", scale_y_var),
|
2644
|
+
("Line Width:", line_width_var),
|
2645
|
+
("Font Size:", font_size_var),
|
2646
|
+
("X Axis Limits (tuple):", x_lim_var),
|
2647
|
+
("Y Axis Limits (tuple):", y_lim_var),
|
2648
|
+
("Title:", title_var),
|
2649
|
+
("X Label Rotation (degrees):", x_label_rotation_var),
|
2650
|
+
("Background Color:", bg_color_var),
|
2651
|
+
("Text Color:", text_color_var),
|
2652
|
+
("Line Color:", line_color_var)
|
2653
|
+
]
|
2654
|
+
|
2655
|
+
for i, (label_text, var) in enumerate(options):
|
2656
|
+
tk.Label(modify_window, text=label_text, bg="#2E2E2E", fg="white").grid(row=i, column=0, padx=10, pady=5)
|
2657
|
+
tk.Entry(modify_window, textvariable=var, bg="#2E2E2E", fg="white").grid(row=i, column=1, padx=10, pady=5)
|
2658
|
+
|
2659
|
+
checkboxes = [
|
2660
|
+
("Grid", grid_var),
|
2661
|
+
("Legend", legend_var),
|
2662
|
+
("Spleens", spleens_var),
|
2663
|
+
("Remove Axes", remove_axes_var)
|
2664
|
+
]
|
2665
|
+
|
2666
|
+
for i, (label_text, var) in enumerate(checkboxes, start=len(options)):
|
2667
|
+
ttk.Checkbutton(modify_window, text=label_text, variable=var, style="TCheckbutton").grid(row=i, column=0, padx=10, pady=5, columnspan=2, sticky='w')
|
2668
|
+
|
2669
|
+
spleens_var.trace_add("write", lambda *args: toggle_spleens())
|
2670
|
+
|
2671
|
+
# Apply button
|
2672
|
+
apply_button = tk.Button(modify_window, text="Apply", command=apply_modifications, bg="#2E2E2E", fg="white")
|
2673
|
+
apply_button.grid(row=len(options) + len(checkboxes), column=0, columnspan=2, pady=10)
|
spacr/gui_utils.py
CHANGED
@@ -76,6 +76,18 @@ def load_app(root, app_name, app_func):
|
|
76
76
|
proceed_with_app(root, app_name, app_func)
|
77
77
|
|
78
78
|
def parse_list(value):
|
79
|
+
"""
|
80
|
+
Parses a string representation of a list and returns the parsed list.
|
81
|
+
|
82
|
+
Args:
|
83
|
+
value (str): The string representation of the list.
|
84
|
+
|
85
|
+
Returns:
|
86
|
+
list: The parsed list.
|
87
|
+
|
88
|
+
Raises:
|
89
|
+
ValueError: If the input value is not a valid list format or contains mixed types or unsupported types.
|
90
|
+
"""
|
79
91
|
try:
|
80
92
|
parsed_value = ast.literal_eval(value)
|
81
93
|
if isinstance(parsed_value, list):
|
@@ -93,7 +105,26 @@ def parse_list(value):
|
|
93
105
|
|
94
106
|
# Usage example in your create_input_field function
|
95
107
|
def create_input_field(frame, label_text, row, var_type='entry', options=None, default_value=None):
|
108
|
+
"""
|
109
|
+
Create an input field in the specified frame.
|
110
|
+
|
111
|
+
Args:
|
112
|
+
frame (tk.Frame): The frame in which the input field will be created.
|
113
|
+
label_text (str): The text to be displayed as the label for the input field.
|
114
|
+
row (int): The row in which the input field will be placed.
|
115
|
+
var_type (str, optional): The type of input field to create. Defaults to 'entry'.
|
116
|
+
options (list, optional): The list of options for a combo box input field. Defaults to None.
|
117
|
+
default_value (str, optional): The default value for the input field. Defaults to None.
|
118
|
+
|
119
|
+
Returns:
|
120
|
+
tuple: A tuple containing the label, input widget, variable, and custom frame.
|
121
|
+
|
122
|
+
Raises:
|
123
|
+
Exception: If an error occurs while creating the input field.
|
124
|
+
|
125
|
+
"""
|
96
126
|
from .gui_elements import set_dark_style, set_element_size
|
127
|
+
|
97
128
|
label_column = 0
|
98
129
|
widget_column = 0 # Both label and widget will be in the same column
|
99
130
|
|
@@ -205,6 +236,12 @@ def annotate(settings):
|
|
205
236
|
|
206
237
|
def generate_annotate_fields(frame):
|
207
238
|
from .settings import set_annotate_default_settings
|
239
|
+
from .gui_elements import set_dark_style
|
240
|
+
|
241
|
+
style_out = set_dark_style(ttk.Style())
|
242
|
+
font_loader = style_out['font_loader']
|
243
|
+
font_size = style_out['font_size'] - 2
|
244
|
+
|
208
245
|
vars_dict = {}
|
209
246
|
settings = set_annotate_default_settings(settings={})
|
210
247
|
|
@@ -216,8 +253,8 @@ def generate_annotate_fields(frame):
|
|
216
253
|
|
217
254
|
# Arrange input fields and labels
|
218
255
|
for row, (name, data) in enumerate(vars_dict.items()):
|
219
|
-
|
220
|
-
|
256
|
+
tk.Label(frame, text=f"{name.replace('_', ' ').capitalize()}:", bg=style_out['bg_color'], fg=style_out['fg_color'], font=font_loader.get_font(size=font_size)).grid(row=row, column=0)
|
257
|
+
#ttk.Label(frame, text=f"{name.replace('_', ' ').capitalize()}:", background="black", foreground="white").grid(row=row, column=0)
|
221
258
|
if isinstance(data['value'], list):
|
222
259
|
# Convert lists to comma-separated strings
|
223
260
|
data['entry'].insert(0, ','.join(map(str, data['value'])))
|
spacr/plot.py
CHANGED
@@ -125,7 +125,7 @@ def plot_image_mask_overlay(file, channels, cell_channel, nucleus_channel, patho
|
|
125
125
|
|
126
126
|
return
|
127
127
|
|
128
|
-
def plot_masks(batch, masks, flows, cmap='inferno', figuresize=
|
128
|
+
def plot_masks(batch, masks, flows, cmap='inferno', figuresize=10, nr=1, file_type='.npz', print_object_number=True):
|
129
129
|
"""
|
130
130
|
Plot the masks and flows for a given batch of images.
|
131
131
|
|
@@ -476,7 +476,7 @@ def _filter_objects_in_plot(stack, cell_mask_dim, nucleus_mask_dim, pathogen_mas
|
|
476
476
|
|
477
477
|
return stack
|
478
478
|
|
479
|
-
def plot_arrays(src, figuresize=
|
479
|
+
def plot_arrays(src, figuresize=10, cmap='inferno', nr=1, normalize=True, q1=1, q2=99):
|
480
480
|
"""
|
481
481
|
Plot randomly selected arrays from a given directory.
|
482
482
|
|
@@ -870,7 +870,7 @@ def _save_scimg_plot(src, nr_imgs=16, channel_indices=[0,1,2], um_per_pixel=0.1,
|
|
870
870
|
|
871
871
|
return
|
872
872
|
|
873
|
-
def _plot_cropped_arrays(stack, filename, figuresize=
|
873
|
+
def _plot_cropped_arrays(stack, filename, figuresize=10, cmap='inferno', threshold=500):
|
874
874
|
"""
|
875
875
|
Plot cropped arrays.
|
876
876
|
|
@@ -997,7 +997,7 @@ def _display_gif(path):
|
|
997
997
|
with open(path, 'rb') as file:
|
998
998
|
display(ipyimage(file.read()))
|
999
999
|
|
1000
|
-
def _plot_recruitment(df, df_type, channel_of_interest, target, columns=[], figuresize=
|
1000
|
+
def _plot_recruitment(df, df_type, channel_of_interest, target, columns=[], figuresize=10):
|
1001
1001
|
"""
|
1002
1002
|
Plot recruitment data for different conditions and pathogens.
|
1003
1003
|
|
spacr/sequencing.py
CHANGED
@@ -223,14 +223,10 @@ def save_to_hdf(queue, output_file, complevel=9, compression='zlib'):
|
|
223
223
|
Save data from a queue to an HDF file.
|
224
224
|
|
225
225
|
Parameters:
|
226
|
-
- queue: Queue object
|
227
|
-
|
228
|
-
-
|
229
|
-
|
230
|
-
- complevel: int, optional
|
231
|
-
The compression level to use (default is 9).
|
232
|
-
- compression: str, optional
|
233
|
-
The compression algorithm to use (default is 'zlib').
|
226
|
+
- queue: Queue object containing chunks of data to be saved
|
227
|
+
- output_file: Path to the output HDF file
|
228
|
+
- complevel: Compression level (default: 9)
|
229
|
+
- compression: Compression algorithm (default: 'zlib')
|
234
230
|
|
235
231
|
Returns:
|
236
232
|
None
|
spacr/utils.py
CHANGED
@@ -3451,7 +3451,7 @@ def setup_plot(figuresize, black_background):
|
|
3451
3451
|
fig, ax = plt.subplots(1, 1, figsize=(figuresize, figuresize))
|
3452
3452
|
return fig, ax
|
3453
3453
|
|
3454
|
-
def plot_clusters(ax, embedding, labels, colors, cluster_centers, plot_outlines, plot_points, smooth_lines, figuresize=
|
3454
|
+
def plot_clusters(ax, embedding, labels, colors, cluster_centers, plot_outlines, plot_points, smooth_lines, figuresize=10, dot_size=50, verbose=False):
|
3455
3455
|
unique_labels = np.unique(labels)
|
3456
3456
|
for cluster_label, color, center in zip(unique_labels, colors, cluster_centers):
|
3457
3457
|
cluster_data = embedding[labels == cluster_label]
|
@@ -1,4 +1,4 @@
|
|
1
|
-
spacr/__init__.py,sha256=
|
1
|
+
spacr/__init__.py,sha256=2MqbX2rPedvIqUyAvI5vJ_YGiDeFDF3VU7xSj7TgF5w,1435
|
2
2
|
spacr/__main__.py,sha256=bkAJJD2kjIqOP-u1kLvct9jQQCeUXzlEjdgitwi1Lm8,75
|
3
3
|
spacr/app_annotate.py,sha256=nEIL7Fle9CDKGo3sucG_03DgjUQt5W1M1IHBIpVBr08,2171
|
4
4
|
spacr/app_classify.py,sha256=urTP_wlZ58hSyM5a19slYlBxN0PdC-9-ga0hvq8CGWc,165
|
@@ -12,19 +12,19 @@ spacr/core.py,sha256=IDme9j7eeC_49KGaNk_xPOKtpxdcXKMhYtoo3xhjQMM,146502
|
|
12
12
|
spacr/deep_spacr.py,sha256=a2YewgkQvLV-95NYJAutnojvJmX4S8z_wv6Tb-XIgUI,34484
|
13
13
|
spacr/graph_learning.py,sha256=1tR-ZxvXE3dBz1Saw7BeVFcrsUFu9OlUZeZVifih9eo,13070
|
14
14
|
spacr/gui.py,sha256=dSEQhzZgIOT7SOonbIp07-zXcLaEt6M7sRiIREpDv64,7226
|
15
|
-
spacr/gui_core.py,sha256=
|
16
|
-
spacr/gui_elements.py,sha256=
|
17
|
-
spacr/gui_utils.py,sha256=
|
15
|
+
spacr/gui_core.py,sha256=HXeMfvthY_G371o84Dcr59VLT6AOKQF8r_V9kVzg7h0,38745
|
16
|
+
spacr/gui_elements.py,sha256=7YLyIeK5JFqzevzEruvfQOrfDGOS9ZgD8ZE-dxywp3g,122706
|
17
|
+
spacr/gui_utils.py,sha256=1pZ9QAh6BCVb6BSXciU0V9qFWOSsTtCiC72iGXUdV0c,29941
|
18
18
|
spacr/io.py,sha256=ZtVNbEom8X8p_KfsuWw0glGwLg6S0CfwwevDPGdfiSc,117342
|
19
19
|
spacr/logger.py,sha256=7Zqr3TuuOQLWT32gYr2q1qvv7x0a2JhLANmZcnBXAW8,670
|
20
20
|
spacr/measure.py,sha256=4rmzH_a5Y0s1qALVi6YRut3xpnkJXs5vzeTPCEf3QS8,54871
|
21
|
-
spacr/plot.py,sha256=
|
22
|
-
spacr/sequencing.py,sha256=
|
21
|
+
spacr/plot.py,sha256=xVnbML7WpAEzdJdrLeYRk6aPinZSiV2dLAeu4mh7n0k,73963
|
22
|
+
spacr/sequencing.py,sha256=y7EB8226B0b0gnGXt6jqBaFVATrM1Y89v3rtHb8XR_k,75746
|
23
23
|
spacr/settings.py,sha256=tDvTBWANeuI6YC_fH5vK2HOOuRgQXIkzyNKDmt1vL4c,67745
|
24
24
|
spacr/sim.py,sha256=FveaVgBi3eypO2oVB5Dx-v0CC1Ny7UPfXkJiiRRodAk,71212
|
25
25
|
spacr/sim_app.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
26
26
|
spacr/timelapse.py,sha256=KMYCgHzf9LTZe-lWl5mvH2EjbKRE6OhpwdY13wEumGc,39504
|
27
|
-
spacr/utils.py,sha256=
|
27
|
+
spacr/utils.py,sha256=5Njrrdhd37Tq09W1cm32941AHmlKrAZiODJGUfOwdCQ,188733
|
28
28
|
spacr/version.py,sha256=axH5tnGwtgSnJHb5IDhiu4Zjk5GhLyAEDRe-rnaoFOA,409
|
29
29
|
spacr/resources/font/open_sans/OFL.txt,sha256=bGMoWBRrE2RcdzDiuYiB8A9OVFlJ0sA2imWwce2DAdo,4484
|
30
30
|
"spacr/resources/font/open_sans/OpenSans-Italic-VariableFont_wdth,wght.ttf",sha256=QSoWv9h46CRX_fdlqFM3O2d3-PF3R1srnb4zUezcLm0,580280
|
@@ -92,9 +92,9 @@ spacr/resources/icons/umap.png,sha256=dOLF3DeLYy9k0nkUybiZMe1wzHQwLJFRmgccppw-8b
|
|
92
92
|
spacr/resources/models/cp/toxo_plaque_cyto_e25000_X1120_Y1120.CP_model,sha256=z8BbHWZPRnE9D_BHO0fBREE85c1vkltDs-incs2ytXQ,26566572
|
93
93
|
spacr/resources/models/cp/toxo_plaque_cyto_e25000_X1120_Y1120.CP_model_settings.csv,sha256=fBAGuL_B8ERVdVizO3BHozTDSbZUh1yFzsYK3wkQN68,420
|
94
94
|
spacr/resources/models/cp/toxo_pv_lumen.CP_model,sha256=2y_CindYhmTvVwBH39SNILF3rI3x9SsRn6qrMxHy3l0,26562451
|
95
|
-
spacr-0.2.
|
96
|
-
spacr-0.2.
|
97
|
-
spacr-0.2.
|
98
|
-
spacr-0.2.
|
99
|
-
spacr-0.2.
|
100
|
-
spacr-0.2.
|
95
|
+
spacr-0.2.65.dist-info/LICENSE,sha256=SR-2MeGc6SCM1UORJYyarSWY_A-JaOMFDj7ReSs9tRM,1083
|
96
|
+
spacr-0.2.65.dist-info/METADATA,sha256=M3kT-VwVosUDjXQ9wd6Pux639rG28yhsjVF9eOdx4OI,5259
|
97
|
+
spacr-0.2.65.dist-info/WHEEL,sha256=GJ7t_kWBFywbagK5eo9IoUwLW6oyOeTKmQ-9iHFVNxQ,92
|
98
|
+
spacr-0.2.65.dist-info/entry_points.txt,sha256=BMC0ql9aNNpv8lUZ8sgDLQMsqaVnX5L535gEhKUP5ho,296
|
99
|
+
spacr-0.2.65.dist-info/top_level.txt,sha256=GJPU8FgwRXGzKeut6JopsSRY2R8T3i9lDgya42tLInY,6
|
100
|
+
spacr-0.2.65.dist-info/RECORD,,
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|