comparison dpmix_plot.py @ 31:a631c2f6d913

Update to Miller Lab devshed revision 3c4110ffacc3
author Richard Burhans <burhans@bx.psu.edu>
date Fri, 20 Sep 2013 13:25:27 -0400
parents 8997f2ca8c7a
children
comparison
equal deleted inserted replaced
30:4188853b940b 31:a631c2f6d913
1 #!/usr/bin/env python 1 #!/usr/bin/env python
2 2
3 import os 3 import os
4 import sys 4 import sys
5 import math 5 import math
6
6 import matplotlib as mpl 7 import matplotlib as mpl
7 mpl.use('PDF') 8 mpl.use('PDF')
9 from matplotlib.backends.backend_pdf import PdfPages
8 import matplotlib.pyplot as plt 10 import matplotlib.pyplot as plt
9 from matplotlib.path import Path 11 from matplotlib.path import Path
10 import matplotlib.patches as patches 12 import matplotlib.patches as patches
11 13
12 ################################################################################ 14 ################################################################################
224 # labels.append('{0:.1f}'.format(vals[-1]/math.pow(10, digits))) 226 # labels.append('{0:.1f}'.format(vals[-1]/math.pow(10, digits)))
225 227
226 return vals, labels 228 return vals, labels
227 229
228 ################################################################################ 230 ################################################################################
231 ################################################################################
232 ################################################################################
233 ################################################################################
234
235 def space_for_legend(plot_params):
236 space = 0.0
237
238 legend_states = plot_params['legend_states']
239 if legend_states:
240 ind_space = plot_params['ind_space']
241 ind_height = plot_params['ind_height']
242 space += len(legend_states) * (ind_space + ind_height) - ind_space
243
244 return space
245
246 ################################################################################
247
248 def space_for_chroms(plot_params, chroms, individuals, data):
249 space_dict = {}
250
251 chrom_height = plot_params['chrom_height']
252 ind_space = plot_params['ind_space']
253 ind_height = plot_params['ind_height']
254
255 for chrom in chroms:
256 space_dict[chrom] = chrom_height
257
258 individual_count = 0
259 for individual in individuals:
260 if individual in data[chrom]:
261 individual_count += 1
262
263 space_dict[chrom] += individual_count * (ind_space + ind_height)
264
265 return space_dict
266
267 ################################################################################
229 268
230 def make_dpmix_plot(input_dbkey, input_file, output_file, galaxy_data_index_dir, state2name=None, populations=3): 269 def make_dpmix_plot(input_dbkey, input_file, output_file, galaxy_data_index_dir, state2name=None, populations=3):
231 fs_chrom_len = build_chrom_len_dict(input_dbkey, galaxy_data_index_dir) 270 fs_chrom_len = build_chrom_len_dict(input_dbkey, galaxy_data_index_dir)
232 chroms, individuals, data, chrom_len, used_states = parse_input_file(input_file) 271 chroms, individuals, data, chrom_len, used_states = parse_input_file(input_file)
233 272
234 if populations == 3: 273 ## populate chrom_len
235 make_state_rectangle = make_state_rectangle_3pop
236 elif populations == 2:
237 make_state_rectangle = make_state_rectangle_2pop
238 else:
239 pass
240
241 for chrom in chrom_len.keys(): 274 for chrom in chrom_len.keys():
242 if chrom in fs_chrom_len: 275 if chrom in fs_chrom_len:
243 chrom_len[chrom] = fs_chrom_len[chrom] 276 chrom_len[chrom] = fs_chrom_len[chrom]
244 277
245 #check_chroms(chroms, chrom_len, input_dbkey) 278 #check_chroms(chroms, chrom_len, input_dbkey)
246 check_data(data, chrom_len, input_dbkey) 279 check_data(data, chrom_len, input_dbkey)
247 280
248 ## units below are inches 281 ## plot parameters
249 top_space = 0.10 282 plot_params = {
250 chrom_space = 0.25 283 'plot_dpi': 300,
251 chrom_height = 0.25 284 'page_width': 8.50,
252 ind_space = 0.10 285 'page_height': 11.00,
253 ind_height = 0.25 286 'top_margin': 0.10,
254 287 'bottom_margin': 0.10,
255 total_height = 0.0 288 'chrom_space': 0.25,
256 289 'chrom_height': 0.25,
257 ## make a legend 290 'ind_space': 0.10,
258 ## only print out states that are 291 'ind_height': 0.25,
292 'legend_space': 0.10
293 }
294
295 ## in the legend, only print out states that are
259 ## 1) in the data 296 ## 1) in the data
260 ## - AND - 297 ## - AND -
261 ## 2) in the state2name map 298 ## 2) in the state2name map
262 ## here, we only calculate the space needed
263 legend_states = [] 299 legend_states = []
264 if state2name is not None: 300 if state2name is not None:
265 for state in used_states: 301 for state in used_states:
266 if state in state2name: 302 if state in state2name:
267 legend_states.append(state) 303 legend_states.append(state)
268 304
269 if legend_states: 305 plot_params['legend_states'] = legend_states
270 total_height += len(legend_states) * (ind_space + ind_height) 306
271 total_height += (top_space - ind_space) 307 ## choose the correct make_state_rectangle method
272 at_top = False 308 if populations == 3:
273 else: 309 plot_params['rectangle_method'] = make_state_rectangle_3pop
274 at_top = True 310 elif populations == 2:
275 311 plot_params['rectangle_method'] = make_state_rectangle_2pop
276 for chrom in chroms: 312
277 if at_top: 313 pdf_pages = PdfPages(output_file)
278 total_height += (top_space + chrom_height) 314
279 at_top = False 315 ## generate a list of chroms for each page
316
317 needed_for_legend = space_for_legend(plot_params)
318 needed_for_chroms = space_for_chroms(plot_params, chroms, individuals, data)
319
320 chrom_space_per_page = plot_params['page_height']
321 chrom_space_per_page -= plot_params['top_margin'] + plot_params['bottom_margin']
322 chrom_space_per_page -= needed_for_legend + plot_params['legend_space']
323 chrom_space_per_page -= plot_params['chrom_space']
324
325 chroms_left = chroms[:]
326 pages = []
327
328 space_left = chrom_space_per_page
329 chrom_list = []
330
331 while chroms_left:
332 chrom = chroms_left.pop(0)
333 space_needed = needed_for_chroms[chrom] + plot_params['chrom_space']
334 if (space_needed > chrom_space_per_page):
335 print >> sys.stderr, 'Multipage chroms not yet supported'
336 sys.exit(1)
337
338 ## sometimes 1.9 - 1.9 < 0 (-4.4408920985e-16)
339 ## so, we make sure it's not more than a millimeter over
340 if space_left - space_needed > -0.04:
341 chrom_list.append(chrom)
342 space_left -= space_needed
280 else: 343 else:
281 total_height += (top_space + chrom_space + chrom_height) 344 pages.append(chrom_list[:])
282 345 chrom_list = []
283 individual_count = 0 346 chroms_left.insert(0, chrom)
284 for individual in individuals: 347 space_left = chrom_space_per_page
285 if individual in data[chrom]: 348
286 individual_count += 1 349 ############################################################################
287 total_height += individual_count * (ind_space + ind_height) 350
288 351 plot_dpi = plot_params['plot_dpi']
289 width = 7.5 352 page_width = plot_params['page_width']
290 height = math.ceil(total_height) 353 page_height = plot_params['page_height']
291 354 top_margin = plot_params['top_margin']
292 bottom = 1.0 355 ind_space = plot_params['ind_space']
293 356 ind_height = plot_params['ind_height']
294 fig = plt.figure(figsize=(width, height)) 357 make_state_rectangle = plot_params['rectangle_method']
295 358 legend_space = plot_params['legend_space']
296 if legend_states: 359 chrom_space = plot_params['chrom_space']
297 at_top = True 360 chrom_height = plot_params['chrom_height']
298 for state in sorted(legend_states): 361
299 if at_top: 362 for page in pages:
300 bottom -= (top_space + ind_height)/height 363 fig = plt.figure(figsize=(page_width, page_height), dpi=plot_dpi)
301 at_top = False 364 bottom = 1.0 - (top_margin/page_height)
365
366 # print legend
367 if legend_states:
368 top = True
369 for state in sorted(legend_states):
370 if top:
371 bottom -= ind_height/page_height
372 top = False
373 else:
374 bottom -= (ind_space + ind_height)/page_height
375
376 ax1 = fig.add_axes([0.0, bottom, 0.09, ind_height/page_height])
377 plt.axis('off')
378 ax1.set_xlim(0, 1)
379 ax1.set_ylim(0, 1)
380 for patch in make_state_rectangle(0, 1, state, 'legend', state2name[state]):
381 ax1.add_patch(patch)
382
383 ax2 = fig.add_axes([0.10, bottom, 0.88, ind_height/page_height], frame_on=False)
384 plt.axis('off')
385 plt.text(0.0, 0.5, state2name[state], fontsize=10, ha='left', va='center')
386
387 bottom -= legend_space/page_height
388
389 # print chroms
390 top = True
391 for chrom in page:
392 length = chrom_len[chrom]
393 vals, labels = tick_foo(0, length)
394
395 if top:
396 bottom -= chrom_height/page_height
397 top = False
302 else: 398 else:
303 bottom -= (ind_space + ind_height)/height 399 bottom -= (chrom_space + chrom_height)/page_height
304 ## add code here to draw legend 400
305 # [left, bottom, width, height] 401 ax = fig.add_axes([0.0, bottom, 1.0, chrom_height/page_height])
306 ax1 = fig.add_axes([0.0, bottom, 0.09, ind_height/height])
307 plt.axis('off')
308 ax1.set_xlim(0, 1)
309 ax1.set_ylim(0, 1)
310 for patch in make_state_rectangle(0, 1, state, 'legend', state2name[state]):
311 ax1.add_patch(patch)
312
313 ax2 = fig.add_axes([0.10, bottom, 0.88, ind_height/height], frame_on=False)
314 plt.axis('off')
315 plt.text(0.0, 0.5, state2name[state], fontsize=10, ha='left', va='center')
316 else:
317 at_top = True
318
319 for_webb = False
320
321 for chrom in chroms:
322 length = chrom_len[chrom]
323 vals, labels = tick_foo(0, length)
324
325 if at_top:
326 bottom -= (top_space + chrom_height)/height
327 at_top = False
328 else:
329 bottom -= (top_space + chrom_space + chrom_height)/height
330
331 if not for_webb:
332 ax = fig.add_axes([0.0, bottom, 1.0, chrom_height/height])
333 plt.axis('off') 402 plt.axis('off')
334 plt.text(0.5, 0.5, chrom, fontsize=14, ha='center') 403 plt.text(0.5, 0.5, chrom, fontsize=14, ha='center')
335 404
336 individual_count = 0 405 individual_count = 0
337 for individual in individuals: 406 for individual in individuals:
338 if individual in data[chrom]: 407 if individual in data[chrom]:
339 individual_count += 1 408 individual_count += 1
340 409
341 i = 0 410 i = 0
342 for individual in individuals: 411 for individual in individuals:
343 if individual in data[chrom]: 412 if individual in data[chrom]:
344 i += 1 413 i += 1
345 414 bottom -= (ind_space + ind_height)/page_height
346 bottom -= (ind_space + ind_height)/height 415
347 if not for_webb: 416 ax1 = fig.add_axes([0.0, bottom, 0.09, ind_height/page_height])
348 # [left, bottom, width, height]
349 ax1 = fig.add_axes([0.0, bottom, 0.09, ind_height/height])
350 plt.axis('off') 417 plt.axis('off')
351 plt.text(1.0, 0.5, individual, fontsize=10, ha='right', va='center') 418 plt.text(1.0, 0.5, individual, fontsize=10, ha='right', va='center')
352 # [left, bottom, width, height] 419
353 ax2 = fig.add_axes([0.10, bottom, 0.88, ind_height/height], frame_on=False) 420 ax2 = fig.add_axes([0.10, bottom, 0.88, ind_height/page_height], frame_on=False)
354 ax2.set_xlim(0, length) 421 ax2.set_xlim(0, length)
355 ax2.set_ylim(0, 1) 422 ax2.set_ylim(0, 1)
356 if i != individual_count: 423
357 plt.axis('off') 424 if i != individual_count:
358 else: 425 plt.axis('off')
359 if not for_webb: 426 else:
360 ax2.tick_params(top=False, left=False, right=False, labelleft=False) 427 ax2.tick_params(top=False, left=False, right=False, labelleft=False)
361 ax2.set_xticks(vals) 428 ax2.set_xticks(vals)
362 ax2.set_xticklabels(labels) 429 ax2.set_xticklabels(labels)
363 else: 430
364 plt.axis('off') 431 for p1, p2, state in sorted(data[chrom][individual]):
365 for p1, p2, state in sorted(data[chrom][individual]): 432 for patch in make_state_rectangle(p1, p2, state, chrom, individual):
366 #for patch in make_state_rectangle(p1, p2, state, chrom, individual): 433 ax2.add_patch(patch)
367 for patch in make_state_rectangle(p1, p2, state, chrom, individual): 434
368 ax2.add_patch(patch) 435 # extend last state to end of chrom
369 436 if p2 < length:
370 plt.savefig(output_file) 437 for patch in make_state_rectangle(p2, length, state, chrom, individual):
438 ax2.add_patch(patch)
439
440
441 pdf_pages.savefig(fig)
442 plt.close(fig)
443
444 pdf_pages.close()
371 445
372 ################################################################################ 446 ################################################################################
373 447
374 if __name__ == '__main__': 448 if __name__ == '__main__':
375 input_dbkey, input_file, output_file, galaxy_data_index_dir = sys.argv[1:5] 449 make_dpmix_plot('loxAfr3', 'output.dat', 'output2_files/picture.pdf', '/scratch/galaxy/home/oocyte/galaxy_oocyte/tool-data', state2name={0: 'heterochromatin', 1: 'reference', 2: 'asian'}, populations=2)
376 make_dpmix_plot(input_dbkey, input_file, output_file, galaxy_data_index_dir) 450 # input_dbkey, input_file, output_file, galaxy_data_index_dir = sys.argv[1:5]
451 # make_dpmix_plot(input_dbkey, input_file, output_file, galaxy_data_index_dir)
377 sys.exit(0) 452 sys.exit(0)
378 453
379 ## notes 454 ## notes
380 # 1) pass in a state to name mapping 455 # 1) pass in a state to name mapping
381 # 2) only print out names for states which exist in the data, and are in the state to name mapping 456 # 2) only print out names for states which exist in the data, and are in the state to name mapping