Black Lives Matter. Please consider donating to Black Girls Code today.

How to customize Plotly Tooltip

Can you share a code snippet of what you attempted so far? This will help understand what exactly you’re trying to do. Thanks.

Here is the link to the sample : https://jsfiddle.net/sjselvan/3q42oxhh/?utm_source=website&utm_medium=embed&utm_campaign=3q42oxhh

It looks like the x pixel position is always undefined and it has nothing to do with the x-axis ticks.

All I’m trying to do is to replace the default tool tip with a custom tooltip for the box & whisker which will show [Max: 5 , Upper Quartile: 3, Median : 3, Lower Quartile : 3, Min : 2, Time : 10:45 - 11:00, Random_Property:Value].

  1. I need to get the X, Y pixel position to set the custom tooltip div position
  2. would like to know the way to pass custom values to the chart that i can later use it to display them in the tooltip.
  3. Is there a way to add a text to the box and whisker something similar to the ‘text’ property for a line chart. I can skip (1) and (2) If (3) is possible

Here’s how to get the boxes corresponding calc data on hover (which is essentially the set of datum we use to draw things internally) -> https://jsfiddle.net/3q42oxhh/1/

You might want to look at Boxplot hoverinfo text not display

Thanks @etienne. I’m able to add a text using annotations. I’ll post the complete solution soon.

@etienne Is there a way to

  1. display the annotations only on mouse over?
  2. also position the annotation just above the max value? I face issues when i set the Y-axis type as ‘log’.

https://jsfiddle.net/sjselvan/3q42oxhh/3/

See https://jsfiddle.net/3q42oxhh/5/

You might want to try xanchor and yanchor to fine-tuned the positioning of your annotations.

Hi @etienne,

I’ve a similar use case like @nithyaranim, but this time within a heatmap.

I’m using the l2p (what’s this acronym standing for?) in combination with the pointNumber data to get a relative positioning within the heatmap. It looks like:

x: point.xaxis.l2p(point.pointNumber[1]),
y: point.yaxis.l2p(point.pointNumber[0])

But the problem with that is that it is relative to the top/left origin of the heatmap svg itself without the outer x- and y-axis labels, so I’m actually missing that part and wonder about whether there isn’t a built-in functionality to get this positioning information directly? The problem is that using external divs as tooltip area that they are located completely outside of the chart and with that I need the information with reference to the top/left origin outside of the chart and the axis labeling.

What seems to work is to use the axis private _offset property and add it to the x and y positions above, so I get

x: point.xaxis.l2p(point.pointNumber[1]) + point.xaxis._offset,
y: point.yaxis.l2p(point.pointNumber[0]) + point.yaxis._offset

But that looks quite nasty to me. Can you point me to some documentation or demo on how to do that “the plotly way” esp. for the heatmap?

Thx in advance,

Andreas

1 Like

That stands for linear-to-pixel.

Unfortunately, that’s properly the best we have available at the moment.

We’re hoping to clean up our event data in v2. See https://github.com/plotly/plotly.js/issues/420 for more info.

1 Like

Hi etienne,

ok. Thx nevertheless. I will then look forward for the v2 release.

Hi @andi1984, thanks for your solution to this, It’s very helpful to me.

@etienne I’m working off of this example, but what if I resize the chart?

How can I get the

point.yaxis.l2p(point.pointNumber[0])

of a point that hasn’t triggered the ‘plotly_hover’ callback? Is there I way I can search for the updated point’s data (maybe by where it is in the index of the array) after I call Plotly.relayout ?

1 Like

thisLayer.on(“plotly_hover” (pointData) => {
const info = pointData.points.map((d) => {
const yaxis = pointData.points[0].yaxis;
const xaxis = pointData.points[0].xaxis;
const distY = yaxis.l2p(d.y) + yaxis._offset; //
const distX = xaxis.l2p(d.x) + xaxis._offset;
this.tooltipStyle = “left:” + distX + "px; " + “top:” + distY + “px;”;
}
});
This will work to calculate the exact point where the tooltip must be shown, but the thing is that you should avoid pointer events on the tooltip or it will blink when hovered . Just add “pointer-events: none;” to your tooltip css.

2 Likes

Hi @etienne,

I’m also trying to implement a custom tooltip, but am having difficulty getting the pixel coordinate for non-numeric axes.
Eg: https://codepen.io/Person21/pen/evBeMr

The x-coordinate is undefined. This is because l2p returns BADNUM if the input is not a number.

Is there any way to get the pixel value for a non-numeric axis?

2 Likes

d2p seems could work for non-numeric axes. But I am not 100% sure.

Thanks, it works!
Just a note to anybody else who wants to use this: d2p is only available for plotly 1.21 and above.

1 Like

Dear @etienne,
This thread is very helpful, I tried to replace the default tooltip with my customized one, it seems to work:

Let me know whether this is the correct way to customize the tooltip. Thanks.

Also my own tooltip doesn’t seem to be as “stable” as the original one, it’s very sensitive to mouse move, is there any way to fix this? Thank you!

1 Like

Hello,
I’m trying to implement a custom tooltip for a pie chart but there is no xaxis/yaxis properties in the ‘hover event data’. So no way to use l2p/d2p function or do I missed something? If not, I would like to know if there is another way to get an x/y coordinate where I can attach the tooltip?

Thanks in advance,
Cédric

@pppw
I know this is an old thread, but it’s been immensely helpful to me, so I wanted to add this here for anyone that didn’t glean it from Manuel’s post above. Adding the ‘pointer-events: none;’ makes the tooltip “stable” like the default one.

@Cedric I found a “hack” to get more detailed data for the hover:

            var addEventDataFn = function (chart) {
                $.each(chart._fullData, function(key, val) {
                    if (val._module.eventData) {
                        return true;
                    }
                    val._module.eventData = function eventData(out, pt, trace, cd, pointNumber) {
                        out = $.extend(out, pt);
                        return out;
                    };
                });
            };

Plotly.react(myGraphDiv).then(function () {
    addEventDataFn(myGraphDiv);
});

(Attention: It uses jQuery)

With this the data contains all the needed information to construct your own hover-effect.

Hope this code-snipped helps a lot of people out there. But beware: If the chart-type defines this function already and provides less data it can make problems, so this case is not reflected yet.

2 Likes

Is there a way to modify what’s displayed on hover for a US county choropleth (Python)? Right now it shows “value” but that’s very confusing for my graph; I want it to show “population” instead. Also, I’ve had some criticism that absolutely no one knows what FIPS are, so I would like to change that to “county code”. At the very least, it would be nice if I could disable the FIPS from showing on hover, but keep the other stuff in the hover box. As far as I can tell, I can only switch the hover from True to False, but then there’s no info.

Thanks!

1 Like

Not sure if this works for county maps, but adding hoverinfo='location+text' to my state choropleth map’s data dictionary worked perfectly for me. The info you want displayed on mouseover should go in your df['text'] column, with each line separated by <br>.

This is what your text column should look like:
‘Inspection Fees: 4<br>Settlement Services: 10<br>Title Insurance: 9<br>Total: 23’

image

hoverinfo (flaglist string)
Any combination of "location", "z", "text", "name" joined with a "+" OR "all" or "none" or "skip".
examples: "location", "z", "location+z", "location+z+text", "all"
default: "all"
Determines which trace information appear on hover. If none or skip are set, no information is displayed upon hovering. But, if none is set, click and hover events are still fired.