# How do I rescale tick marks on a polar plot?

I am working with an external "number-crunching" application that generates radiation patterns for antennas. The data that I am working with is a function of spherical angles theta and phi and it produces numbers in the range of 0 through some maximum value. I want to plot using PolarPlot to show a "scaled" tick mark where the scaling is the result of some function that I write to do the proper transformation. So, here is an example [below, phi is controlled externally and sometimes via Manipulate[]).

PolarPlot[
gdb[180/Pi (Abs[Pi/2 - theta]), phi], {theta, 0, Pi},
PolarAxes -> True, PolarTicks -> {"Degrees", Automatic},
PolarGridLines -> Automatic, PlotRangeClipping -> False,
PolarAxesOrigin -> Automatic]


And, this is the resultant plot:

Now, the PolarAxesOrigin option given Automatic generates the axes labeled from 20 thru the maximum of 80. However, for this same plot, the only change I want (in this example) is to scale that axes tick mark labels as 0.0 for the 80 tick mark label and then the inner concentric circles would be -10, -20, -30, -40, and so on. Thus, the labeling are all negative numbers with zero as the maximum range on the PolarAxesOrigin.

I have researched various posted questions here and experimented using scaling features, tick functions, and other things (merely guessing) to figure out how to achieve this and nothing works right. I am hoping that I can provide some kind of function that can do a transformation from the plotted values to some scaled tick mark labels. Changing the data itself to be negative does not work, the resultant plot is not correct.

• Your code is not a working example because there is no definition go gdb. So anyone who might want to help can't reproduce your problem, which greatly reduces the chance that you get an answer. – m_goldberg May 13 '20 at 2:53
• Sorry about that but the gdb function is an Interpolation of about 4000 or so data points for angles theta 0 to 90 and phi 0 to 360. So, not really a function that can be easily included. But, the range of the function I mentioned which of course varies over the domain variables. – K7PEH May 13 '20 at 3:43

It's a shame you did not include your own function, so I will have to use a made up one. I do not know how to change that detail before the plot is generated, but inspection of the plot's InputForm (try plot // InputForm // SequenceForm) shows the general format of those labels. This can be modified after the fact as follows, using a global replacement to generate the ticks you want:

plot = PolarPlot[
25 theta, {theta, 0, Pi},
PolarAxes -> True,
PolarTicks -> {"Degrees", Automatic},
PolarGridLines -> Automatic,
PlotRangeClipping -> False,
PolarAxesOrigin -> Automatic
];

plot /. Text[Style[value_Real, {}], opts__] :> Text[Style[value - 80, {}], opts]


Above I restricted the pattern for replacement using val_Real to avoid causing the same change to the angular ticks, which otherwise would also become e.g. 30° - 80. "30°" is represented internally as Times[30, Degree]; that expression has head Times to Mathematica's eyes, and is not a real number (i.e. something with head Real), so it can be distinguished from the radial ticks that are plain real numbers instead.

• A bit of a hack, this should be supported through a Ticks option no? – M.R. May 13 '20 at 14:26
• @M.R. It sure should be (indeed that was my first attempt), but I was unable to make Ticks work here, hence the hack, – MarcoB May 13 '20 at 15:20
• So, I did the same hack on my plot and it worked. Now, I need to figure out how it worked. I understand the rule substitution but I do not understand the reason it works. For example, Text[Style[value_Real,{}],opts__] is a pattern match but I would not have been able to come up with that pattern myself. I figure value_Real matches any real value but I have never seen that before "the value part". Also, why the opts__ ? Does this match any options to be used in the substitution (my guess). – K7PEH May 13 '20 at 16:09
• I noted that in my version of Mathematica (should be the most recent) the function SequenceForm is obsolete and no longer exists. It is to be replaced with Row or Text. I am not sure how this SequenceForm adds to the description of the InputForm so not sure how Row or Text would be used as a substitute. – K7PEH May 13 '20 at 16:11
• @K7PEH The output of InputForm is normally formatted as text and does not allow the usual context-aware selection (e.g. keep clicking with the mouse to expand selection in a syntax aware fashion). SequenceForm makes the output more easily editable. Row does not work as well for this; Text is an acceptable but inferior substitute. – MarcoB May 13 '20 at 16:17

Yes, for some reason Ticks does not work with PolarPlot. I would prefer a more straight forward solution because of the obvious side effect of the above hack. Additionally its more versatile to produce ticks and other items.

pplot = PolarPlot[
{ Style[ 4, Thick, Gray ],
Style[ 2 Sin[3x] + 4, Blue, Thick ] }, { x, 0, 2\[Pi] },
PlotRangeClipping -> False,
PolarAxes -> { True, False },
PolarGridLines -> { Range[12] * 30 Degree, Range[10] },
PolarTicks -> { "Degrees", Automatic },
PolarAxesOrigin -> { 0, 10 },
Epilog -> Table[Table[ Text[ v-4, pos ], { v, Drop[Range[9],{4}] } ],
{ pos, { {0,v}, {0,-v}, {v,0}, {-v,0} } } ]
];


The radial axis is swiched off and substituted in the Epilog part.

PolarTicks >> Details:

• For each axis, the following tick mark options can be given:

So we can use

radialTicks = Thread[{Subdivide[0, 80, 8],
Style[-#, 16, Red] & /@ Reverse[Subdivide[0, 80, 8]], .01, Green}]

PolarPlot[20 (2 + Sin[3 t]), {t, 0, 2 Pi}, ImageSize -> Large,
PolarAxes -> True,
PolarGridLines -> {Subdivide[##, 24] &, Range[##, 10] &},
PolarAxesOrigin -> {Pi/2, 80}]


Alternatively, we can use a ticks function that uses the automatic radial axis range to construct a list of labeled ticks:

radialTicksFunction = Thread[{Subdivide[##, 8],
Style[-#, 16, Red] & /@ Reverse[Subdivide[##, 8]], .01, Green}] &;

PolarPlot[20 (2 + Sin[3 t]), {t, 0, 2 Pi}, ImageSize -> Large,
PolarAxes -> True,
PolarGridLines -> {Subdivide[##, 24] &, Range[##, 10] &},