Ask Your Question

png image within a Graphics object

asked 2013-04-04 02:02:44 +0200

vdelecroix gravatar image


I have an image, let say a png file, which represents the values of a function. The function is continuous but highly non derivable (a good example is a Julia set and there is no way to obtain a clean picture directly within Sage or matplotlib.

Now that I have this picture, I would like to be able to add axes, lines or circles. Is it possible to do it in Sage ? with matplotlib ?


edit retag flag offensive close merge delete

3 Answers

Sort by ยป oldest newest most voted

answered 2013-04-04 07:28:45 +0200

vdelecroix gravatar image

I am very sorry to edit an answer for my own question but I finally ended with a solution. I confess that it is not completely satisfactory. It makes use of the precious post suppress border and the library PIL which is included in Sage.

First of all, I do have a graphic which is here of size 600x600 which is the Mandelbrot set in the range xmin=-2, xmax=1, ymin=-1.5, ymax=1.5.

image description

Let us do some import

sage: from PIL import Image
sage: from matplotlib.backends.backend_agg import FigureCanvasAgg
sage: import matplotlib.pyplot as plt

The graphics that I want to add are the axes the precise plot of the main cardioid and the circle that corresponds to the period 2 attracting cycle.

sage: P1 = line2d([(1-(exp(CC(0,t*2.*RR(pi)))+1)**2)/4 for t in xsrange(-.5,.5,.002)])
sage: P1 += point2d((0,0), color='green')
sage: P2 = circle((-1,0),1/4) 
sage: P2 += point2d((-1,0), color='green')
sage: G = P1 + P2
sage: G.set_axes_range(-2,1,-1.5,1.5)

Now I use the trick in the post mentioned above and save the picture

sage: pm = G.matplotlib(axes=True, axes_pad=0)
sage: pm.subplots_adjust(left=0,right=1,top=1,bottom=0)
sage: pm.set_canvas(FigureCanvasAgg(pm))
sage: pm.set_size_inches(6,6)   # with 80 dpi, this gives a 600x600 picture
sage: pm.savefig('/tmp/a.png', bbox_inches=0)

The result is seen below and one can check that it has the expected dimension 600x600.

image description

Then, using PIL, I can merge the two images

sage: mandel ='/tmp/mandel.png')
sage: axes   ='/tmp/a.png')
sage: mask ='L', (600,600), 125)
sage: mandel.paste(axes, mask)

image description

edit flag offensive delete link more


Very nice. How do you determine the origin `(0,0)` of the image? I see that you have xmin, xmax, etc. But what if you didn't have this information? And how do you know xmin, xmax, etc?

ppurka gravatar imageppurka ( 2013-04-04 09:01:48 +0200 )edit

In this case, these are well-known properties of the Mandelbrot set. Note that he saves it with exactly 600x600 - the size of his original png.

kcrisman gravatar imagekcrisman ( 2013-04-04 10:23:37 +0200 )edit

answered 2013-04-04 16:23:38 +0200

Jason Grout gravatar image

I wonder if you could use matplotlib's imshow to do this in an easier way:

edit flag offensive delete link more


I don't see how... I tried but did not suceed.

vdelecroix gravatar imagevdelecroix ( 2013-04-04 17:31:35 +0200 )edit

answered 2013-07-11 01:27:28 +0200

Wheatley gravatar image

You can try a image processing toolkit for adding axes, lines or circleswhich of cause should support the PNG manipulation.

edit remove flag flag offensive (1) delete link more


I did not see how to add axes with the library you mentioned. It is more suited to image manipulation (crop, resize, rotate, ...). Could you provide a more precise pointer?

vdelecroix gravatar imagevdelecroix ( 2013-07-11 06:25:06 +0200 )edit

Your Answer

Please start posting anonymously - your entry will be published after you log in or create a new account.

Add Answer

Question Tools


Asked: 2013-04-04 02:02:44 +0200

Seen: 1,669 times

Last updated: Jul 11 '13