Add tooltip annotation functionality#7127
Conversation
Implemented style and template handling
I figured it out. |
|
Apologies @kb- - we are trying to get the next Dash and Plotly.py releases out the door, so we're short on cycles for reviewing PRs (particularly ones that touch this many files). I'll try to prioritize it in the next work cycle, but realistically it's going to be at least a couple more weeks :-( Thanks for your patience - @gvwilson |
|
Rebased this PR onto current upstream and fixed the tooltip annotation modebar so it works again after the template-formatting changes that landed since this was opened. What changed:
Verification:
This should now be back in a reviewable state. I realize priorities shift, but since the PR has been dormant for a year, I wanted to surface it again and hope you still consider it. Thanks! |
|
I added an optional callback function. The tooltip feature is now more powerful than the similar one in Matlab😎 |
This PR addresses #7054
The tooltip function can be activated by a new modebar button.
It allows to add an annotation to every clicked point. By default, tooltips contain x, y and when available z, or ohlc data (open, high, low, close).
Tooltips can be customized with an optional tooltiptemplate (leverages existing hovertemplate code) and tooltip annotation options (leverages existing annotations code)

I added examples for various plot types in \test\image\mocks
Additional interactivity:
When a plot is created with
editable: true, the tooltips can be dragged around for placement or deleted interactively. Their text can also be edited. To delete a tooltip, click on its text and delete it.Compatibility:
(active for plots with hasCartesian or hasGL2D)
✓ heatmapgl(trace type no longer exists)✓ pointcloud(trace type no longer exists)Usage example:
Tooltip Annotation - documentation
Overview
Tooltip annotations let users click data points and create persistent Plotly annotations from the modebar. The feature supports three customization layers:
tooltiptemplatefor formatting the annotation texttooltipfor annotation stylingtooltipfunction(ctx)for runtime customization, remapping, or cancellationThis feature is designed for Plotly.js usage in JavaScript. The callback form is runtime-only and is attached directly to the plotted trace object.
Requirements And Activation
To use tooltip annotations:
config.modeBarButtonsToAdd: ['tooltip']editable: trueso created annotations can be edited directly on the graphExample:
editable: trueis recommended because it makes tooltip annotations easier to work with after they are created:Basic Usage With
tooltiptemplatetooltiptemplateuses the same interpolation style ashovertemplate. It controls the text shown inside the created annotation.See Plotly's hovertemplate documentation:
https://plotly.com/javascript/hover-text-and-formatting/
Numeric formatting inside
%{...}uses D3 format syntax, for example%{x:.2f}or%{z:.3e}.See the D3 format syntax reference:
https://d3js.org/d3-format
If no
tooltiptemplateis supplied, Plotly falls back to a built-in default based on the clicked point data, typicallyx,y, andzwhen available.Basic scatter example:
Heatmap or histogram2d example:
Styling With
tooltiptooltipaccepts annotation-style properties. It is merged with Plotly's built-in defaults for tooltip annotations.These are the same annotation-style properties documented in Plotly's text and annotations page:
https://plotly.com/javascript/text-and-annotations/
Common styling fields include:
bgcolorbordercolorfontarrowcolorExample:
Runtime Customization With
tooltipfunction(ctx)tooltipfunction(ctx)is the executable customization layer. It is:gd.data[traceIndex]Attach it after the plot exists:
Return Contract
The callback may return:
falseornullto cancel tooltip creationstringto replace the template text inputobjectwith any of these fields:pointtextannotationstyleMeaning of each object field:
point: merged into the clicked point data beforetooltiptemplateinterpolationtext: replaces the resolved template string before interpolationannotation: overrides fields on the annotation object that Plotly is about to createstyle: adds or overrides annotation styling after the trace-leveltooltipstyle is readExamples for each field:
Example using
point:Example returning a string:
Example using
text:Example cancelling the tooltip:
Example injecting extra fields used by
tooltiptemplate:Example using
annotation:Use
annotationwhen you want to control the annotation object itself, for example:axandayxanchororyanchorExample using
style:ctxReferenceThe callback receives a single
ctxobject with these fields:gdeventDataeventpointtracefullTracecalcdatafullLayoutxaxisyaxisPractical usage of each field:
ctx.gdThe graph div. Use this when you need direct access to the rendered plot object.
ctx.eventDataThe
plotly_clickpayload. Useful when you want the full click event object, including all clicked points.ctx.eventThe raw mouse event. Useful for screen-space calculations such as
clientX,clientY, or DOM target geometry.ctx.pointThe clicked point or bin event data. This is usually the main input for runtime tooltip logic.
Typical values include:
xyzpointIndexorpointIndicespointNumberscustomdatawhen availablectx.traceThe original input trace from
gd.data. This is where runtime-only additions such astooltipfunctionlive.ctx.fullTraceThe fully processed trace from
gd._fullData. It is the plotted version of the trace after Plotly has applied defaults and internal preprocessing. Use it when you need the trace as Plotly is actually using it, not only the raw input you provided ingd.data.ctx.calcdataTrace-specific calcdata. Useful for advanced logic on binned traces such as
histogram2d, where you may want access to computed bins and values.ctx.fullLayoutThe fully processed layout object from the rendered plot. Use it when you need the active layout state that Plotly is currently using, such as the current locale, axis objects, hover mode, subplot internals, or computed defaults.
ctx.xaxisandctx.yaxisThe clicked subplot axes. These are Plotly axis objects with conversion helpers.
Common internal helpers include:
c2p: data coordinate to pixelp2c: pixel to data coordinated2c: displayed value to coordinate, often useful on categorical axesThese helpers are internal Plotly axis methods rather than public top-level API methods, so they are best treated as advanced usage helpers inferred from the current implementation.
See Plotly's event data documentation for the general click-event payload shape:
https://plotly.com/javascript/plotlyjs-events/
customdataIn The CallbackFor direct point-based traces,
customdatais often available directly on the clicked point:For aggregated traces like
histogram2d, a clicked bin usually corresponds to many source samples. In that case, usectx.point.pointIndiceswithctx.trace.customdata:Examples
Example 1: Basic Scatter Tooltip Annotation
Example 2: Programmatic Attachment On An Existing Plot
Example 3: Styling A Tooltip Annotation
Example 4: Histogram2d Or Heatmap Local Maximum
This pattern remaps the tooltip to the strongest value inside a rectangular kernel.
In this example:
kernelSizeXandkernelSizeYare in plot data units, not pixelspoint.x,point.y, andpoint.zchanges both the formatted values and the default arrow anchor positionIf you only return
point.xandpoint.y, the arrow already moves to that remapped point. You only needannotationas well if you want the annotation object itself to differ, for example with a customax,ay,xanchor, or a deliberately differentx/ythan the remapped point.If you want the annotation object itself to differ from the remapped point, add
annotationexplicitly:Example 5: Cancellation
Returning
falseornullis useful for conditional display when only some points or bins should produce tooltip annotations.Caveats And Notes
tooltipfunction(ctx)is synchronous only