Take the 2-minute tour ×
Mathematica Stack Exchange is a question and answer site for users of Mathematica. It's 100% free, no registration required.

I frequently generate framed plots like this:

Plot[Sin[x], {x, 0, 2 \[Pi]}, Frame -> True]

enter image description here

Is there an easy way to change the background color of the framed region only?

Specifying the Background option changes the background color of the entire plot, not just the framed region:

Plot[Sin[x], {x, 0, 2 \[Pi]}, Frame -> True, Background -> LightGray]

enter image description here

Also, is there a way to make figures look like MATLAB's default figure style, i.e. a white background surrounded by a gray frame (see below)?

MATLAB figure

share|improve this question
3  
See related: stackoverflow.com/questions/6303500/… –  Eli Lansey Feb 24 '12 at 14:36
    
The answers from stackoverflow.com/questions/6303500/… have been move here as a result of merging. –  Mr.Wizard Feb 24 '12 at 17:31
    
wow... it has been a while since I've been to stack overflow. But now I come back and my question has been migrated here and given credit to someone else... @Mr.Wizard, what's going on here? How do I find my original post? –  jmlopez Mar 29 '12 at 19:03
    
@jmlopez I am new to moderating but I am trying to do the best job I can. When a duplicate question was posted here (this one) I wanted to combine the two rather than cover old ground. Even at the time I was uncertain how to handle it; normally I would close the new question as a duplicate of the old, but it was suggested to me to keep the new one instead, and since you appeared to have left StackExchange I did not argue. Please read the chat transcript to see how this played out. –  Mr.Wizard Mar 30 '12 at 1:23
2  
@Mr.Wizard it appears it was deleted, yet he retains the rep from it. –  rcollyer Apr 8 '12 at 2:39

7 Answers 7

up vote 25 down vote accepted

You can use the Prolog option with Scaled coordinates:

Plot[Sin[x], {x, 0, 2 \[Pi]}, Frame -> True,
 Prolog -> {LightGray, Rectangle[Scaled[{0, 0}], Scaled[{1, 1}]]}
]

Mathematica graphics

Note: Using scaled coordinates lets this work for any PlotRangePadding, and with PlotRangePadding->False:

Plot[Sin[x], {x, 0, 2 \[Pi]}, Frame -> True, 
 Prolog -> {LightGray, Rectangle[Scaled[{0, 0}], Scaled[{1, 1}]]}, 
 PlotRangePadding -> .6]

Mathematica graphics

Plot[Sin[x], {x, 0, 2 \[Pi]}, Frame -> True, 
 Prolog -> {LightGray, Rectangle[Scaled[{0, 0}], Scaled[{1, 1}]]}, 
 PlotRangePadding -> -.2, PlotRangeClipping -> False]

Mathematica graphics

share|improve this answer
    
Very helpful. Thank you both! –  David Skulsky Feb 24 '12 at 14:37

After playing around for a while with various graphics and frame options...
I decided to take the simplest option - your polygon one:

Framed[Plot[Sin[x] Exp[x], {x, 1, 10}, Frame -> True, 
  PlotRangePadding -> None, Axes -> False, 
  Prolog -> {White, Rectangle[Scaled[{0, 0}], Scaled[{1, 1}]]}], 
 Background -> LightGray]

An example image generated from the above code

share|improve this answer
6  
This works because Plot sets PlotRangeClipping -> True by default. (A good choice -- it keeps curves from drawing beyond the frame.) Using Scaled instead of ImageScaled would be better, since the Scaled coordinate system naturally corresponds to plot range (ie, the region inside the frame.) –  Brett Champion Jun 10 '11 at 14:13
    
@Brett: Thanks Brett. Using Scaled is by far the better choice. Too many graphics/image options and I always forget which is which. –  Simon Jun 10 '11 at 23:56
    
@Brett and @Simon: I edited my post in order to add a solution based on your ideas. This gives me more control over my custom labels and graphics. Thank you for your answers. –  jmlopez Jun 11 '11 at 20:57

You could also do:

Framed[Plot[{Sin[x] Exp[x], Exp[x]}, {x, 1, 10}, 
       Frame -> True, 
       Axes  -> False, 
       PlotRangePadding -> None, 
       Filling          -> {1 -> Top, 1 -> Bottom}, 
       FillingStyle     -> White], 
       Background       -> LightGray]

enter image description here

Edit

I suspected problems when the function is not defined in the full range, but found it is not the case:

Framed[Plot[{Piecewise[{{x^2, x < 4}, {x, x > 6}}]}, {x, 1, 10}, 
       Frame -> True, 
       Axes  -> False, 
       PlotRangePadding -> None, 
       Filling          -> {1 -> Top, 1 -> Bottom}, 
       FillingStyle     -> White], 
       Background       -> LightGray]  

enter image description here

share|improve this answer
1  
+1 nice way to hack it –  Mr.Wizard Jun 10 '11 at 12:31
    
+1 The hack even works if you want to fill down in color and have the rest white. Framed[Plot[{Piecewise[{{x^2, x < 4}, {x, x > 6}}]}, {x, 1, 10}, Frame -> True, Axes -> False, PlotRangePadding -> None, Filling -> {1 -> Top, 1 -> Bottom}, FillingStyle -> {White, Blue}, ImageSize -> Large], Background -> LightGray] –  Simon Jun 10 '11 at 13:35
    
@Simon Not so well. Try -x^2 instead of x^2 –  belisarius Jun 10 '11 at 13:43
    
The problem there is a combination of the PlotRange and the default default (0) for Piecewise... –  Simon Jun 10 '11 at 13:57

