Skip to content

Add tickmode "proportional" #6827

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
wants to merge 38 commits into
base: master
Choose a base branch
from

Conversation

ayjayt
Copy link
Contributor

@ayjayt ayjayt commented Dec 26, 2023

For #6824:

The basic idea is that we create a mode called 'proportional' which is equivelent to 'array' but values are mapped from proportions before drawn. Then again, array doesn't need to have to be recalculated on zoom, so it's not quite so simple. [0, .5, 1] would be [left-most point, middle, right-most point].

nb: includes my other trivial pull request about meta-charset

TODO:

  • Check if graph is reversed
  • Find where ticks are redrawn on zoom (like in "auto") and make redraw proportional (will probably fix below)
  • Figure out why ticks not redrawn on double click/home
  • Add docs in layout
  • Run tests (make new tests)
  • Use simplemap, not array map
  • Test all other types of cartesian maps:
    • category (disable it, probably?)
    • log
    • date
    • multicategory (disable it, probably?)
  • New task List

- Create tickmode "proportional"
- Map fractional tickvals to axis values w/ axis range:
  - Set ax.(minor?).tickvals to
  - Do that right before `arrayTicks()` is called
- Every instance of `tickmode === "array"` gets `...|| "proportional"`

This works well since tickmode "proportional" really just adds a preprocess step to
tickmode "array".

TODO:

- Check if graph is reversed
- Find where ticks are redrawn on zoom and make redraw proportional (will probably fix below)
- Figure out why ticks not redrawn on double click/home
- Add docs in layout
The algo has to set the tickvals property back to original value after
spoofing it. This does that.
@ayjayt
Copy link
Contributor Author

ayjayt commented Dec 26, 2023

Re: 6d48a3b "Fix bug by which..." and "redrawing issue":

  • Find where ticks are redrawn on zoom (like in "auto") and make redraw proportional (will probably fix below)
  • Figure out why ticks not redrawn on double click/home

Issue was that replacing proportional values with actual values causes exponential tickval increase- each time actual values were to be calcuated, the proportional values used were equal to result of last calculation. This issue is a good argument for adding a whole new property other than tickvals (tickpropvals?)- but the relationship with array is nice for the end user experience.

@ayjayt ayjayt force-pushed the pikul-proportional-ticks branch from 8743766 to 00e884a Compare December 26, 2023 04:57
@ayjayt
Copy link
Contributor Author

ayjayt commented Dec 26, 2023

Alright that's pretty good. One more commit for whatever lint the bot picks up. I'll write tests after I get a response from devs.

Questions for devs:

  • Multicategories, should I even try to support it? It actually works kind of well for regular categories, it can help position the ticks.

Tomorrow, a youtube video with results.

Merry Christmas!
image

@ayjayt
Copy link
Contributor Author

ayjayt commented Dec 27, 2023

This strategy currently doesn't work if both major and minor ticks are proportional because plotly's array-mode conditions in calcTicks are broken. As of now, calcTicks cannot actually separate major and minor tick processing into separate loops (like it claims to do through comments and if (major)) instead processing major and minor ticks in the major loops, and then both again (duplicated) in the minor loops. There are other problems with that: Issue #6828, PR #6829

Plotly does some math on the ticks, sometimes comrparing major and minor
values, so we have to store both in their own separate values and then
restore them to their attribute at the very end so plotly has them
throughout the calculating process.
These tests currently fail but this commit currently doesn't include
fundamental bug fixes.
@ayjayt
Copy link
Contributor Author

ayjayt commented Dec 28, 2023

Alright, the testing is parameterized and randomized:

It tests xaxis.tickmode:'proportional' xaxis.minor.tickmode:'proportional' yaxis.tickmode:'proportional' and yaxis.minor.tickmode:'proportional' in every permutation. Understandably, it's failling as a result of #6828.

All tickval are randomized, both length and values.

It runs for category linear log date type graphs and checks proportions against DOM object properties to verify geometry.

File would obviously be renamed or put into other more relevant location.

I don't understand how this concept would extend to multicategory especially since multicategory is TODO in arrayTicks.

Also, not sure how range padding is calculated but it might be convenient if the user were to know what proportion is added by padding so, eg., w/ autorange, maybe [.05, .95] would have the intended effect of [0, 1].

@ayjayt ayjayt marked this pull request as ready for review December 29, 2023 00:21
@archmoj
Copy link
Contributor

