Skip to main content

Create complicated text formulas in graphics


I want to put somewhat complicated, or at least non-standardly formatted, text on some of my graphics. For example, I'd like to be able to use f^[4](x) (where the ^[4] should obviously be a superscript rather than f^(4)[x] for the fourth derivative as a plot label. I'd like to control the formatting of various mathematical objects (for example, I'd like x^2+x+1 to be written that way rather than as 1+x+x^2), and the like.


The only way I've found for doing this is actually building up the string using StyleBox'es, which is both time-consuming and ugly. Am I missing something?



Answer



The general answer for what you appear to be doing is to wrap your expressions in HoldForm. However, it depends on how you include the expression. For example, here I'm using PlotLabel and have no problem:



Plot[x^2 + x + 1, {x, 0, 1}, PlotLabel -> x^2 + x + 1] 

plotlabel


However, what if I want to permute the order of the terms to x + 1 + x^2? Then HoldForm does the job:


Plot[x^2 + x + 1, {x, 0, 1}, PlotLabel -> HoldForm[x + 1 + x^2]]

plotlabel 2


Edit


I just noticed the second part of your question about the derivative format. The documentation on formatting is indeed somewhat confusing because it's spread through different pages. Maybe that has to do with the fact that there are so many different methods that it's hard to identify the "officially preferred" approach. I'm thinking, for example, of the Notation package which seems like it's supposed to make custom notation easier but which is actually a bit clumsy to use.


The default style for labels in plots is TraditionalForm, so I'll restrict the style modifications to that particular output form. Here is one way that you could make plot labels appear with the formatting for derivatives that you describe in the question:



Derivative /: 
MakeBoxes[Derivative[\[Alpha]__][f1_][vars__Symbol],
TraditionalForm] := RowBox[
Flatten@{SuperscriptBox[ToBoxes[f1],
RowBox[Flatten@{"[", Riffle[Map[ToBoxes, {\[Alpha]}], ","],
"]"}]], "(", Riffle[Map[ToBoxes, {vars}], ","], ")"}]

Now you should be able to do the following:


Plot[x^2 + x + 1, {x, 0, 1}, PlotLabel -> HoldForm[f'[x]]]


and the plot label will look like this:



$f^{[1]}(x)$



I added some extra logic to the style definition to make it work with higher-order derivatives and many variables, too.


As another example, you would input a mixed higher-order derivative like HoldForm[Derivative[1, 2][f][x, y]] and the display would be



$f^{[1,2]}(x,y)$



This modification will affect the display of all derivatives that were entered using the Derivative keyword when the output format is TraditionalForm. So if you want it to appear that way when TraditionalForm isn't the default, you'll have to wrap the expression in TraditionalForm explicitly. Also note that the TraditionalForm display of the alternative derivative D[f[x],x] is not affected by the new format, whereas f'[x] is. So you can still choose between two different TraditionalForm appearances for derivatives - a nontraditional and a traditional one...



Edit 2


Some additional links:



Comments

Popular posts from this blog

mathematical optimization - Minimizing using indices, error: Part::pkspec1: The expression cannot be used as a part specification

I want to use Minimize where the variables to minimize are indices pointing into an array. Here a MWE that hopefully shows what my problem is. vars = u@# & /@ Range[3]; cons = Flatten@ { Table[(u[j] != #) & /@ vars[[j + 1 ;; -1]], {j, 1, 3 - 1}], 1 vec1 = {1, 2, 3}; vec2 = {1, 2, 3}; Minimize[{Total@((vec1[[#]] - vec2[[u[#]]])^2 & /@ Range[1, 3]), cons}, vars, Integers] The error I get: Part::pkspec1: The expression u[1] cannot be used as a part specification. >> Answer Ok, it seems that one can get around Mathematica trying to evaluate vec2[[u[1]]] too early by using the function Indexed[vec2,u[1]] . The working MWE would then look like the following: vars = u@# & /@ Range[3]; cons = Flatten@{ Table[(u[j] != #) & /@ vars[[j + 1 ;; -1]], {j, 1, 3 - 1}], 1 vec1 = {1, 2, 3}; vec2 = {1, 2, 3}; NMinimize[ {Total@((vec1[[#]] - Indexed[vec2, u[#]])^2 & /@ R...

functions - Get leading series expansion term?

Given a function f[x] , I would like to have a function leadingSeries that returns just the leading term in the series around x=0 . For example: leadingSeries[(1/x + 2)/(4 + 1/x^2 + x)] x and leadingSeries[(1/x + 2 + (1 - 1/x^3)/4)/(4 + x)] -(1/(16 x^3)) Is there such a function in Mathematica? Or maybe one can implement it efficiently? EDIT I finally went with the following implementation, based on Carl Woll 's answer: lds[ex_,x_]:=( (ex/.x->(x+O[x]^2))/.SeriesData[U_,Z_,L_List,Mi_,Ma_,De_]:>SeriesData[U,Z,{L[[1]]},Mi,Mi+1,De]//Quiet//Normal) The advantage is, that this one also properly works with functions whose leading term is a constant: lds[Exp[x],x] 1 Answer Update 1 Updated to eliminate SeriesData and to not return additional terms Perhaps you could use: leadingSeries[expr_, x_] := Normal[expr /. x->(x+O[x]^2) /. a_List :> Take[a, 1]] Then for your examples: leadingSeries[(1/x + 2)/(4 + 1/x^2 + x), x] leadingSeries[Exp[x], x] leadingSeries[(1/x + 2 + (1 - 1/x...

What is and isn't a valid variable specification for Manipulate?

I have an expression whose terms have arguments (representing subscripts), like this: myExpr = A[0] + V[1,T] I would like to put it inside a Manipulate to see its value as I move around the parameters. (The goal is eventually to plot it wrt one of the variables inside.) However, Mathematica complains when I set V[1,T] as a manipulated variable: Manipulate[Evaluate[myExpr], {A[0], 0, 1}, {V[1, T], 0, 1}] (*Manipulate::vsform: Manipulate argument {V[1,T],0,1} does not have the correct form for a variable specification. >> *) As a workaround, if I get rid of the symbol T inside the argument, it works fine: Manipulate[ Evaluate[myExpr /. T -> 15], {A[0], 0, 1}, {V[1, 15], 0, 1}] Why this behavior? Can anyone point me to the documentation that says what counts as a valid variable? And is there a way to get Manpiulate to accept an expression with a symbolic argument as a variable? Investigations I've done so far: I tried using variableQ from this answer , but it says V[1...