This is how I would do it:

passepartout[plot_, opt : OptionsPattern[]] := With[{
   p = Show[plot, PlotRangePadding -> None]
   },
  Show[Show[
    Graphics[{((Background /. Options[plot]) /. 
        Background -> Transparent), 
      Apply[Rectangle, Transpose[PlotRange /. Quiet@AbsoluteOptions[p]]]}], 
    p, Options[p]],
   opt]
  ]

This function should be able to take any Graphics object as its argument "plot". It uses whatever Background plot has been given beforehand, and then adds the frame according to the options Background and ImagePadding supplied to the passepartout function.

For example, start with a plot

p = Plot[Sin[x], {x, 1, 10}, Frame -> True, Axes -> False, Background -> Yellow]

(I added a yellow background, but that's just for illustration and is completely optional). To get what you're looking for, just say

passepartout[p, ImagePadding -> 30, Background -> LightGray]

Output of the previous command

To make the frame thicker or asymmetric, use the standard ImagePadding syntax. You can also add other options such as AspectRatio to passpartout.

In the passepartout function, I use AbsoluteOptions to extract the PlotRange that determines the "passepartout opening." You could replace this by Options to speed things up, but the advantage of using AbsoluteOptions is that it also works for arbitrary Graphics, such as

p = Graphics[Circle[], Background -> Yellow]
share|improve this answer

While Eli's answer is elegantly simple, it has a drawback: the Prolog objects are layered on top of GridLines, thus a background rectangle covers all the gridlines. So to come over this issue, here is my version of a background-and-frame.

The general background (gray) is defined by the outermost Frame's Background option (this way we won't cover GridLines), while the outer green frame is defined as a FilledCurve (using ImageScaled and Scaled coordinates), put in an independent Graphics object, and displayed with the final plot via Show. There is at least one caveat: any options defined for a Plot object must be then forwarded to the Show, otherwise they mess up the result.

Framed[
 Show[
  Graphics[{
    Hue[.3, 1, 1, .5], 
    FilledCurve[{
        {Line[ImageScaled /@ {{0, 0}, {1, 0}, {1, 1}, {0, 1}}]},
        {Line[Scaled /@ ({{0, 0}, {1, 0}, {1, 1}, {0, 1}})]}
       }],
    }],
  Plot[Sin[x], {x, 0, 2 \[Pi]}], (* this is the main plot, options given to Show *)
  ImagePadding -> 30, Frame -> True, GridLines -> Automatic, 
  GridLinesStyle -> Red
  ],
 Background -> GrayLevel@.9, FrameMargins -> 0, FrameStyle -> None]

Mathematica graphics

You might wonder why I didn't put the FilledCurve into the Plot's Prolog: well, Prolog cannot handle coordinates that are out of the defined PlotRange, thus ImageScaled coordinates out of the plot's frame won't show at all.

share|improve this answer

I'll add another way of combinig a plot with an image :

gr = Graphics[{
       Opacity[0.4], Texture[ExampleData[{"AerialImage", "Pentagon"}]], 
       Polygon[{{0, -1}, {2 Pi, -1}, {2 Pi, 1}, {0, 1}}, 
       VertexTextureCoordinates -> {{0, -1}, {2 Pi, -1}, {2 Pi, 1}, {0, 1}}]}]
Show[Plot[ Sin[x], {x, 0, 2 Pi}, PlotStyle -> {Blue, Thick}, Frame -> True], gr] 

enter image description here

share|improve this answer
1  
You needed to rescale the sine curve to fit the image dimensions. This is not practical. Why don't you put the image into a Raster and position the Raster to fill up the whole plot range (Scaled)? Or why don't you tile a Texture onto a background Rectangle? –  Szabolcs Feb 24 '12 at 18:20
    
@Szabolcs Good point! Not sure if Raster would yield a better solution, since there might be still some arrangements to do. But hope this completely different approach is worthy of note. –  Artes Feb 24 '12 at 19:30
2  
Plot[Sin[x], {x, 0, 2 Pi}, Prolog -> {{Raster[ ExampleData[{"AerialImage", "Pentagon"}, "Data"]/ 255., {Scaled[{0, 0}], Scaled[{1, 1}]}]}}, Frame -> True] –  Szabolcs Feb 24 '12 at 19:37

It is possible to combine a background PlotRange fill using the Scaled Rectangle approach with GridLines by specifying the undocumented option Method -> {"GridLinesInFront" -> True}. If it is desirable to place the plot lines over the grid lines we can move or copy the Line primitives into an Epilog option.

Mathematica graphics

gr = LogPlot[
  {5 (80/x)^4, 5 (55/x)^4, 12 (40/x)^4, 15 (80/x)^4, 9 (80/x)^4, 15 (55/x)^4, 9 (55/x)^4},
  {x, 40, 120},
  PlotStyle -> Map[Directive[Thick, ColorData[14]@#] &, {2, 6, 7, 4, 3, 1, 5}],
  GridLines -> Automatic,
  PlotRange -> {1, 33},
  Frame -> True,
  PlotRangePadding -> {Automatic, 0.1},
  Prolog -> {GrayLevel[0.95], Rectangle[Scaled[{0, 0}], Scaled[{1, 1}]]},
  Method -> {"GridLinesInFront" -> True},
  ImageSize -> 500
];

Show[gr,
  Epilog -> (gr[[1, 1]] /.
    {style__, x_Line} :> {{Black, Opacity[0.5], AbsoluteThickness[3], x}, style, x})]
share|improve this answer

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

Not the answer you're looking for? Browse other questions tagged or ask your own question.