archmoj commented Jan 2, 2024

Interesting PR.
I merged your #6826 pull request.
To simplify the diffs for the reviewers here, I suggest you fetch upstream/master then after git pull, merge master into this branch.
Thank you!

@archmoj archmoj added feature something new community community contribution labels Jan 2, 2024
@ayjayt
Copy link
Contributor Author

ayjayt commented Jan 2, 2024

Two suggestions by Alex coming tonight:

  1. Change Name
  2. Additional mode to allow generation of ticks along domain w/o

Tomrrow:
3) Test for #2 tomorrow

if(nt === 0) {
// pass
} else if(nt === 1) {
tickVals = [0];
Copy link
Collaborator

Choose a reason for hiding this comment

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

Suggested change
tickVals = [0];
tickVals = [0.5];

If you just want one tick I'd put it in the middle. Not that it matters much, this is horrible whatever we choose since you can't tell the scale at all.

Comment on lines 973 to 975
Lib.nestedProperty(ax, 'tickvals').set(tickVals);
} else {
Lib.nestedProperty(ax.minor, 'tickvals').set(tickVals);
Copy link
Collaborator

Choose a reason for hiding this comment

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

We should try to avoid altering real attribute values after the supplyDefaults step. But you can set an underscored attribute like _tickvals if you like, then you just need to look for that in arrayTicks (if you're in one of the domain tickmodes). That should avoid the need to reset it later too, I'd imagine.

Also kudos on figuring out nestedProperty - but it's overkill here since we know the attribute names, you can just do ax._tickvals = tickVals etc - or if you feel like code golf, (major ? ax : ax.minor)._tickvals = tickVals 😎

@ayjayt
Copy link
Contributor Author

ayjayt commented Jan 24, 2024

So, I'm happy to write logic + tests for the tick-mode combination but I need it spelled out (and what do we do if they try a combo that doesn't work?- edit: I'll just take a look at how layout_attribute.js violations handles bad values and probably add the logic in the same place)

To confirm:

Major Tickmode: Auto, Linear
  allow:
    Auto                # (within major ticks)
    Linear              # (absolute values)
    Array               # (absolute values)


Major Tickmode: Array
  allow:
    Linear              # (absolute values)
    Array               # (absolute values)

Major Tickmode: Sync
  allow:
    Sync                # automatic

Major Tickmode: Full Domain
  allow:
    Full Domain         # (within major ticks)
    Domain Array        # (within major ticks)

Major Tickmode: Domain Array
  allow:
    Domain Array        # (within major ticks)

@ayjayt
Copy link
Contributor Author

ayjayt commented Jan 25, 2024

  • Use a private property ax._something instead of overriding ax.tickvals
  • Remove use of Lib.nestedProperty
  • Make some mocks
  • Rework math on minor ticks to be relative to major ticks (what do we do if major ticks is [])
  • Reinspect log math
  • Fail if using domain array/full domain in *category mode (how?)
  • Maybe take a look at sync while I'm here? (@archmoj if you don't mind)
  • Nail down the logic tree for proper major/minor tick combinations

@gvwilson gvwilson added P2 considered for next cycle and removed status: has TODOs labels Aug 8, 2024
@gvwilson
Copy link
Contributor

@ayjayt if you can change the name of the file containing the tests to not include your name, I'll get this one reviewed :-) thanks - @gvwilson

@gvwilson gvwilson self-assigned this Nov 21, 2024
@gvwilson gvwilson added the cs customer success label Nov 21, 2024
@gvwilson gvwilson assigned archmoj and unassigned camdecoster and gvwilson Jul 17, 2025
@archmoj
Copy link
Contributor

archmoj commented Jul 18, 2025

@ayjayt Would you please resolve the conflicts?
Thank you!

'If *array*, the placement of the ticks is set via `tickvals`,',
'which are actual values, and the tick text is `ticktext`.',
'(*array* is the default value if `tickvals` is provided).',
'If *full domain*, the number of ticks is set bia `nticks` but ticks',
Copy link
Contributor

Choose a reason for hiding this comment

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

Suggested change
'If *full domain*, the number of ticks is set bia `nticks` but ticks',
'If *full domain*, the number of ticks is set via `nticks` but ticks',

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
community community contribution cs customer success feature something new P2 considered for next cycle
Projects
None yet
Development

Successfully merging this pull request may close these issues.

6 participants