Repository: plotly/plotly.py
Pull request: fixed bug in hover data
Closes #2529 

Problem statement:
hover_data formatting don't work if labels is assigned.
I'm working with the latest version `plotly.__version__ ==  '4.8.1'`. If I add `labels` the formatting in `hover_data` is not working.


```python
import pandas as pd
import plotly.express as px

diz = {'bins': {0: 'till 500',
  1: 'till 500',
  2: '501-600',
  3: '501-600',
  4: 'more 601',
  5: 'more 601'},
 'data': {0: 4, 1: 26, 2: 15, 3: 35, 4: 41, 5: 9},
 'longitude': {0: 12.5,
  1: 65.5,
  2: 122.58333,
  3: 12.58333,
  4: -115.53333,
  5: 55.53333},
 'latitude': {0: 27.5, 1: 29.5, 2: 45.36667, 3: 55.36667, 4: 38.08, 5: -38.08},
 'names': {0: 'Name2',
  1: 'Name4',
  2: 'Name1',
  3: 'Name5',
  4: 'Name3',
  5: 'Name6'}}

df = pd.DataFrame(diz)

fig = px.scatter_geo(df,
                     lon='longitude',
                     lat='latitude',
                     color='bins',
                     color_discrete_sequence=px.colors.qualitative.Set1,
                     hover_name="names",
                     size='data',
                     opacity=0.7,
                     projection="equirectangular",
                     size_max=35,
                     hover_data={"longitude": False,
                                 "latitude": False,
                                 "names": False,
                                 "data": ":.2f"},
                    # If one comment out the following two lines
                   # "data" is formatted as in hover_data
                     labels={"bins": "Bin",
                                  "data": "Data"}
                   )
fig.show()

```

Hints from issue discussion:

Commit message: fixed bug in hover data

Patch to review:
diff --git a/packages/python/plotly/plotly/express/_core.py b/packages/python/plotly/plotly/express/_core.py
index df600555b14..30690abca5c 100644
--- a/packages/python/plotly/plotly/express/_core.py
+++ b/packages/python/plotly/plotly/express/_core.py
@@ -116,6 +116,14 @@ def get_label(args, column):
         return column
 
 
+def invert_label(args, column):
+    reversed_labels = {value: key for (key, value) in args["labels"].items()}
+    try:
+        return reversed_labels[column]
+    except Exception:
+        return column
+
+
 def _is_continuous(df, col_name):
     return df[col_name].dtype.kind in "ifc"
 
@@ -434,11 +442,12 @@ def make_trace_kwargs(args, trace_spec, trace_data, mapping_labels, sizeref):
         mapping_labels_copy = OrderedDict(mapping_labels)
         if args["hover_data"] and isinstance(args["hover_data"], dict):
             for k, v in mapping_labels.items():
-                if k in args["hover_data"]:
-                    if args["hover_data"][k][0]:
-                        if isinstance(args["hover_data"][k][0], str):
+                k_args = invert_label(args, k)
+                if k_args in args["hover_data"]:
+                    if args["hover_data"][k_args][0]:
+                        if isinstance(args["hover_data"][k_args][0], str):
                             mapping_labels_copy[k] = v.replace(
-                                "}", "%s}" % args["hover_data"][k][0]
+                                "}", "%s}" % args["hover_data"][k_args][0]
                             )
                     else:
                         _ = mapping_labels_copy.pop(k)
diff --git a/packages/python/plotly/plotly/tests/test_core/test_px/test_px_hover.py b/packages/python/plotly/plotly/tests/test_core/test_px/test_px_hover.py
index f63696e8dee..07d0e201a43 100644
--- a/packages/python/plotly/plotly/tests/test_core/test_px/test_px_hover.py
+++ b/packages/python/plotly/plotly/tests/test_core/test_px/test_px_hover.py
@@ -72,6 +72,18 @@ def test_newdatain_hover_data():
         )
 
 
+def test_formatted_hover_and_labels():
+    df = px.data.tips()
+    fig = px.scatter(
+        df,
+        x="tip",
+        y="total_bill",
+        hover_data={"total_bill": ":.1f"},
+        labels={"total_bill": "Total bill"},
+    )
+    assert ":.1f" in fig.data[0].hovertemplate
+
+
 def test_fail_wrong_column():
     with pytest.raises(ValueError) as err_msg:
         px.scatter(


Code review comments:
diff_hunk: @@ -116,6 +116,14 @@ def get_label(args, column):
         return column
 
 
+def invert_label(args, column):
+    reversed_labels = {value: key for (key, value) in args["labels"].items()}
path: packages/python/plotly/plotly/express/_core.py
text: @author:
This works because the default for `args["labels"]` is set to `{}` but probably we should use `None` instead, what do you think @user1 ?

@user1:
Yes we should stop using `{}` as defaults :)

Here btw there's a potential issue if people use the same label for two things... this is a bad idea for a user to do but... ?


@author:
I created https://github.com/plotly/plotly.py/issues/2562 to talk about this issue since it already exists before this PR.