bio-graphics 1.0

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.
Files changed (63) hide show
  1. data/doc/classes/Bio.html +135 -0
  2. data/doc/classes/Bio/Graphics.html +247 -0
  3. data/doc/classes/Bio/Graphics/Panel.html +344 -0
  4. data/doc/classes/Bio/Graphics/Panel.src/M000005.html +29 -0
  5. data/doc/classes/Bio/Graphics/Panel.src/M000006.html +19 -0
  6. data/doc/classes/Bio/Graphics/Panel.src/M000007.html +67 -0
  7. data/doc/classes/Bio/Graphics/Panel/Ruler.html +238 -0
  8. data/doc/classes/Bio/Graphics/Panel/Ruler.src/M000008.html +20 -0
  9. data/doc/classes/Bio/Graphics/Panel/Ruler.src/M000009.html +28 -0
  10. data/doc/classes/Bio/Graphics/Panel/Ruler.src/M000010.html +54 -0
  11. data/doc/classes/Bio/Graphics/Panel/Ruler.src/M000013.html +20 -0
  12. data/doc/classes/Bio/Graphics/Panel/Ruler.src/M000014.html +28 -0
  13. data/doc/classes/Bio/Graphics/Panel/Ruler.src/M000015.html +59 -0
  14. data/doc/classes/Bio/Graphics/Panel/Track.html +342 -0
  15. data/doc/classes/Bio/Graphics/Panel/Track.src/M000008.html +23 -0
  16. data/doc/classes/Bio/Graphics/Panel/Track.src/M000009.html +42 -0
  17. data/doc/classes/Bio/Graphics/Panel/Track.src/M000010.html +285 -0
  18. data/doc/classes/Bio/Graphics/Panel/Track.src/M000011.html +23 -0
  19. data/doc/classes/Bio/Graphics/Panel/Track.src/M000012.html +43 -0
  20. data/doc/classes/Bio/Graphics/Panel/Track.src/M000013.html +259 -0
  21. data/doc/classes/Bio/Graphics/Panel/Track/Feature.html +292 -0
  22. data/doc/classes/Bio/Graphics/Panel/Track/Feature.src/M000011.html +65 -0
  23. data/doc/classes/Bio/Graphics/Panel/Track/Feature.src/M000014.html +65 -0
  24. data/doc/classes/Bio/Graphics/Panel/Track/Feature/PixelRange.html +155 -0
  25. data/doc/classes/Bio/Graphics/Panel/Track/Feature/PixelRange.src/M000012.html +18 -0
  26. data/doc/classes/Bio/Graphics/Panel/Track/Feature/PixelRange.src/M000015.html +18 -0
  27. data/doc/classes/ImageMap.html +185 -0
  28. data/doc/classes/ImageMap.src/M000001.html +18 -0
  29. data/doc/classes/ImageMap.src/M000002.html +24 -0
  30. data/doc/classes/ImageMap/ImageMapElement.html +187 -0
  31. data/doc/classes/ImageMap/ImageMapElement.src/M000003.html +19 -0
  32. data/doc/classes/ImageMap/ImageMapElement.src/M000004.html +20 -0
  33. data/doc/created.rid +1 -0
  34. data/doc/files/README_DEV.html +432 -0
  35. data/doc/files/TUTORIAL.html +358 -0
  36. data/doc/files/lib/bio-graphics_rb.html +121 -0
  37. data/doc/files/lib/bio/graphics/feature_rb.html +113 -0
  38. data/doc/files/lib/bio/graphics/image_map_rb.html +113 -0
  39. data/doc/files/lib/bio/graphics/panel_rb.html +113 -0
  40. data/doc/files/lib/bio/graphics/ruler_rb.html +113 -0
  41. data/doc/files/lib/bio/graphics/track_rb.html +113 -0
  42. data/doc/fr_class_index.html +35 -0
  43. data/doc/fr_file_index.html +34 -0
  44. data/doc/fr_method_index.html +41 -0
  45. data/doc/images/example.png +0 -0
  46. data/doc/images/glyph_showcase.png +0 -0
  47. data/doc/images/terms.png +0 -0
  48. data/doc/images/terms.svg +166 -0
  49. data/doc/index.html +24 -0
  50. data/images/example.png +0 -0
  51. data/images/glyph_showcase.png +0 -0
  52. data/images/terms.png +0 -0
  53. data/images/terms.svg +166 -0
  54. data/lib/bio-graphics.rb +18 -0
  55. data/lib/bio/graphics/feature.rb +136 -0
  56. data/lib/bio/graphics/image_map.rb +37 -0
  57. data/lib/bio/graphics/panel.rb +205 -0
  58. data/lib/bio/graphics/ruler.rb +96 -0
  59. data/lib/bio/graphics/track.rb +387 -0
  60. data/samples/arkdb_features.rb +37 -0
  61. data/samples/data.txt +32 -0
  62. data/samples/glyph_showcase.rb +29 -0
  63. metadata +137 -0
