Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Hoverinformation for shapes in plotly

I know there is the hovertemplate/hover_text/ option for traces (marker/line) but I cannot find such a thing for shapes. Is there a way to have a hover text pop up when moving over a shape? Maybe a workaround?

Example:

import plotly.graph_objects as go

fig = go.Figure()

fig.add_trace(go.Scatter(
    x=[1.5, 3],
    y=[2.5, 2.5],
    text=["Rectangle reference to the plot",
          "Rectangle reference to the axes"],
    mode="markers",
))
fig.add_shape(
        # Rectangle reference to the plot
            type="rect",
            xref="paper",
            yref="paper",
            x0=0.25,
            y0=0,
            x1=0.5,
            y1=0.5,
            line=dict(
                color="LightSeaGreen",
                width=3,
            ),
            fillcolor="PaleTurquoise",
        )

When I hover over the two points, I get a hover-template with information. How can I get something similar for the shape?

like image 946
Dana_Miles Avatar asked Jun 05 '20 16:06

Dana_Miles


2 Answers

It seems that it's not possible to add hoverinfo to shapes directly. But you can obtain something very close to what seems to be the desired effect through the right combination of shapes and traces. The following plot is made from specifying two rectangles in a list like:

shapes = [[2,6,2,6],
          [4,7,4,7]]

The rest of the code snippet is set up to be flexible with regards to the number of shapes, and the colors assigned to them and the corresponding traces to make that little dot in the lower right corners of the shapes.

Plot:

enter image description here

If this is something you can use, we can discuss ways to edit what is being displayed in the hoverinfo.

Complete code:

# Imports
import pandas as pd
#import matplotlib.pyplot as plt
import numpy as np
import plotly.graph_objects as go
import plotly.express as px

# shape definitions
shapes = [[2,6,2,6],
          [4,7,4,7]]

# color management
# define colors as a list 
colors = px.colors.qualitative.Plotly

# convert plotly hex colors to rgba to enable transparency adjustments
def hex_rgba(hex, transparency):
    col_hex = hex.lstrip('#')
    col_rgb = list(int(col_hex[i:i+2], 16) for i in (0, 2, 4))
    col_rgb.extend([transparency])
    areacol = tuple(col_rgb)
    return areacol

rgba = [hex_rgba(c, transparency=0.4) for c in colors]
colCycle = ['rgba'+str(elem) for elem in rgba]

# plotly setup
fig = go.Figure()

# shapes
for i, s in enumerate(shapes):
    fig.add_shape(dict(type="rect",
                        x0=s[0],
                        y0=s[2],
                        x1=s[1],
                        y1=s[3],
                        layer='above',
                        fillcolor=colCycle[i],
                        line=dict(
                            color=colors[i],
                            width=3)))

# traces as dots in the lower right corner for each shape
for i, s in enumerate(shapes):
    fig.add_trace(go.Scatter(x=[s[1]], y=[s[2]], name = "Hoverinfo " +str(i + 1),
                             showlegend=False,
                             mode='markers', marker=dict(color = colors[i], size=12)))

    # edit layout
fig.update_layout(yaxis=dict(range=[0,8], showgrid=True),
                  xaxis=dict(range=[0,8], showgrid=True))
fig.show()
like image 194
vestland Avatar answered Nov 12 '22 05:11

vestland


I thought of a solution I am happy with. Simply draw a shape. You won't be able to see a hover text. However, if you add a trace with a fill on top of the shape, then set the trace to opacity=0 you will see the hover text from the trace pop up when moving over the shape. Again, thanks for your responses!

import plotly.graph_objects as go    

# Draw shape (you won't be able to add a hover text for it)
fig = go.Figure()
    fig.add_shape(
        type="rect",
        x0=0, y0=0,
        x1=4, y1=3,
        fillcolor='LightSkyBlue',
        line_color='Blue',
        name='Shape 1'
    )

    # Adding a trace with a fill, setting opacity to 0
    fig.add_trace(
        go.Scatter(
            x=[0,0,4,4,0], 
            y=[0,3,3,0,0], 
            fill="toself",
            mode='lines',
            name='',
            text='Custom text on top of shape',
            opacity=0
        )
    )
    fig.show()
like image 24
Dana_Miles Avatar answered Nov 12 '22 07:11

Dana_Miles