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

Add box-based zoom support for interval selections. #4742

Open
tweeter0830 opened this issue Mar 20, 2019 · 24 comments
Open

Add box-based zoom support for interval selections. #4742

tweeter0830 opened this issue Mar 20, 2019 · 24 comments
Assignees
Labels
Milestone

Comments

@tweeter0830
Copy link

I spend a lot of time looking at engineering time-series data.

I currently use bokeh for this, but I would love to switch to vega/vega-lite/altair.

However, I'm hesitant to switch because vega appears to be missing a box-zoom feature. This feature is incredibly useful for exploratory time-series plotting/analysis.

As an example, my data often looks like a more complex version of this bokeh example.

There may be many phenomenon of different x/y axis scales which get manifested in time-series data and being able to change the zoom level/aspect ratio is incredibly useful.

Basically, I would love to see Bokeh's BoxZoomTool (as enabled in the box_annotaion example above) in vega/vega-lite/altair.

@jheer
Copy link
Member

jheer commented Mar 20, 2019

Thanks for posting! The good news is that what you describe is already expressible within Vega. Here is a modified zoomable scatterplot example. You can shift-drag to create a zoom region, and when you release the mouse button the view will snap to the new scale extents. You can also double click to restore the chart to the initial configuration. Note that this works alongside standard drag-pan and scroll-zoom interactions. Or, here is the same example within an Observable notebook: https://observablehq.com/@vega/vega-interactive-scatter-plot

The less good news is that I don't think this is currently expressible in Vega-Lite / Altair. However, I could imagine extensions to the interval selection logic that would change that. So, I'm going to rename this issue and transfer it over to the Vega-Lite repo for folks to look at there!

@jheer jheer changed the title Add support for box/rectangle zoom Add box-based zoom support for interval selections. Mar 20, 2019
@jheer jheer transferred this issue from vega/vega Mar 20, 2019
@tweeter0830
Copy link
Author

Oh cool! It's good to know that this is one step closer to being in Altair. Thanks for moving the bug over.

@arvind arvind added this to the 4.0 milestone May 17, 2019
@kanitw kanitw added the P2 Important Issues that should be fixed soon label Jun 6, 2019
@kanitw kanitw modified the milestones: 4.1, 4.x Dec 5, 2019
@pramitchoudhary
Copy link

This feature would be great.

@domoritz
Copy link
Member

domoritz commented May 6, 2020

@allenjlee are you working on this? If not, let's unassign you.

@robsmith11
Copy link

Is there any alternative to getting interactive zooming of arbitrary regions of a plot working with vega-lite?

@kanitw kanitw added the P1 Critical -- to fix ASAP label Oct 3, 2021
@kanitw kanitw self-assigned this Oct 3, 2021
@Episkiliski
Copy link

Is there any development on this yet? Thanks!

@arvind
Copy link
Member

arvind commented Feb 1, 2022

No updates yet, unfortunately. Sorry.

@Episkiliski
Copy link

Is there any plan for this? Or is it just in the backlog with no plans at the moment? Thanks!

@domoritz
Copy link
Member

domoritz commented Feb 1, 2022

It's in the backlog but I think @kanitw wanted to address this issue so it's higher up in the queue. He can comment on the timing.

If this is not urgent, we should remove the P1.

@Episkiliski
Copy link

It would be great and I understand many folks are waiting for this feature too. Having the hability to box-zoom is sometimes a must for some data exploration. So yeah, I'm really looking forward to this...

@bendasse
Copy link

I'm looking forward to this too, if it's possible with Vega-lite. Thanks !

@kanitw kanitw removed the P2 Important Issues that should be fixed soon label Mar 10, 2022
@krokosik
Copy link

krokosik commented Jun 2, 2022

I'm also really looking forward to this feature. If there is any way I can help with this, let me know

@wisp3rwind
Copy link

Not quite the real thing, but a workaround is to zoom x- and y-axis independently via Selection projection and event filters depending on whether the shift key is held:

(in Altair)

selection_x = alt.selection_interval(
    bind='scales',
    encodings=["x"],
    zoom="wheel![!event.shiftKey]",
)
selection_y = alt.selection_interval(
    bind='scales',
    encodings=["y"],
    zoom="wheel![event.shiftKey]",
)
chart = (alt.Chart(...)
    ...
    .add_selection(selection_x)
    .add_selection(selection_y)
)

(in vega-lite)

{
  ...
  "selection": {
    "selectorx": {
      "bind": "scales",
      "encodings": [
        "x"
      ],
      "type": "interval",
      "zoom": "wheel![!event.shiftKey]"
    },
    "selectory": {
      "bind": "scales",
      "encodings": [
        "y"
      ],
      "type": "interval",
      "zoom": "wheel![event.shiftKey]"
    }
  },
}

@Episkiliski

This comment has been minimized.

@samimia-swks
Copy link

The lack of this feature is holding Altair back compared to plotly, bokeh, etc

@thomascamminady
Copy link

I agree with @samimia-swks: This is arguably the one feature that holds back altair. Especially for time-series analysis, our team still sticks with seaborn because zooming into the data is crucial. I really love vega-lite / altair, I think the grammar of graphics approach is the best way to deal with data and I love feature like cross-filtering and the interactivity that's already present at the moment.

@domoritz asked in Feb 1, 2022 whether this is "not urgent". I'd argue that this is currently one of the most urgent features. Would there be any way to prioritize this feature?