@@ -0,0 +1,387 @@
1
+ #
2
+ # = bio/graphics/track - track class
3
+ #
4
+ # Copyright:: Copyright (C) 2007
5
+ # Jan Aerts <jan.aerts@bbsrc.ac.uk>
6
+ # License:: The Ruby License
7
+ #
8
+ module Bio
9
+ module Graphics
10
+ class Panel
11
+ # The Bio::Graphics::Track class describes the container for features of
12
+ # the same type. See Bio::Graphics documentation for explanation of
13
+ # interplay between different classes.
14
+ class Track
15
+ # !!Not to be used directly. Use Bio::Graphics::Panel.add_track instead!!
16
+ # A track can not exist except within the confines of a
17
+ # Bio::Graphics::Panel object.
18
+ #
19
+ #--
20
+ # This is necessary because the track needs to know the rescale_factor
21
+ # and width of the picture, both of which are defined within the panel.
22
+ #++
23
+ #
24
+ # ---
25
+ # *Arguments*:
26
+ # * _panel_ (required) :: Bio::Graphics::Panel object that this track
27
+ # belongs to
28
+ # * _name_ (required) :: Name of the track to be displayed (e.g. 'genes')
29
+ # * _colour_ :: Colour to be used to draw the features within the track.
30
+ # Default = 'blue'
31
+ # * _glyph_ :: Glyph to use for drawing the features. Options are:
32
+ # 'generic', 'directed_generic', 'spliced, 'directed_spliced' and
33
+ # 'triangle'. Triangles can be used
34
+ # for features whose start and stop positions are the same (e.g. SNPs).
35
+ # If you try to draw a feature that is longer with triangles, an error
36
+ # will be shown.
37
+ # *Returns*:: Bio::Graphics::Track object
38
+ def initialize(panel, name, feature_colour = [0,0,1], feature_glyph = 'generic')
39
+ @panel = panel
40
+ @name = name
41
+ @feature_colour = feature_colour
42
+ @feature_glyph = feature_glyph
43
+ @features = Array.new
44
+ @number_of_times_bumped = 0
45
+ end
46
+ attr_accessor :panel, :name, :feature_colour, :feature_glyph, :features, :number_of_times_bumped, :height
47
+
48
+ # Adds a Bio::Graphics::Panel::Track::Feature to this track. A track contains
49
+ # features of the same type, e.g. (for sequence annotation:) genes,
50
+ # polymorphisms, ESTs, etc.
51
+ #
52
+ # est_track.add_feature('EST1','50..60')
53
+ # est_track.add_feature('EST2','52..73')
54
+ # est_track.add_feature('EST3','41..69')
55
+ # gene_track.add_feature('gene2','39..73')
56
+ #
57
+ # For spliced features:
58
+ # est_track.add_feature('EST4','join(34..53,153..191)')
59
+ #
60
+ # Or on the complement strand:
61
+ # est_track.add_feature('EST5','complement(join(34..53,153..191))')
62
+ #
63
+ # See the documentation in Bio::Locations for a full description of
64
+ # how locations can be defined.
65
+ #
66
+ # Features are only added if they are at least partly in the displayed
67
+ # region. If a feature is completely outside of the region, it's not
68
+ # added. If it should be only partly visible, it is added completely.
69
+ #
70
+ # ---
71
+ # *Arguments*:
72
+ # * _name_ (required) :: Name of the feature
73
+ # * _location_ :: String. Default: whole of panel, forward strand.
74
+ # * _link_ :: URL to link to for this glyph
75
+ # *Returns*:: Bio::Graphics::Track::Feature object that was created or nil
76
+ def add_feature(name, location_string = '1..' + @panel.length.to_s, link = nil)
77
+ if link == ''
78
+ link = nil
79
+ end
80
+
81
+ # Calculate the ultimate start and stop of the feature: the start
82
+ # of the first subfeature (e.g. exon) and the stop of the last one.
83
+ # The only reason we want to know these positions, is because we want
84
+ # to determine if the feature falls within the view of the image or
85
+ # not (see below).
86
+ location_object = Bio::Locations.new(location_string)
87
+ start = location_object.collect{|l| l.from}.min.to_i
88
+ stop = location_object.collect{|l| l.to}.max.to_i
89
+
90
+ # If the feature wouldn't show because it's not in the region we're
91
+ # looking at, don't bother storing the stuff. I think this makes huge
92
+ # speed and memory differences if you've got a chromosome with
93
+ # thousands of features.
94
+ if stop <= panel.display_start or start >= panel.display_stop
95
+ return nil
96
+ else #elsif start >= panel.display_start and stop <= panel.display_stop
97
+ @features.push(Bio::Graphics::Panel::Track::Feature.new(self, name, location_object, link))
98
+ return @features[-1]
99
+ end
100
+
101
+ return self
102
+ end
103
+
104
+
105
+ # Adds the track to a cairo drawing. This method should not be used
106
+ # directly by the user, but is called by Bio::Graphics::Panel.draw
107
+ # ---
108
+ # *Arguments*:
109
+ # * _paneldrawing_ (required) :: the panel cairo object
110
+ # * _verticaloffset_ (required) :: number of pixels to offset the track downwards,
111
+ # based on the height of other tracks that were drawn above it
112
+ # *Returns*:: FIXME: I don't know
113
+ def draw(panel_drawing, vertical_offset)
114
+ track_drawing = Cairo::Context.new(panel_drawing)
115
+
116
+ # Draw thin line above title
117
+ track_drawing.set_source_rgb(0.75,0.75,0.75)
118
+ track_drawing.move_to(0, vertical_offset)
119
+ track_drawing.line_to(panel.width, vertical_offset)
120
+ track_drawing.stroke
121
+
122
+ # Draw track title
123
+ track_drawing.set_source_rgb(0,0,0)
124
+ track_drawing.select_font_face('Georgia',1,1)
125
+ track_drawing.set_font_size(TRACK_HEADER_HEIGHT)
126
+ track_drawing.move_to(0,TRACK_HEADER_HEIGHT + vertical_offset + 10)
127
+ track_drawing.show_text(self.name)
128
+
129
+ # Draw the features
130
+ grid = Hash.new
131
+
132
+ track_drawing.save do
133
+ track_drawing.translate(0, vertical_offset + TRACK_HEADER_HEIGHT)
134
+ track_drawing.set_source_rgb(@feature_colour)
135
+
136
+ # Now draw the features
137
+ # These are the basic steps:
138
+ # A. find out what row to draw it on
139
+ # B. see if we want to change the glyph type from directed to
140
+ # undirected
141
+ # C. draw the thing
142
+ @features.each do |feature|
143
+ # Don't even bother if the feature is not in the view
144
+ if feature.stop <= self.panel.display_start or feature.start >= self.panel.display_stop
145
+ next
146
+ else
147
+ feature_drawn = false
148
+
149
+ # A. find out what row to draw it on
150
+ feature_range = (feature.start.floor..feature.stop.ceil)
151
+ row = 1
152
+ row_available = true
153
+ until feature_drawn
154
+ if ! grid[row].nil?
155
+ grid[row].each do |covered|
156
+ if feature_range.include?(covered.first) or covered.include?(feature_range.first)
157
+ row_available = false
158
+ end
159
+ end
160
+ end
161
+
162
+ if ! row_available
163
+ row += 1
164
+ row_available = true
165
+ else
166
+ if grid[row].nil?
167
+ grid[row] = Array.new
168
+ end
169
+ grid[row].push(feature_range)
170
+
171
+ # B. see if we want to change the glyph type from directed to
172
+ # undirected
173
+ # There are 2 cases where we don't want to draw arrows on
174
+ # features:
175
+ # (a) when the picture is really zoomed out, features are
176
+ # so small that the arrow itself is too big
177
+ # (b) if a directed feature on the fw strand extends beyond
178
+ # the end of the picture, the arrow is out of view. This
179
+ # is the same as considering the feature as undirected.
180
+ # The same obviously goes for features on the reverse
181
+ # strand that extend beyond the left side of the image.
182
+ #
183
+ # (a) Zoomed out
184
+ replace_directed_with_undirected = false
185
+ if (feature.stop - feature.start).to_f/panel.rescale_factor.to_f < 2
186
+ replace_directed_with_undirected = true
187
+ end
188
+ # (b) Extending beyond borders picture
189
+ if ( feature.chopped_at_stop and feature.strand = 1 ) or ( feature.chopped_at_start and feature.strand = -1 )
190
+ replace_directed_with_undirected = true
191
+ end
192
+
193
+ local_feature_glyph = nil
194
+ if feature_glyph == 'directed_generic' and replace_directed_with_undirected
195
+ local_feature_glyph = 'generic'
196
+ elsif feature_glyph == 'directed_spliced' and replace_directed_with_undirected
197
+ local_feature_glyph = 'spliced'
198
+ else
199
+ local_feature_glyph = feature_glyph
200
+ end
201
+
202
+ # C. And draw the thing.
203
+ top_pixel_of_feature = FEATURE_V_DISTANCE + (FEATURE_HEIGHT+FEATURE_V_DISTANCE)*row
204
+ bottom_pixel_of_feature = top_pixel_of_feature + FEATURE_HEIGHT
205
+
206
+ case local_feature_glyph
207
+ # triangles are typical for features which have a 1 bp position (start == stop)
208
+ when 'triangle'
209
+ raise "Start and stop are not the same (necessary if you want triangle glyphs)" if feature.start != feature.stop
210
+
211
+ # Need to get this for the imagemap
212
+ left_pixel_of_feature = feature.pixel_range_collection[0].start_pixel - 3
213
+ right_pixel_of_feature = feature.pixel_range_collection[0].stop_pixel + 3
214
+ track_drawing.move_to(left_pixel_of_feature + 3, top_pixel_of_feature)
215
+ track_drawing.rel_line_to(-3, FEATURE_HEIGHT)
216
+ track_drawing.rel_line_to(6, 0)
217
+ track_drawing.close_path.fill
218
+
219
+ when 'directed_generic'
220
+ # Need to get this for the imagemap
221
+ left_pixel_of_feature = feature.pixel_range_collection.sort_by{|pr| pr.start_pixel}[0].start_pixel
222
+ right_pixel_of_feature = feature.pixel_range_collection.sort_by{|pr| pr.start_pixel}[-1].stop_pixel
223
+ if feature.strand == -1 # Reverse strand
224
+ # Draw main box
225
+ track_drawing.rectangle(left_pixel_of_feature+FEATURE_ARROW_LENGTH, top_pixel_of_feature, right_pixel_of_feature - left_pixel_of_feature - FEATURE_ARROW_LENGTH, FEATURE_HEIGHT).fill
226
+
227
+ # Draw arrow
228
+ track_drawing.move_to(left_pixel_of_feature+FEATURE_ARROW_LENGTH, top_pixel_of_feature)
229
+ track_drawing.rel_line_to(-FEATURE_ARROW_LENGTH, FEATURE_HEIGHT/2)
230
+ track_drawing.rel_line_to(FEATURE_ARROW_LENGTH, FEATURE_HEIGHT/2)
231
+ track_drawing.close_path.fill
232
+
233
+ else #default is forward strand
234
+ track_drawing.rectangle(left_pixel_of_feature, top_pixel_of_feature, right_pixel_of_feature - left_pixel_of_feature - FEATURE_ARROW_LENGTH, FEATURE_HEIGHT).fill
235
+ track_drawing.move_to(right_pixel_of_feature - FEATURE_ARROW_LENGTH, top_pixel_of_feature)
236
+ track_drawing.rel_line_to(FEATURE_ARROW_LENGTH, FEATURE_HEIGHT/2)
237
+ track_drawing.rel_line_to(-FEATURE_ARROW_LENGTH, FEATURE_HEIGHT/2)
238
+ track_drawing.close_path.fill
239
+ end
240
+ when 'spliced'
241
+ gap_starts = Array.new
242
+ gap_stops = Array.new
243
+
244
+ # Need to get this for the imagemap
245
+ left_pixel_of_feature = feature.pixel_range_collection.sort_by{|pr| pr.start_pixel}[0].start_pixel
246
+ right_pixel_of_feature = feature.pixel_range_collection.sort_by{|pr| pr.start_pixel}[-1].stop_pixel
247
+
248
+ # First draw the parts
249
+ feature.pixel_range_collection.sort_by{|pr| pr.start_pixel}.each do |pr|
250
+ track_drawing.rectangle(pr.start_pixel, top_pixel_of_feature, (pr.stop_pixel - pr.start_pixel), FEATURE_HEIGHT).fill
251
+ gap_starts.push(pr.stop_pixel)
252
+ gap_stops.push(pr.start_pixel)
253
+ end
254
+
255
+ # And then draw the connections in the gaps
256
+ # Start with removing the very first start and the very last stop.
257
+ gap_starts.sort!.pop
258
+ gap_stops.sort!.shift
259
+
260
+ gap_starts.length.times do |gap_number|
261
+ from = gap_starts[gap_number].to_f
262
+ to = gap_stops[gap_number].to_f
263
+ middle = from + ((to - from)/2)
264
+ track_drawing.move_to(from, top_pixel_of_feature+2)
265
+ track_drawing.line_to(middle, top_pixel_of_feature+7)
266
+ track_drawing.line_to(to, top_pixel_of_feature+2)
267
+ track_drawing.stroke
268
+ end
269
+
270
+ if feature.hidden_subfeatures_at_stop
271
+ from = feature.pixel_range_collection.sort_by{|pr| pr.start_pixel}[-1].stop_pixel
272
+ to = panel.width
273
+ track_drawing.move_to(from, top_pixel_of_feature+5)
274
+ track_drawing.line_to(to, top_pixel_of_feature+5)
275
+ track_drawing.stroke
276
+ end
277
+
278
+ if feature.hidden_subfeatures_at_start
279
+ from = 1
280
+ to = feature.pixel_range_collection.sort_by{|pr| pr.start_pixel}[0].start_pixel
281
+ track_drawing.move_to(from, top_pixel_of_feature+5)
282
+ track_drawing.line_to(to, top_pixel_of_feature+5)
283
+ track_drawing.stroke
284
+ end
285
+
286
+ when 'directed_spliced'
287
+ gap_starts = Array.new
288
+ gap_stops = Array.new
289
+ # First draw the parts
290
+ locations = feature.location.sort_by{|l| l.from}
291
+
292
+ # Need to get this for the imagemap
293
+ left_pixel_of_feature = feature.pixel_range_collection.sort_by{|pr| pr.start_pixel}[0].start_pixel
294
+ right_pixel_of_feature = feature.pixel_range_collection.sort_by{|pr| pr.start_pixel}[-1].stop_pixel
295
+
296
+ # Start with the one with the arrow
297
+ pixel_ranges = feature.pixel_range_collection.sort_by{|pr| pr.start_pixel}
298
+ range_with_arrow = nil
299
+ if feature.strand == -1 # reverse strand => box with arrow is first one
300
+ range_with_arrow = pixel_ranges.shift
301
+ track_drawing.rectangle((range_with_arrow.start_pixel)+FEATURE_ARROW_LENGTH, top_pixel_of_feature, range_with_arrow.stop_pixel - range_with_arrow.start_pixel, FEATURE_HEIGHT).fill
302
+ track_drawing.move_to(range_with_arrow.start_pixel+FEATURE_ARROW_LENGTH, top_pixel_of_feature)
303
+ track_drawing.rel_line_to(-FEATURE_ARROW_LENGTH, FEATURE_HEIGHT/2)
304
+ track_drawing.rel_line_to(FEATURE_ARROW_LENGTH, FEATURE_HEIGHT/2)
305
+ track_drawing.close_path.fill
306
+ else # forward strand => box with arrow is last one
307
+ range_with_arrow = pixel_ranges.pop
308
+ track_drawing.rectangle(range_with_arrow.start_pixel-FEATURE_ARROW_LENGTH, top_pixel_of_feature, range_with_arrow.stop_pixel - range_with_arrow.start_pixel, FEATURE_HEIGHT).fill
309
+ track_drawing.move_to(range_with_arrow.stop_pixel-FEATURE_ARROW_LENGTH, top_pixel_of_feature)
310
+ track_drawing.rel_line_to(FEATURE_ARROW_LENGTH, FEATURE_HEIGHT/2)
311
+ track_drawing.rel_line_to(-FEATURE_ARROW_LENGTH, FEATURE_HEIGHT/2)
312
+ end
313
+ gap_starts.push(range_with_arrow.stop_pixel)
314
+ gap_stops.push(range_with_arrow.start_pixel)
315
+
316
+ # And then add the others
317
+ pixel_ranges.each do |range|
318
+ track_drawing.rectangle(range.start_pixel, top_pixel_of_feature, range.stop_pixel - range.start_pixel, FEATURE_HEIGHT).fill
319
+ gap_starts.push(range.stop_pixel)
320
+ gap_stops.push(range.start_pixel)
321
+ end
322
+
323
+ # And then draw the connections in the gaps
324
+ # Start with removing the very first start and the very last stop.
325
+ gap_starts.sort!.pop
326
+ gap_stops.sort!.shift
327
+
328
+ gap_starts.length.times do |gap_number|
329
+ from = gap_starts[gap_number].to_f
330
+ to = gap_stops[gap_number].to_f
331
+ middle = from + ((to - from)/2)
332
+ track_drawing.move_to(from, top_pixel_of_feature+2)
333
+ track_drawing.line_to(middle, top_pixel_of_feature+7)
334
+ track_drawing.line_to(to, top_pixel_of_feature+2)
335
+ track_drawing.stroke
336
+ end
337
+
338
+ if feature.hidden_subfeatures_at_stop
339
+ from = feature.pixel_range_collection.sort_by{|pr| pr.start_pixel}[-1].stop_pixel
340
+ to = panel.width
341
+ track_drawing.move_to(from, top_pixel_of_feature+5)
342
+ track_drawing.line_to(to, top_pixel_of_feature+5)
343
+ track_drawing.stroke
344
+ end
345
+
346
+ if feature.hidden_subfeatures_at_start
347
+ from = 1
348
+ to = feature.pixel_range_collection.sort_by{|pr| pr.start_pixel}[0].start_pixel
349
+ track_drawing.move_to(from, top_pixel_of_feature+5)
350
+ track_drawing.line_to(to, top_pixel_of_feature+5)
351
+ track_drawing.stroke
352
+ end
353
+
354
+ else #treat as 'generic'
355
+ left_pixel_of_feature, right_pixel_of_feature = feature.pixel_range_collection[0].start_pixel, feature.pixel_range_collection[0].stop_pixel
356
+ track_drawing.rectangle(left_pixel_of_feature, top_pixel_of_feature, (right_pixel_of_feature - left_pixel_of_feature), FEATURE_HEIGHT).fill
357
+ end
358
+
359
+ # And add the region to the image map
360
+ if panel.clickable
361
+ # Comment: we have to add the vertical_offset and TRACK_HEADER_HEIGHT!
362
+ panel.image_map.elements.push(ImageMap::ImageMapElement.new(left_pixel_of_feature,
363
+ top_pixel_of_feature + vertical_offset + TRACK_HEADER_HEIGHT,
364
+ right_pixel_of_feature,
365
+ bottom_pixel_of_feature + vertical_offset + TRACK_HEADER_HEIGHT,
366
+ feature.link
367
+ ))
368
+ end
369
+
370
+
371
+ feature_drawn = true
372
+ end
373
+ end
374
+ end
375
+ end
376
+
377
+ end
378
+
379
+ @number_of_times_bumped = ( grid.keys.length == 0 ) ? 1 : grid.keys.max + 1
380
+
381
+ return panel_drawing
382
+ end
383
+
384
+ end #Track
385
+ end #Panel
386
+ end #Graphics
387
+ end #Bio
@@ -0,0 +1,37 @@
1
+ require File.dirname(__FILE__) + '/../lib/bio-graphics'
2
+
3
+ #Initialize graphic for a nucleotide sequence of 4173015 bp, zooming in on the
4
+ #region 11111..3333333
5
+ my_panel = Bio::Graphics::Panel.new(4173015, 800, false, 11111, 3333333)
6
+ #my_panel = Bio::Graphics::Panel.new(4173015, 800, false, 1, 4173015)
7
+
8
+ #Create and configure tracks
9
+ scaffold_track = my_panel.add_track('scaffold')
10
+ marker_track = my_panel.add_track('marker')
11
+ clone_track = my_panel.add_track('clone')
12
+
13
+ scaffold_track.feature_colour = [1,0,0]
14
+ marker_track.feature_colour = [0,1,0]
15
+ marker_track.feature_glyph = 'triangle'
16
+ clone_track.feature_colour = [0,0,1]
17
+
18
+ # Add data to tracks
19
+ File.open('data.txt').each do |line|
20
+ line.chomp!
21
+ accession, type, start, stop = line.split(/\t/)
22
+ if type == 'scaffold'
23
+ if start.nil?
24
+ scaffold_track.add_feature(accession)
25
+ else
26
+ scaffold_track.add_feature(accession, start + '..' + stop)
27
+ end
28
+
29
+ elsif type == 'marker'
30
+ marker_track.add_feature(accession, ((start.to_i + stop.to_i)/2).to_s, 'http://www.thearkdb.org/arkdb/do/getMarkerDetail?accession=' + accession)
31
+ elsif type == 'clone'
32
+ clone_track.add_feature(accession, start + '..' + stop)
33
+ end
34
+ end
35
+
36
+ # And draw
37
+ my_panel.draw('my_panel.png')
@@ -0,0 +1,32 @@
1
+ test scaffold
2
+ ARKSCA00000496 scaffold 1766280 3140306
3
+ ARKSCA00000495 scaffold 1454125 1756279
4
+ ARKMKR00050962 marker 1547565 1547116
5
+ ARKMKR00049743 marker 1467043 1467548
6
+ ARKMKR00049753 marker 1293787 1294437
7
+ ARKMKR00033347 marker 976330 976530
8
+ ARKMKR00049788 marker 959182 959941
9
+ ARKMKR00049746 marker 3030496 3031106
10
+ ARKCLN00574951 clone 1454125 1743183
11
+ ARKCLN00580755 clone 1115673 1332008
12
+ ARKCLN00734502 clone 2680312 2880020
13
+ ARKCLN00637391 clone 1291903 1444124
14
+ ARKCLN00733777 clone 554351 745744
15
+ ARKCLN00516431 clone 1766280 2053569
16
+ ARKCLN00734156 clone 1973620 2155335
17
+ ARKCLN00605941 clone 1576502 1756279
18
+ ARKCLN00608810 clone 672169 860914
19
+ ARKCLN00565213 clone 348808 418529
20
+ ARKCLN00679752 clone 2321244 2563972
21
+ ARKCLN00538485 clone 2851750 3078918
22
+ ARKCLN00581628 clone 2966855 3140306
23
+ ARKCLN00511832 clone 1034205 1213124
24
+ ARKCLN00734700 clone 2566852 2709684
25
+ ARKCLN00534126 clone 1043517 1290570
26
+ ARKCLN00734007 clone 951813 1154597
27
+ ARKCLN00733988 clone 140268 332409
28
+ ARKCLN00589095 clone 800155 1015201
29
+ ARKCLN00635737 clone 265756 445381
30
+ ARKCLN00573316 clone 2226636 2363631
31
+ ARKCLN00494906 clone 2130193 2314107
32
+ ARKCLN00515356 clone 81435 254456