Ask Your Question
3

How can I Change the background color of a plot.

asked 2014-04-25 14:21:00 +0200

Raul gravatar image

I want to create some plots using sage to then save them in my computer. I don't want the background to be white (or transparent). Is there a way of specifying the background of a plot inside sage?

(I'm looking for an option of the form:

sage: t=var('t')

sage: p=parametric_plot((t,2*t), (t, -5, 5))

sage: p.show(background=(.1,.2,.3))

or something like that.)

edit retag flag offensive close merge delete

4 Answers

Sort by ยป oldest newest most voted
3

answered 2014-04-27 06:48:19 +0200

ndomes gravatar image

Using PIL offers a further way. PIL is included in Sage.

def show_bg(gobj,bgcolor=(100,200,200),**kwargs):
    """
    add background color to a transparent plot

    gobj         any 2D graphics object created with option transparent=True
    bgcolor      tuple  (r,g,b) r,g,b in range 0..255
                 or string with proper color name 
    kwargs       all other keyword args are passed to save    

    EXAMPLES:
    sage: P = plot(sin,-pi,pi,color='red',thickness=2,transparent=True)
    sage: P += parametric_plot((2*x,x),(x,-2,2),color='gold',thickness=3)
    sage: show_bg(P,aspect_ratio=3/2,figsize=5,bgcolor='mistyrose')

    """

    # create temp file in DATA folder of this worksheet
    gobj.save(DATA+'tmp_plot.png',**kwargs)

    from PIL import Image
    im = Image.open('./data/tmp_plot.png')

    # create background file of same size and given bgcolor    
    bg = Image.new('RGB',im.size,bgcolor)

    # paste im into bg using im as mask
    bg.paste(im,(0,0),im)
    bg.save('output.png')
edit flag offensive delete link more

Comments

I tried to use your example in green, but I got this answer: File "/tmp/tmpGDjbwd/___code___.py", line 5, in <module> show_bg(P,aspect_ratio=_sage_const_3 /_sage_const_2 ,figsize=_sage_const_5 ,bgcolor='mistyrose') NameError: name 'show_bg' is not defined I guess I should include some package before using this?

Raul gravatar imageRaul ( 2014-04-27 15:55:48 +0200 )edit
1

Copy and paste the entire code into a cell of your worksheet and evaluate this cell. Than you can call this self defined python function 'show_bg' as shown in the example.

ndomes gravatar imagendomes ( 2014-04-27 17:09:04 +0200 )edit

@ndomes: Huh, this is cool. I'd say it rates inclusion in the reference manual - are you interested in submitting something? And do you have a version that works without the transparent background?

kcrisman gravatar imagekcrisman ( 2014-04-28 12:05:10 +0200 )edit

@kcrisman: you asked for a version working without transparent background: here it comes, see below.

ndomes gravatar imagendomes ( 2014-04-29 07:00:34 +0200 )edit

@ndomes: Thanks a lot! It works pretty nice now!

Raul gravatar imageRaul ( 2014-04-29 13:57:28 +0200 )edit
3

answered 2014-04-26 07:49:24 +0200

ndomes gravatar image

Create a plot with option transparent=True and save to DATA folder.

G = circle((2,2),3,transparent=True)
G.save(DATA+'circle.png')

Now you may create a backround file using imagemagick command-line tool and compose both files.

%sh
convert -size 600x600 xc:#ffffaa ./data/bg.png
convert ./data/bg.png  ./data/circle.png   -composite  output.png
edit flag offensive delete link more
1

answered 2014-04-26 22:23:53 +0200

kcrisman gravatar image

This SO question also seems relevant. However, even with using the relevant Sage functionality

sage: P = plot(sin(x),(x,-pi,pi),color='green',linestyle='--',thickness=10)
sage: P = plot(sin(x),(x,-pi,pi),color='green',linestyle='--',thickness=10)
sage: M = P.matplotlib()
sage: M.add_subplot(111,axisbg='r')
<matplotlib.axes.AxesSubplot at 0x115234610>
sage: from matplotlib.backends.backend_agg import FigureCanvasAgg
sage: M.set_canvas(FigureCanvasAgg(M))
sage: M.savefig('/Users/.../test.png',dpi=100,transparent=False)

it covers up/replaces the previous Axes object. It doesn't seem (easily) possible to change this afterward. (That is apparently a limitation in matplotlib and/or a feature of how they use the subplot instances.) However, it would be relatively straightforward to add this in Sage, though one would have to make sure it didn't mess anything up.

edit flag offensive delete link more
1

answered 2014-04-29 07:01:03 +0200

ndomes gravatar image
def show_bg(gobj,bgcolor=(100,200,200),**kwargs):
    """
    add new background color to a plot

    gobj         any 2D graphics object 
    bgcolor      tuple  (r,g,b) r,g,b in range 0..255
                 or string with proper color name 
    kwargs       all other keyword args are passed to save    

    EXAMPLES:
    sage: P = plot(sin,-pi,pi,color='red',thickness=2)
    sage: P += parametric_plot((2*x,x),(x,-2,2),color='gold',thickness=3)
    sage: show_bg(P,aspect_ratio=3/2,figsize=5,bgcolor='mistyrose')
    """

    # make gobj transparent 
    # the first element of graphics-array has to be transparent
    # so let's draw a dummy point with option transparent=True
    D = gobj.get_minmax_data()
    gobj_t = point((D['xmin'],D['ymin']),color=bgcolor,transparent=True)   
    gobj_t += gobj

    # create temp file in DATA folder of this worksheet
    gobj_t.save(DATA+'tmp_plot.png',**kwargs)

    from PIL import Image
    im = Image.open('./data/tmp_plot.png')

    # create background file of same size and given bgcolor    
    bg = Image.new('RGB',im.size,bgcolor)

    # paste im into bg using im as mask
    bg.paste(im,(0,0),im)
    bg.save('output.png')
edit flag offensive delete link more

Comments

Interesting that mpl doesn't seem to support this... I assume this still works with "Pillow"? See http://trac.sagemath.org/ticket/15539 - I can't test this with newest devel version of Sage, I destroyed my install last night.

kcrisman gravatar imagekcrisman ( 2014-04-29 10:38:28 +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

Stats

Asked: 2014-04-25 14:21:00 +0200

Seen: 3,155 times

Last updated: Apr 29 '14