Skip to content
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

feature: custom axis labeling from kernel side (tick_labels). #1526

Merged
merged 1 commit into from Sep 29, 2022

Conversation

maartenbreddels
Copy link
Member

This allows any custom labeling from the kernel side, and code reuse of labeling code for bqplot and matplotlib.
While I think it's always good to have more scales, there is always a use case of not being able to let the scales+axis do what you want.
Using tick_values was already useful, but in combination with the new tick_labels (dict that maps values to labels) users have ultimate freedom to position and format the ticks on that axis.

Listening to min and max on the scales, we can update the ticks when we pan (no code example for that yet).

e.g.:

# given a locator and formatter
import numpy as np

def locator(xmin, xmax, ticks=5):
    # Given view interval, returns the ticks to show in data coordinates
    return (xmin + (xmax - xmin) * np.linspace(0, 1, ticks) ** 0.5).astype(int)

def formatter(x, pos=None):
    # Given x values in data coordinates, return the label to show
    return f'{100 * int(x):.1f}nm'

We can use that for matplotlib (code by @astrofrog ):

import numpy as np

def locator(xmin, xmax, ticks=5):
    # Given view interval, returns the ticks to show in data coordinates
    return (xmin + (xmax - xmin) * np.linspace(0, 1, ticks) ** 0.5).astype(int)

def formatter(x, pos=None):
    # Given x values in data coordinates, return the label to show
    return f'{100 * int(x):.1f}nm'

And also use that in bqplot (yes, react-ipywidget code 😛 )

import react_ipywidgets as react
import react_ipywidgets.bqplot as bq
import react_ipywidgets.ipywidgets as w
import bqplot


@react.component
def Plot():
    ticks, set_ticks = react.use_state(4)

    y = data = np.random.random((64, ))
    x = np.arange(len(y))

    x_min = 0
    x_max = len(data) - 1
    # x is in 'data' coordinates
    x_scale = bq.LinearScale(allow_padding=False, min=x_min, max=x_max)

    # use the same locator as matplotlib code
    tick_values = locator(x_min, x_max, ticks)
    ymax = None
    y_scale = bq.LinearScale(min=0, max=ymax)
    display_legend = True
    color = 'red'
    label = 'test'

    lines = bq.Lines(x=x, y=y, scales={"x": x_scale, "y": y_scale}, stroke_width=3, colors=[color], display_legend=display_legend, labels=[label])

    # same formatted as matplotlib code
    tick_labels = {k:formatter(k) for k in tick_values}
    # using .element because the wrapper does not know tick_labels yet
    x_axis = bqplot.Axis.element(scale=x_scale, tick_labels=tick_labels, tick_values=tick_values)
    y_axis = bq.Axis(scale=y_scale, orientation="vertical")
    with w.VBox() as main:
        w.IntSlider(value=ticks, on_value=set_ticks, description="Ticks")
        bq.Figure(axes=[x_axis, y_axis],
                  marks=[lines],
                  scale_x=x_scale,
                  scale_y=y_scale,
                  layout={"min_width": "800px"})
    return main
        
Plot()

Giving:
image

See also the notebook example, where I added roman numbering:

image

Copy link
Member

@martinRenou martinRenou left a comment

Choose a reason for hiding this comment

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

Thanks!

@martinRenou martinRenou merged commit 138dc5f into bqplot:0.12.x Sep 29, 2022
@martinRenou martinRenou deleted the feat_axis_tick_labels branch September 29, 2022 14:13
@martinRenou
Copy link
Member

meeseeksdev please backport to master

meeseeksmachine pushed a commit to meeseeksmachine/bqplot that referenced this pull request Sep 29, 2022
martinRenou added a commit that referenced this pull request Sep 29, 2022
…6-on-master

Backport PR #1526 on branch master (feature: custom axis labeling from kernel side (tick_labels).)
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.

None yet

2 participants