Skip to content

Make it possible to set custom tick positions and labels with the plots.pl macro.#1389

Merged
somiaj merged 2 commits into
openwebwork:PG-2.21from
drgrice1:plots-custom-ticks
May 19, 2026
Merged

Make it possible to set custom tick positions and labels with the plots.pl macro.#1389
somiaj merged 2 commits into
openwebwork:PG-2.21from
drgrice1:plots-custom-ticks

Conversation

@drgrice1
Copy link
Copy Markdown
Member

To set custom tick positions use the tick_positions axis option. Set that to a reference to an array containing the positions on the axis that ticks are desired. For example, tick_positions => [ 2, 5, 9 ] will place ticks at positions 2, 5, and 9 on the axis. Note that when this option is used the tick_delta, tick_scale, and tick_distance options are not used. So only the given tick positions will appear in the graph.

To set custom tick labels use the tick_labels option. Note that this is not a new option, but now it accepts a new type of value. Previously this was purely boolean (0 or 1), and it only determined if tick labels would be shown or not. Now it can take a value that is a reference to a hash. The keys of the hash are tick positions, and the values are the labels to be placed at those positons. Note that formatting of the label must be done by the auther, and the tick_label_format option is ignored for any label provided in this hash. If a major tick is not listed in the hash, then the position will be used for the label and it will be formatted according to the tick_label_format option.

This is intended to replace what is done in #1374 and is a more flexible approach than what is done there. In that pull request the capability for custom tick labels only is added, and it is extremely restrictive in what it can do. Only positive tick labels can be customized, and it requires that the problem author label all major ticks (there is no fallback and a tick is labeled "undefined" if one is missing).

Here is a rather rudimentary example of using this new feature:

DOCUMENT();

loadMacros('PGstandard.pl', 'PGML.pl', 'plots.pl', 'PGcourse.pl');

$plot = Plot(
    xmin            => -2,
    xmax            => 12,
    xtick_distance  => 2,
    xminor          => 1,
    xtick_positions => [ 2, 4, 6 ],
    xtick_labels    => { 2 => '\(a\)', 6 => '\(b\)' },
    ymin            => -2,
    ymax            => 12,
    ytick_distance  => 2,
    yminor          => 1,
);

BEGIN_PGML
[@ $plot->image_type('Tikz'); @]*[!TikZ Image!]{$plot}

[@ $plot->image_type('JSXGraph'); @]*[!JSXGraph Image!]{$plot}
END_PGML

ENDDOCUMENT();

@drgrice1 drgrice1 changed the base branch from develop to PG-2.21 March 31, 2026 20:52
@drgrice1 drgrice1 force-pushed the plots-custom-ticks branch from d536a47 to f0b3968 Compare March 31, 2026 21:30
@drgrice1 drgrice1 force-pushed the plots-custom-ticks branch from f0b3968 to c5718f1 Compare April 21, 2026 21:45
@drgrice1 drgrice1 force-pushed the plots-custom-ticks branch from c5718f1 to 2246328 Compare April 28, 2026 21:56
@somiaj
Copy link
Copy Markdown
Contributor

somiaj commented Apr 28, 2026

Not related to this pull request, but TikZ doesn't allow \dfrac{}{}? I decided to see what labels would do if they were really tall and the ymin was zero, so I replaced your problem with ymin => 0 and xtick_labels => { 2 => '\(\dfrac{\dfrac{a}{b}}{\dfrac{c}{d}}\)', 6 => '\(b\)' }. The TiKz version only showed abcd for the label. But if I replaced dfrac with frac it worked. Does some additional TiKz package need loaded?

TiKz:

image

JSXGraph

image

@drgrice1 drgrice1 force-pushed the plots-custom-ticks branch 2 times, most recently from 0fa3513 to acff063 Compare April 28, 2026 22:40
@drgrice1
Copy link
Copy Markdown
Member Author

I will look into the \dfrac thing. I am not sure what is happening there. latex is giving an undefined control sequence for a \dfrac.

@drgrice1
Copy link
Copy Markdown
Member Author

Ahh, it is because \dfrac is part of the amsmath package. It is not default latex. So you will need to add the amsmath package to use it.

@drgrice1
Copy link
Copy Markdown
Member Author

This is a limitation of the plots.pl macro. It does not give you access to the LaTeXImage object before it is drawn, and so there is not way to add TeX packages.

@somiaj
Copy link
Copy Markdown
Contributor

somiaj commented Apr 28, 2026

