One of Mathematica's strengths is its consistent underlying representation of objects. Thus, to change attributes of a plot without redoing the computation used to generate it, I could do something like
Replace[myplot, {Graphics[x_List, y_List] :>
Graphics[x,Flatten[{y,
BaseStyle -> {FontFamily -> Helvetica, FontSize -> 20}}]]}]
Unfortunately, every time I want to use this approach to modify a plot in order to change the style/color of lines, points, fonts, etc. I have to figure out what the appropriate replacement rule is by trial and error, which negates any efficiency gained by not having to recompute the plotted data. Here's another example:
myplot = Plot[{Cos[x], Sin[x]}, {x, 0, 2 Pi},
PlotStyle -> {{Red, Dashing[None]}, {Green, Dashing[None]}}]
myplot /. { {x___, PatternSequence[Red, Dashing[_]], y___}
-> {x, Green, Thickness[.02], Dashing[Tiny], y},
{x___, Green, y___}
-> {x, Thickness[Large], Red, y} }
This gets the job done (changes line color/dashing/thickness), but seems voodoo-ish.
Is there any documentation (guides or tutorials) -- short of poring over the exact specifications for Graphics objects and primitives -- that could guide me in constructing the appropriate replacements?.. If not, are there better ways of tweaking the appearance of plots without recomputing (other than saving data in a variable and using ListPlot)?
I await more examples of your desired manipulations, but for now I'll point out that it may be possible to do a class of them without replacements at all. Forced to merely guess at what you want, one interpretation follows.
myplot = Plot[{Sin[x], Csc[x]}, {x, 1, 10}];
Replace[myplot, {Graphics[x_List, y_List] :>
Graphics[x,
Flatten[{y,
BaseStyle -> {FontFamily -> "Helvetica", FontSize -> 20}}]]}]
Show[myplot, BaseStyle -> {FontFamily -> "Helvetica", FontSize -> 20}]
As you can see, in this case Replace
is not needed.
Addressing your updated question, there are two different categories of graphical objects in a Plot
output.
The plotted lines of the functions (Sin[x]
, Cos[x]
) and their styles are "hard coded" into Line
objects, which Graphics
can understand.
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.
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]}}]
newstyles = Directive @@@
{{Green, Thickness[.02], Dashing[Tiny]},
{Thickness[Large], Red}};
i = 1; MapAt[# /. {__, l : Line[__]} :> {newstyles[[i++]], l} &, myplot, {1, 1}]
Please note the part in bold-italic in the last line of code above. This is the part specification for the location of the Line
objects within myplot
, and it may change. Usually this will work as is, but if you find that you must change this often, a function to detect its position should be possible (ask if needed).
telefunkenvf14's comment reminded me that I was negligent to not mention the Graphics Inspector.
While I personally tend to avoid extensive after-Plot restyling, because I like to keep everything on 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.
You can now copy and paste the entire graphic, or directly assign it to a symbol: p = <graphic>
Also, see: http://www.wolfram.com/broadcast/screencasts/howtoeditmathematicagraphics/
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With