1

I would like some advice on the following: I've created an image with circos (dna data). I want to annotate this data by plotting a gene name in the middle of the plot, and an arrow to show where the first gene starts. (an example output file here: http://www.nature.com/ncomms/2015/150122/ncomms6973/images/ncomms6973-f3.jpg)

This is part of a pipeline, so thousands of images need to be created. This sounds like basic functionality, but is there any software available (under open licence) to do this ?

I think the best way to do this is to load in the image in 'some' package, and use the generated image as a canvas to plot additional things onto.

Could someone give any tips on how to do such a thing ? I tried googling, but the question seems to broad for googling.

Apart from circos I'm using matplotlib and reportlab, so I'm hoping its doable in one of those.

I understand if this is not a 'pure' programming question (downvotes in 3.. 2.. 1..)

EDIT: I would like to plot 2 things. 1) Text in the center of the image. 2) A curved arrow in the top middle pointing right, following the circle.

MrFronk
  • 382
  • 5
  • 23

2 Answers2

2

This kind of image can be produce by creating a polar subplot, then using the ax.bar method : http://matplotlib.org/examples/pie_and_polar_charts/polar_bar_demo.html

By tweaking it, you can do something similar :

import numpy as np
import matplotlib.pyplot as plt


N = 40
theta = np.linspace(0.0, 2 * np.pi, N, endpoint=False)
radii = np.random.uniform(-20,20,N)
width = 2*np.pi / N

ax = plt.subplot(111, polar=True)
ax.grid(False)
bars1 = ax.bar(theta, radii, width=width, bottom=40.0) 
bars2 = ax.bar(theta, radii, width=width, bottom=100.0)


# Use custom colors and opacity
for r, bar in zip(radii, bars1):
    bar.set_facecolor( 'r' if r>0 else 'g' )
    bar.set_alpha(0.5)

plt.show()

fig.savefig("figure_1.png")

example

A lot of example are available in matplotlib gallery : http://matplotlib.org/gallery.html

Now, if you really have that many images just as complex, it might be difficult for matplotlib, which is not really optimized to do fast graphic computation.

But you have those image saved, you can load them and process them. This might be faster indeed :

For example, I saved the previous as png, I can then load it with scipy.misc.imread (note that this work with any jpeg/png/etc.. image, even one not produce from matplotlib), plot it with imshow, then plot on it with the usual plot, you just need to take care to use the right coordinates :

import numpy as np
import matplotlib.pyplot as plt
import scipy.misc

fig = plt.figure()
ax = fig.add_subplot(111)
ax.grid(False)
img = scipy.misc.imread("figure_1.png")
ax.imshow(img)

ax.plot([400,500],[300,200],'k', linewidth=4)

plt.show()

enter image description here

Nihl
  • 557
  • 1
  • 5
  • 14
0

I like your plan of "cleanest way" - the best way is :

  • Modify the SVG file by yourself

Circos's output file is SVG or png. So we choose SVG.

  1. Add text in the center: just add text tag in svg file like this:

    <text x="1500" y="1500">Here is your text in center</text>

  2. plot by path and textpath

    Path is a strong feature of svg . You can visit https://developer.mozilla.org/en-US/docs/Web/SVG/Element/textPath to learn more .

Gentle Y
  • 331
  • 1
  • 10