@domoritz
Copy link
Member

I think @kanitw was also excited about box based zoom.

Since most of us are volunteers, the best way to prioritize features is to describe use cases, help design what the feature looks like, prototype (manually) in Vega, or to send pull requests.

@thomascamminady
Copy link

Thanks for the reply! I will try to lay out the use case and see whether I could get something to work in Vega. Really appreciate the effort everyone is putting into these packages! Thanks so much for that!

@thomascamminady
Copy link

thomascamminady commented Apr 19, 2024

So I tried to modify the "Overview and Detail" demo.
image

I discarded the second plot to only have the top plot and turned that into vega code that I paste below.

However, now the zoom is broken because as you click to select a rectangular region, the zoom is already applied.
I think I found a spot that I thought I might need to modify:

        {
          "name": "brush_tuple_fields",
          "value": [
            {
              "field": "date",
              "channel": "x",
              "type": "R"
            }
          ]
        },

If you remove the "type":"R", you get to properly select a box, as shown in this video:

demo.mov

However, now nothing happens with the selection. I thought I would just have to change "R" to "pointerup" or something like that but that does not work. I think that if on mouse release, the box is applied, that would already be the solution.

Full example gist

@thomascamminady
Copy link

Maybe I'm overthinking this. Could it be as simple as finding the correct way for the on field to only trigger after the release of the click?

{
  "$schema": "https://vega.github.io/schema/vega-lite/v5.json",
  "data": {"url": "data/sp500.csv"},
    "width": 480,
    "height": 60,
    "mark": "area",
    "params": [{
      "name": "brush",
      "select": {
        "type": "interval", 
        "encodings": ["x"],
         "on": "[pointerdown, pointerup] > pointermove"
        }
    }],
    "encoding": {
      "x": {
        "field": "date",
        "type": "temporal",
        "scale": {"domain": {"param": "brush"}}
      },
      "y": {
        "field": "price",
        "type": "quantitative",
        "axis": {"tickCount": 3, "grid": false}
      }
    }
}

https://vega.github.io/editor/#/url/vega-lite/N4IgJAzgxgFgpgWwIYgFwhgF0wBwqgegIDc4BzJAOjIEtMYBXAI0poHsDp5kTykBaADZ04JAKyUAVhDYA7EABoQAEySYUqUAwBOgtCrVJOOMQAZTlKBGIgAvkoDuNZfTQAWAByml8GmSxoAGzeIMjaANb6SNpwKEo40UgIEGgA2qCySXD6TNoMEDCKIBBwgnBQmGigmACeONnoNLKYcNrESHpKcLJQbMpNZCmoqSAAHiAAukpy+qk4bE0t2spsDrIKAATzi60MOBMbAHxbC82tCGykdrZTIN29-bJkVWMvAGY0pcr6qi1FtfV9C0EPNtB0itAOg1QCtkE0XgkwQgcnkCtd7CAau9PoJvugcNoaFBskoAQ0QABHBhIZp0NQ0K5KJCjGhDapE8IAYTYDGaaAAzEoyIS8W8OiVbJLbEA

@PBI-David
Copy link
Contributor

Drawing a box can be copied from here: https://vega.github.io/editor/#/examples/vega/brushing-scatter-plots

You just then need to link that to a zoom.

@thomascamminady
Copy link

Not sure I fully understand @PBI-David. The brush is linked, I just need to delay the action of updating the interval until I stop clicking the mouse?

@PBI-David
Copy link
Contributor

I was showing that a box zoom can be created using the same logic on that Vega example. The first part is drawing a box (the example I showed) and the second is zooming the domain.

@thomascamminady
Copy link

I think I got a very rough first version of this working.

I started with the overview and detail example. From that, I removed the lower chart to have everything integrated into one chart. That's this code

{
    "$schema": "https://vega.github.io/schema/vega-lite/v5.json",
    "data": {
        "url": "data/sp500.csv"
    },
    "width": 480,
    "mark": "area",
    "params": [
        {
            "name": "brush",
            "select": {
                "type": "interval",
                "encodings": [
                    "x"
                ]
            }
        }
    ],
    "encoding": {
        "x": {
            "field": "date",
            "type": "temporal",
            "scale": {
                "domain": {
                    "param": "brush"
                }
            },
            "axis": {
                "title": ""
            }
        },
        "y": {
            "field": "price",
            "type": "quantitative"
        }
    }
}

Now this is broken because as soon as you start selecting a range, the image starts to zoom.

I then looked at the compiled Vega code.

Here, I substitute

        {
          "events": {
            "source": "window",
            "type": "pointermove",
            "consume": true,
            "between": [
              {
                "source": "scope",
                "type": "pointerdown",
                "filter": [
                  "!event.item || event.item.mark.name !== \"brush_brush\""
                ]
              },
              {
                "source": "window",
                "type": "pointerup"
              }
            ]
          },
          "update": "[brush_x[0], clamp(x(unit), 0, width)]"
        },

with

 {
          "events": {
            "source": "window",
            "type": "pointerup",
            "consume": true
          },
          "update": "[brush_x[0], clamp(x(unit), 0, width)]"
        },

to get this example. When you start selecting a range, the box that highlights the reason is not drawn but upon mouse release, you zoom into the right subdomain.
If we could add the highlighting of the current selection back and only trigger the zoom on pointerup, this could already be a good starting point. Unfortunately, I'm unable to decouple the zoom from the drawing of the background.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

No branches or pull requests