-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathvisualizer.py
186 lines (149 loc) · 8.29 KB
/
visualizer.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
import matplotlib.pyplot as plt
import argparse
import yielder as yld
### Plotting
def plot_single_neuron(neuron, file, pad, custom_des, transpone):
'''Plot single chosen neuron from dataset or produce sequence of chosen neurons. '''
min_x, max_x, min_y, max_y = float('inf'), float('-inf'), float('inf'), float('-inf') # for graph adjusting
neuron, x_coords, y_coords = yld.harvest_neuron_points(neuron, file)
if len(x_coords) < 3 and len(y_coords) < 3 and x_coords and y_coords:
print('Neuron', neuron,'is too short for processing! Contains only', len(x_coords), 'point(s).')
return False
else:
try:
min_x, _, min_y, _ = yld.find_min_and_max_values(x_coords, y_coords, min_x, max_x, min_y, max_y)
neuron, x_crds_norm, y_crds_norm = yld.normalize_point_data(neuron, min_x, min_y, file, transpone)
print('Processed neuron:', neuron, 'from file:', file)
except ValueError:
print('Neuron not found:', neuron, 'in file:', file)
return False
plt.plot(x_crds_norm, y_crds_norm)
plt.axis([0-pad, max(x_crds_norm)+pad, 0-pad, max(y_crds_norm)+pad])
plt.xlabel('microns')
plt.ylabel('microns')
if custom_des:
title_ = input("Write graph title: ")
plt.title(title_)
else:
plt.title('Neuron {}'.format(neuron))
plt.show()
def plot_neurons_sequentially(from_num, to_num, file, pad, custom_des, transpone):
'''Invoke plot_single_neuron for sequential plotting of choosen range of neurons. '''
for neuron in range(from_num, to_num+1):
plot_single_neuron(neuron, file, pad, custom_des, transpone)
def plot_range_of_neurons(*args, file, mode, pad):
'''Plot range or group of neurons together on graph. '''
if mode == 'range':
group = range(*(args[0], args[1] + 1)) # for range including last neuron
elif mode == 'group':
group = args
else:
print('Wrong usage. Check range numbers.')
return False
min_x, max_x, min_y, max_y = yld.iterate_for_min_and_max_values(group, file)
for neuron in group:
try:
_, x_crds, y_crds = yld.normalize_point_data(neuron, min_x, min_y, file, transpone=False)
plt.plot(x_crds, y_crds)
except ValueError:
continue
plt.axis([0-pad, max_x-min_x+pad, 0-pad, max_y-min_y+pad]) # adjust axes with provided padding + data are non-normalized (max-min)
plt.xlabel('microns')
plt.ylabel('microns')
title_ = input("Write graph title: ")
plt.title(title_)
plt.show()
def mode_decider(args, mode):
'''Process neuron argumets based on mode. '''
if mode == 'range' and len(args[0]) == 2 and len(args[1]) == 2:
first_source = (args[0][0], tuple(args[0])[1] + 1) # for range including last neuron
second_source = (args[1][0], tuple(args[1])[1] + 1)
group = range(*first_source), range(*second_source)
elif mode == 'group':
group = args
else:
print('Wrong usage. Check range numbers.')
return False
return group
def plot_both_groups_neurons(*args, file, file2, mode, pad, custom_des):
'''Plotting neurons from two files for comparation. '''
group = mode_decider(args, mode)
_, axs = plt.subplots(1, 2, sharex=True, sharey=True)
min_x, min_y = float('inf'), float('inf')
max_x_, max_y_ = float('-inf'), float('-inf')
for number, file_name in enumerate((file, file2)):
min_x, _, min_y, _ = yld.iterate_for_min_and_max_values(group[number], file_name)
for neuron in group[number]:
try:
neuron, x_crds, y_crds = yld.normalize_point_data(neuron, min_x, min_y, file_name, transpone=False)
axs[number].plot(x_crds, y_crds)
max_x_ = max(x_crds) if max(x_crds) > max_x_ else max_x_ # max needed from semi-normalized data
max_y_ = max(y_crds) if max(y_crds) > max_y_ else max_y_
except ValueError:
continue
if custom_des:
name = input('Write description for ' + str(number+1) + '. group of neurons: ')
axs[number].set_title(name)
else:
axs[number].set_title(file_name)
if number == 0: axs[number].set(ylabel = 'microns', xlabel = 'microns') # exclude y label for second graph
else: axs[number].set(xlabel = 'microns')
plt.sca(axs[0])
min_x, min_y = float('inf'), float('inf') # reinitialize min values for second group
plt.axis([0-pad, max_x_+pad, 0-pad, max_y_+pad]) # adjust axes with provided padding
plt.show()
# Control
def cmd_control():
'''Command line user interface. '''
parser = argparse.ArgumentParser(description='Providing arguments for selective neuron graph plotting.')
parser.add_argument('-f', '--filename',
help='Csv source of data. Structure: second column neuron number, third and fourth x,y coordinates.',
type=str, required=True, dest='filename')
parser.add_argument('-f2', '--filename2',
help='Second csv source of data. Structure: second column neuron number, third and fourth x,y coordinates.',
type=str, required=False, dest='filename2')
parser.add_argument('-m', '--mode',
help='Options: [ single | burst | range | group ]',
type=str, required=True, dest='mode')
####
parser.add_argument('-n', '--neuron_first',
help='Neurons from first file. Modes: [ single (int) | burst (from int, to int) | range (from int, to int) | group (arbitrary int(s)) ]',
nargs='*', type=int, required=True, dest='neuron_first')
parser.add_argument('-n2', '--neuron_other',
help='Neurons from second file. Modes: [ range (from int, to int) | group (arbitrary int(s)) ]',
nargs='*', type=int, dest='neuron_second')
####
parser.add_argument('-t', '--transpone',
help='Transpone neuron for burst or single mode from / to \\ if needed.',
type=bool, required=False, dest='transpone', default=False)
parser.add_argument('-p', '--padding',
help='Adjusting space around neuron(s) in graph. Default=20px',
type=int, required=False, dest='padding', default=20)
parser.add_argument('-d', '--description',
help='Choosing custom description.',
type=bool, required=False, dest='description', default=False)
return parser
def execute_commands():
'''Executing cmd user input. '''
parser = cmd_control()
args = parser.parse_args()
try:
if args.filename and args.filename2:
args_ = (args.neuron_first, ) + (args.neuron_second, )
plot_both_groups_neurons(*args_, file=args.filename, file2=args.filename2, mode=args.mode, pad=args.padding, custom_des=args.description)
else:
if args.mode == 'single':
plot_single_neuron(*args.neuron_first, args.filename, args.padding, args.description, args.transpone)
elif args.mode == 'burst' and len(args.neuron_first) == 2 and args.neuron_first[0] < args.neuron_first[1]:
plot_neurons_sequentially(*args.neuron_first, args.filename, args.padding, args.description, args.transpone)
elif args.mode == 'range' and len(args.neuron_first) == 2 and args.neuron_first[0] < args.neuron_first[1]:
plot_range_of_neurons(*args.neuron_first, file=args.filename, mode=args.mode, pad=args.padding) # decription always
elif args.mode == 'group':
args_ = tuple(args.neuron_first)
plot_range_of_neurons(*args_, file=args.filename, mode=args.mode, pad=args.padding) # decription always
else:
print('Wrong usage. Check command line arguments.')
except TypeError:
print('Wrong usage. Check command line arguments.')
if __name__ == "__main__":
execute_commands()