@@ -664,6 +664,10 @@ def plot_density(
664664
665665 ax .fill_between (x , y1 , y2 = y2 , color = color , lw = 0 , step = "post" , rasterized = raster )
666666
667+ if data .strand_aware :
668+ max_used_y_val = max (abs (min_used_y_val ), max_used_y_val )
669+ min_used_y_val = - max (abs (min_used_y_val ), max_used_y_val ) if data .minus is not None else 0
670+
667671 if jxns :
668672 # sort the junctions by intron length for better plotting look
669673 jxns_sorted_list = sorted (jxns .keys (), key = lambda x : (x .end - x .start , x .start , x .end ), reverse = True )
@@ -675,15 +679,22 @@ def plot_density(
675679 min_junction_count = min (jxns .values ())
676680 junction_count_gap = max_junction_count - min_junction_count
677681
682+ recorded_pts = set ()
678683 jxn_numbers = []
679- for plotted_count , jxn in enumerate (jxns_sorted_list ):
684+ for jxn in jxns_sorted_list :
685+ logger .debug (f"junctions of { y_label } : { jxn } - { round (jxns [jxn ], 2 )} " )
680686 leftss , rightss = jxn .start , jxn .end
681687
688+ # junction must at least have one anchor located in plotted region
689+ if (leftss < region .start and rightss > region .end ) or rightss < region .start or leftss > region .end :
690+ logger .warning (f"junction { jxn } of { y_label } is is out of plotting region, skip" )
691+ continue
692+
682693 # @2022.09.26
683694 # Skip these too short span junction for avoiding plotting junction number
684- overlap_length = min (rightss , region .end ) - max (leftss , region .start ) + 1
685- if not overlap_length / len (region ) > 0.5 and not overlap_length / len (jxns ) > 0.5 :
686- continue
695+ # overlap_length = min(rightss, region.end) - max(leftss, region.start) + 1
696+ # if not overlap_length / len(region) > 0.5 and not overlap_length / len(jxns) > 0.5:
697+ # continue
687698
688699 # @2018.12.19
689700 # set junctions coordinate here
@@ -695,27 +706,47 @@ def plot_density(
695706 add two new variables to make it clear which one is index, which one is genomic site
696707 """
697708 ss1 , ss2 = graph_coords [ss1_idx ], graph_coords [ss2_idx ]
709+
698710 # draw junction on bottom
699- if plotted_count % 2 == 0 :
711+ if jxn . strand == "-" and kwargs . get ( "density_by_strand" ) :
700712 current_height = abs (3 * min_used_y_val / 4 )
701713 left_dens , right_dens = abs (data .curr_min (ss1_idx )), abs (data .curr_min (ss2_idx ))
702714 pts = [
703- ( ss1 , - left_dens if not ss1_modified else - left_dens - current_height ) ,
704- ( ss1 , - current_height ) ,
705- ( ss2 , - current_height ) ,
706- ( ss2 , - right_dens if not ss2_modified else - right_dens - current_height )
715+ - left_dens if not ss1_modified else - left_dens - current_height ,
716+ - left_dens - current_height ,
717+ - right_dens - current_height ,
718+ - right_dens if not ss2_modified else - right_dens - current_height
707719 ]
708720 # draw junction on top
709721 else :
710722 current_height = abs (3 * max_used_y_val / 4 )
711723 left_dens , right_dens = data .curr_max (ss1_idx ), data .curr_max (ss2_idx )
712724 pts = [
713- ( ss1 , left_dens if not ss1_modified else left_dens + current_height ) ,
714- ( ss1 , left_dens + current_height ) ,
715- ( ss2 , right_dens + current_height ) ,
716- ( ss2 , right_dens if not ss2_modified else right_dens + current_height )
725+ left_dens if not ss1_modified else left_dens + current_height ,
726+ left_dens + current_height ,
727+ right_dens + current_height ,
728+ right_dens if not ss2_modified else right_dens + current_height
717729 ]
718730
731+ pts_ = "_" .join ([str (x ) for x in pts ])
732+ while pts_ in recorded_pts :
733+ pts [1 ], pts [2 ] = pts [1 ] * 1.1 , pts [2 ] * 1.1
734+ pts_ = "_" .join ([str (x ) for x in pts ])
735+ recorded_pts .add (pts_ )
736+
737+ """
738+ @2018.12.26
739+ scale the junctions line width
740+ """
741+ if junction_count_gap > 0 :
742+ line_width = (jxns [jxn ] - min_junction_count ) / junction_count_gap
743+ else :
744+ line_width = 0
745+
746+ pts = [(ss1 , pts [0 ]), (ss1 , pts [1 ]), (ss2 , pts [2 ]), (ss2 , pts [3 ])]
747+ ax .add_patch (PathPatch (Path (pts , [Path .MOVETO , Path .CURVE4 , Path .CURVE4 , Path .CURVE4 ]),
748+ ec = color , lw = line_width + 0.2 , fc = 'none' ))
749+
719750 if show_junction_number :
720751 midpt = cubic_bezier (pts , .5 )
721752
@@ -731,33 +762,24 @@ def plot_density(
731762 t .set_bbox (dict (alpha = 0 ))
732763 jxn_numbers .append (t )
733764
734- a = Path (pts , [Path .MOVETO , Path .CURVE4 , Path .CURVE4 , Path .CURVE4 ])
735-
736- """
737- @2018.12.26
738- scale the junctions line width
739- """
740- if junction_count_gap > 0 :
741- line_width = (jxns [jxn ] - min_junction_count ) / junction_count_gap
742- else :
743- line_width = 0
744-
745- ax .add_patch (PathPatch (a , ec = color , lw = line_width + 0.2 , fc = 'none' ))
746-
747765 adjust_text (jxn_numbers , force_text = 0.2 , arrowprops = dict (arrowstyle = "-" , color = 'black' , lw = 1 ), autoalign = "y" )
748766
749767 if obj and obj .title :
750768 ax .text (max (graph_coords ) - len (obj .title ), max_used_y_val , obj .title , color = color , fontsize = font_size )
751769
752- if data .strand_aware :
770+ # update the y-axis actually used
771+ min_used_y_val , max_used_y_val = ax .get_ylim ()
772+ if data .strand_aware and kwargs .get ("density_by_strand" ):
753773 max_used_y_val = max (abs (min_used_y_val ), max_used_y_val )
754- min_used_y_val = - max (abs (min_used_y_val ), max_used_y_val ) if data .minus is not None else 0
774+ min_used_y_val = - max_used_y_val
775+ elif not kwargs .get ("density_by_strand" ):
776+ min_used_y_val = 0
755777
756778 set_y_ticks (
757779 ax , label = y_label , theme = theme ,
758780 graph_coords = graph_coords ,
759- max_used_y_val = max_used_y_val ,
760- min_used_y_val = min_used_y_val ,
781+ max_used_y_val = max_used_y_val * 1.1 , # keep a buffer at top and bottom of junctions
782+ min_used_y_val = min_used_y_val * 1.1 ,
761783 n_y_ticks = n_y_ticks ,
762784 distance_between_label_axis = distance_between_label_axis ,
763785 font_size = font_size ,
0 commit comments