For example:

p = Plot[Sin[x], {x, 0, 1}]

Is it possible to write options in Show to change the curve's color for example into red?

Show[p, (* Option?? *)]
  • 2
    $\begingroup$ p = Plot[Sin[x], {x, 0, 1}]; col = Cases[p, _Hue, Infinity][[1]]; Show[p /. col -> Red] - not sure if this really merits an answer? $\endgroup$ – Yves Klett Jan 4 '13 at 9:21
  • 2
    $\begingroup$ just to make sure, you wanted the Show way (to work on already existing plots), not simply a Plot[...,PlotStyle->Red] kind of solution ? $\endgroup$ – Yves Klett Jan 4 '13 at 11:57

I already answered this question on StackOverflow but since old questions can no longer be migrated without undue trouble I shall reproduce my answer here.

There are two different categories of graphical objects in a Plot output.

  1. The plotted lines of the functions (Sin[x], Cos[x]) and their styles are "hard coded" into Line objects, which Graphics can understand.

  2. Auxiliary settings such as Axes -> True, PlotLabel -> "Sine Cosecant Plot" and AxesStyle -> Orange are understood by Graphics directly, without conversion, and therefore remain within the myplot object.

The second kind of settings can be easily changed after the fact because they are soft settings. (e.g. Show[p, (* options *)]

The first kind much be processed in some way. This is complicated by the fact that different *Plot functions output different patterns of Graphics and Plot itself may give different patterns of output depending on the input it is given.

I am not aware of any global way to restyle all plot types, and if you do such restyling often, it probably makes more sense to retain the data that is required and simply regenerate the graphic with Plot. Nevertheless, for basic uses, your method can be improved. Each function plotted creates a Line object, in the given order. Therefore, you can use something like this to completely restyle a plot:

myplot = Plot[{Cos[x], Sin[x]}, {x, 0, 2 Pi}, 
  PlotStyle -> {{Red, Dashing[None]}, {Green, Dashing[None]}}]

Mathematica graphics

newstyles = Directive @@@ {
    {Green, Thickness[.02], Dashing[Tiny]},
    {Thickness[Large], Red}

i = 1;
MapAt[# /. {__, ln__Line} :> {newstyles[[i++]], ln} &, myplot, {1, 1}]

enter image description here

Please note the part {1, 1} in the last line of code above. This is the part specification for the location of the Line objects within myplot. It is specified so as not to accidentally style Lines that might appear in other parts of the Graphics object. This part may need to be changed; for example when using Filling the Lines end up in {1, 2}. For this reason in the function below I simply used 1 which will be more flexible but could conceivably conflict with something.

Restyle function

The method above can be made into a self-contained function.
I will use this method to cycle the styles given.

restylePlot[plot_Graphics, styles_List, op : OptionsPattern[Graphics]] :=
 Module[{x = styles}, Show[
   MapAt[# /. {__, ln__Line} :> {Directive @ Last[x = RotateLeft@x], ln} &, plot, 1],


myplot2 = Plot[Evaluate[Table[BesselJ[n, x], {n, 4}]], {x, 0, 10}, Filling -> Axis]

Mathematica graphics

  {Green, Thickness[.02], Dashing[Tiny]},
  {Thickness[Large], Red},
 Axes -> False,
 Frame -> True,
 FrameStyle -> Directive[20, FontColor -> Orange]

Mathematica graphics

You will notice that the filling styles have not changed. While it is possible to change these by using GraphicsGroup in place of Line in the replacement rule the structure is considerably more complex to the point of being inconvenient. (It would probably be better to use the Graphics Inspector, or preferably to regenerate the graphic.)

Graphics Inspector

While I personally tend to avoid extensive after-Plot restyling because I like to keep everything in one place (the Plot command), and I prefer to make what changes I do with code so that there is a record of my settings without having to dig into the Graphics object, the Graphics Inspector is directly applicable.

  • Double click the plot. The border should change from orange to thick gray.
  • Single click one of the plot lines. (the pointed should change when you hover over an element)
  • Press Ctrl+g to open the Graphics Inspector.
  • Make the changes you desire, and close the Graphics Inspector.

You can now copy and paste the entire graphic, or directly assign it to a symbol: p = <graphic>

Also see: https://reference.wolfram.com/language/howto/EditWolframLanguageGraphics.html

Tangentially related:

How to change the default ColorData used in Mathematica's Plot?

Filling Styles using a single Plot in Mathematica

| improve this answer | |
  • $\begingroup$ btw, I like this one too... You should find a place for this here. $\endgroup$ – rm -rf Jan 4 '13 at 17:56
  • $\begingroup$ Yes, it works, but you need to fix a typo in the definition – MapAt[..., plot, 1]. Also, my dashings look very different (like thick solid green). Do you have custom settings? $\endgroup$ – rm -rf Jan 4 '13 at 17:59
  • $\begingroup$ @Hypnotoad thanks! hm... I don't think I've got custom dashing. I better look at that. $\endgroup$ – Mr.Wizard Jan 4 '13 at 18:04
  • $\begingroup$ @Hypnotoad how does Thickness[.02], Dashing[Tiny] look in other plots? $\endgroup$ – Mr.Wizard Jan 4 '13 at 18:22
  • $\begingroup$ It looks same as in the above plot. I'm not surprised though, because I always run into trouble with Thickness (since it's based on the plot size and possibly other things). I always use AbsoluteThickness for these. $\endgroup$ – rm -rf Jan 4 '13 at 19:00

Ah well... this is not robust, but probably of educational value and useful as a starting point for other post-processing needs on Graphics or Graphics3D expressions:

p = Plot[Sin[x], {x, 0, 1}]
col = Cases[p, _Hue, Infinity][[1]];
Show[p /. col -> Red]

Mathematica graphics

Update: As pointed out by matheorem, Version 10 switched from Hue to RGBColor, so the Casesstatement has to be changed accordingly, preferably (thanks to @rcollyer) using ColorQ to cover all future bases. (e.g. Show[p /. _?ColorQ -> Red])

| improve this answer | |
  • 5
    $\begingroup$ Thank you very much! You're so clever! But I found an easier way inspired by your idea. A single line Show[p/._Hue->Red] will be enough! $\endgroup$ – matheorem Jan 4 '13 at 14:17
  • 1
    $\begingroup$ @user15964 thanks for the unexpected praise =). It is very good to see you managed an even simpler solution (mine may still be of use for plots with multiple colors). $\endgroup$ – Yves Klett Jan 4 '13 at 14:38
  • 2
    $\begingroup$ @YvesKlett Oh, I just found that in Mathematica 10, Hue is not working any more. They have changed Hue into RBGColor. So now in M10, we have to use p/._RGBColor->Red. Since your answer is most popular, you may add a note to it. $\endgroup$ – matheorem Nov 5 '14 at 13:35
  • 6
    $\begingroup$ @YvesKlett use _?ColorQ instead for v10 as it covers all your bases. $\endgroup$ – rcollyer Nov 5 '14 at 15:36
  • 3
    $\begingroup$ For fun: Animate[Plot[Evaluate[Table[1/(x - 2 n), {n, 4}]], {x, 0, 10}, Filling -> Axis] /. c_?ColorQ :> Function[{h, s, b}, Hue[h + a, s, b]] @@ ColorConvert[c, "HSB"], {a, 0, 1}] $\endgroup$ – Michael E2 Nov 5 '14 at 17:11

As Mr.Wizard indicated, you can also reconstruct the plot using the data. Here is an example:

restylePlot2[p_, op : OptionsPattern[ListLinePlot]] := 
    ListLinePlot[Cases[Normal@p, Line[x__] :> x, ∞], op, Options[p]]

then we can set the style as we do in plot. For example

 PlotStyle -> {{Green, Thick, Dashed}, {Thickness[Large], Red}, Blue},
  Filling -> Axis, FrameStyle -> Directive[20, FontColor -> Orange], 
 PlotLegends -> LineLegend[{"1", "2", "3", "4"}]]

enter image description here

I found it useful when sometime I want to combine several plots:

pls = Table[Plot[Sin[n x], {x, 0, 2 π}], {n, 1, 3}];

enter image description here

restylePlot2[pls, Joined -> True, Axes -> False, Frame -> True, PlotLegends -> {"1", "2", "3"}] 

enter image description here

| improve this answer | |
  • 1
    $\begingroup$ Nice idea. I think you are missing Joined -> True in the first example; I recommend using ListLinePlot rather than Joined -> True anyway. Also this loses any options from the original including any Prolog and Epilog that may exist. I think it would be better to filter the old options and use them as the defaults, allowing them to be overridden by any new ones that are given. $\endgroup$ – Mr.Wizard Sep 16 '14 at 1:22
  • $\begingroup$ @Mr.Wizard Thanks for pointing out, I was setting Joined->True to be the default setting in my Mathematica so I didn't notice. But for the old options, I did attach them to the end so I think Epilog, Prolog etc. should be alright. $\endgroup$ – xslittlegrass Sep 16 '14 at 14:00
  • $\begingroup$ I somehow either missed or misread that. One refinement you might make: use OptionsPattern[ListLinePlot] as that is the function that will be receiving the options. $\endgroup$ – Mr.Wizard Sep 16 '14 at 14:58

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

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