@@ -396,10 +396,10 @@ def make_trace_kwargs(args, trace_spec, trace_data, mapping_labels, sizeref):
396
396
if args ["hover_data" ] and isinstance (args ["hover_data" ], dict ):
397
397
for k , v in mapping_labels .items ():
398
398
if k in args ["hover_data" ]:
399
- if args ["hover_data" ][k ]:
400
- if isinstance (args ["hover_data" ][k ], str ):
399
+ if args ["hover_data" ][k ][ 0 ] :
400
+ if isinstance (args ["hover_data" ][k ][ 0 ] , str ):
401
401
mapping_labels_copy [k ] = v .replace (
402
- "}" , "%s}" % args ["hover_data" ][k ]
402
+ "}" , "%s}" % args ["hover_data" ][k ][ 0 ]
403
403
)
404
404
else :
405
405
_ = mapping_labels_copy .pop (k )
@@ -935,6 +935,17 @@ def build_dataframe(args, attrables, array_attrables):
935
935
else :
936
936
df_output [df_input .columns ] = df_input [df_input .columns ]
937
937
938
+ # hover_data is a dict
939
+ hover_data_is_dict = (
940
+ "hover_data" in args
941
+ and args ["hover_data" ]
942
+ and isinstance (args ["hover_data" ], dict )
943
+ )
944
+ if hover_data_is_dict :
945
+ for k in args ["hover_data" ]:
946
+ if not isinstance (args ["hover_data" ][k ], tuple ):
947
+ args ["hover_data" ][k ] = (args ["hover_data" ][k ], None )
948
+
938
949
# Loop over possible arguments
939
950
for field_name in attrables :
940
951
# Massaging variables
@@ -970,15 +981,20 @@ def build_dataframe(args, attrables, array_attrables):
970
981
if isinstance (argument , str ) or isinstance (
971
982
argument , int
972
983
): # just a column name given as str or int
973
- if not df_provided :
984
+ bypass_warnings = (
985
+ hover_data_is_dict
986
+ and argument in args ["hover_data" ]
987
+ and args ["hover_data" ][argument ][1 ]
988
+ )
989
+ if not df_provided and not bypass_warnings :
974
990
raise ValueError (
975
991
"String or int arguments are only possible when a "
976
992
"DataFrame or an array is provided in the `data_frame` "
977
993
"argument. No DataFrame was provided, but argument "
978
994
"'%s' is of type str or int." % field
979
995
)
980
996
# Check validity of column name
981
- if argument not in df_input .columns :
997
+ if not bypass_warnings and argument not in df_input .columns :
982
998
err_msg = (
983
999
"Value of '%s' is not the name of a column in 'data_frame'. "
984
1000
"Expected one of %s but received: %s"
@@ -989,7 +1005,7 @@ def build_dataframe(args, attrables, array_attrables):
989
1005
"\n To use the index, pass it in directly as `df.index`."
990
1006
)
991
1007
raise ValueError (err_msg )
992
- if length and len (df_input [argument ]) != length :
1008
+ if not bypass_warnings and length and len (df_input [argument ]) != length :
993
1009
raise ValueError (
994
1010
"All arguments should have the same length. "
995
1011
"The length of column argument `df[%s]` is %d, whereas the "
@@ -1002,7 +1018,14 @@ def build_dataframe(args, attrables, array_attrables):
1002
1018
)
1003
1019
)
1004
1020
col_name = str (argument )
1005
- df_output [col_name ] = df_input [argument ].values
1021
+ if (
1022
+ field_name == "hover_data"
1023
+ and hover_data_is_dict
1024
+ and args ["hover_data" ][col_name ][1 ]
1025
+ ):
1026
+ df_output [col_name ] = args ["hover_data" ][col_name ][1 ]
1027
+ else :
1028
+ df_output [col_name ] = df_input [argument ].values
1006
1029
# ----------------- argument is a column / array / list.... -------
1007
1030
else :
1008
1031
is_index = isinstance (argument , pd .RangeIndex )
0 commit comments