last-dotplot: implementing annotation names...
authorMartin C. Frith
Fri Jul 31 15:04:20 2020 +0900 (11 days ago)
changeset 10763b8d229f8359
parent 1075 70b0e512d696
child 1077 5209deca661c
last-dotplot: implementing annotation names...
scripts/last-dotplot
     1.1 --- a/scripts/last-dotplot	Fri Jul 31 14:48:36 2020 +0900
     1.2 +++ b/scripts/last-dotplot	Fri Jul 31 15:04:20 2020 +0900
     1.3 @@ -694,8 +694,9 @@
     1.4          else:
     1.5              yield 2000, opts.unbridged_color, seqName, beg, end, ""
     1.6  
     1.7 -def bedBoxes(beds, rangeDict, margin, edge, isTop, bpPerPix):
     1.8 -    for layer, color, seqName, bedBeg, bedEnd, name in beds:
     1.9 +def bedBoxes(beds, rangeDict, edge, isTop, bpPerPix, textSizes):
    1.10 +    cover = [(edge, edge)]
    1.11 +    for layer, color, seqName, bedBeg, bedEnd, name in reversed(beds):
    1.12          for rangeBeg, rangeEnd, isReverseRange, origin in rangeDict[seqName]:
    1.13              beg = max(bedBeg, rangeBeg)
    1.14              end = min(bedEnd, rangeEnd)
    1.15 @@ -716,15 +717,22 @@
    1.16                          pixBeg = (origin + beg) // bpPerPix
    1.17                      else:
    1.18                          pixEnd = div_ceil(origin + end, bpPerPix)
    1.19 -            if isTop:
    1.20 -                box = pixBeg, margin, pixEnd, edge
    1.21 +            textWidth, textHeight = textSizes[name]
    1.22 +            nameBeg = (pixBeg + pixEnd - textHeight) // 2
    1.23 +            nameEnd = nameBeg + textHeight
    1.24 +            if name and all(e <= nameBeg or b >= nameEnd for b, e in cover):
    1.25 +                cover.append((nameBeg, nameEnd))
    1.26              else:
    1.27 -                box = margin, pixBeg, edge, pixEnd
    1.28 -            yield layer, color, box
    1.29 +                name = ""
    1.30 +            yield layer, color, isTop, pixBeg, pixEnd, name, nameBeg, textWidth
    1.31  
    1.32 -def drawAnnotations(im, boxes):
    1.33 +def drawAnnotations(im, boxes, tMargin, bMarginBeg, lMargin, rMarginBeg):
    1.34      # xxx use partial transparency for different-color overlaps?
    1.35 -    for layer, color, box in boxes:
    1.36 +    for layer, color, isTop, beg, end, name, nameBeg, nameLen in boxes:
    1.37 +        if isTop:
    1.38 +            box = beg, tMargin, end, bMarginBeg
    1.39 +        else:
    1.40 +            box = lMargin, beg, rMarginBeg, end
    1.41          im.paste(color, box)
    1.42  
    1.43  def placedLabels(labels, rangePixBegs, rangePixLens, beg, end):
    1.44 @@ -952,8 +960,10 @@
    1.45      rangeDict1 = expandedSeqDict(rangeDict1)
    1.46      rangeDict2 = expandedSeqDict(rangeDict2)
    1.47  
    1.48 -    boxes1 = bedBoxes(annots1, rangeDict1, tMargin, bMarginBeg, 1, bpPerPix)
    1.49 -    boxes2 = bedBoxes(annots2, rangeDict2, lMargin, rMarginBeg, 0, bpPerPix)
    1.50 +    boxes1 = list(bedBoxes(annots1, rangeDict1, bMarginBeg, True, bpPerPix,
    1.51 +                           annoTextSizes1))
    1.52 +    boxes2 = list(bedBoxes(annots2, rangeDict2, rMarginBeg, False, bpPerPix,
    1.53 +                           annoTextSizes2))
    1.54      boxes = sorted(itertools.chain(boxes1, boxes2))
    1.55  
    1.56      logging.info("drawing...")
    1.57 @@ -961,7 +971,7 @@
    1.58      image_size = width, height
    1.59      im = Image.new(image_mode, image_size, opts.background_color)
    1.60  
    1.61 -    drawAnnotations(im, boxes)
    1.62 +    drawAnnotations(im, boxes, tMargin, bMarginBeg, lMargin, rMarginBeg)
    1.63  
    1.64      joinA, joinB = twoValuesFromOption(opts.join, ":")
    1.65      if joinA in "13":