Might be worth adding the amsmath package by default? I didn't consider that someone would need access to it, but seems like there is a reason. Ether way, with this people may want to use \dfrac for fraction labels, so we could address this here or another PR if we want to make a more extensible method to allow access to the LaTeXImage object.

@drgrice1 drgrice1 force-pushed the plots-custom-ticks branch from acff063 to ad79b30 Compare May 18, 2026 11:18
@pstaabp
Copy link
Copy Markdown
Member

pstaabp commented May 19, 2026

Could we add another option for tick_labels like:

xtick_labels => ['\(a\)', '\(b\)', '\(c\)'],

that would replace the labels in tick position? I would argue that this would be easier for many authors that don't know/use hashes.

@drgrice1
Copy link
Copy Markdown
Member Author

If you are writing PG problems, you really need to understand at least basic Perl, and knowing how to work with hashes is a basic part of that. The problem is that doing so introduces a lot of ugliness in the code because that approach is entirely unreliable and you have to protect against all of the issues it creates. The fact is that is the wrong data structure for this usage.

So I am going to say no.

@pstaabp
Copy link
Copy Markdown
Member

pstaabp commented May 19, 2026

Seems like the JSXgraph custom labels aren't working. Here's a version of your code above:

DOCUMENT();

loadMacros('PGstandard.pl', 'PGML.pl', 'plots.pl', 'PGcourse.pl');

$plot = Plot(
    xmin            => -2,
    xmax            => 12,
    xtick_distance  => 2,
    xminor          => 1,
    ytick_positions => [ 2, 4, 6 ],
    ytick_labels    => { 2 => '\(a\)', 6 => '\(b\)' },
    ymin            => -2,
    ymax            => 12,
    ytick_distance  => 2,
    yminor          => 1,
);

BEGIN_PGML
[@ $plot->image_type('Tikz'); @]*[!TikZ Image!]{$plot}

[@ $plot->image_type('JSXGraph'); @]*[!JSXGraph Image!]{$plot}
END_PGML

ENDDOCUMENT();

and I see the tikz change the y labels, but not the JSXGraph.

@drgrice1 drgrice1 force-pushed the plots-custom-ticks branch from ad79b30 to 3a99675 Compare May 19, 2026 15:03
@drgrice1
Copy link
Copy Markdown
Member Author

@pstaabp: That is fixed. I don't know why I missed that. The y-axis needs to use the correct coordinate!

@pstaabp
Copy link
Copy Markdown
Member

pstaabp commented May 19, 2026

Fixed!

Copy link
Copy Markdown
Member

@pstaabp pstaabp left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

👍

drgrice1 added 2 commits May 19, 2026 16:43
…ots.pl` macro.

To set custom tick positions use the `tick_positions` axis option.  Set
that to a reference to an array containing the positions on the axis
that ticks are desired.  For example, `tick_positions => [ 2, 5, 9 ]`
will place ticks at positions 2, 5, and 9 on the axis.  Note that when
this option is used the `tick_delta`, `tick_scale`, and `tick_distance`
options are not used. So only the given tick positions will appear in
the graph.

To set custom tick labels use the `tick_labels` option.  Note that this
is not a new option, but now it accepts a new type of value.  Previously
this was purely boolean (0 or 1), and it only determined if tick labels
would be shown or not.  Now it can take a value that is a reference to a
hash.  The keys of the hash are tick positions, and the values are the
labels to be placed at those positons. Note that formatting of the label
must be done by the auther, and the `tick_label_format` option is
ignored for any label provided in this hash. If a major tick is not
listed in the hash, then the position will be used for the label and it
will be formatted according to the `tick_label_format` option.

This is intended to replace what is done in openwebwork#1374 and is a more flexible
approach than what is done there.  In that pull request the capability
for custom tick labels only is added, and it is extremely restrictive in
what it can do.  Only positive tick labels can be customized, and it
requires that the problem author label all major ticks (there is no
fallback and a tick is labeled "undefined" if one is missing).
…the y-axis.

The coordinate for the y-axis is different than for the x-axis.
@drgrice1 drgrice1 force-pushed the plots-custom-ticks branch from 3a99675 to 6bb06e7 Compare May 19, 2026 21:43
@somiaj
Copy link
Copy Markdown
Contributor

somiaj commented May 19, 2026

Two approvals so merging.

@somiaj somiaj merged commit 3d4e945 into openwebwork:PG-2.21 May 19, 2026
3 checks passed
@drgrice1 drgrice1 deleted the plots-custom-ticks branch May 19, 2026 23:10
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants