18

The goal is to plot some data using plotly where the text param contains multiple columns.

Here is my DataFrame:

import pandas as pd
import numpy as np
import plotly as py
import plotly.graph_objs as go

np.random.seed(1)
df = pd.DataFrame({'Mean Age': np.random.randint(40,60,10),
                   'Percent': np.random.randint(20,80,10),
                   'Number Column': np.random.randint(100,500,10)},
                  index=list('ABCDEFGHIJ'))

df.index.name = 'Text Column'
df = df.sort_values('Mean Age')

Here is an example of how I plotted the data with text from one column to show on hover:

# trace for Percent
trace0 = go.Scatter(
    x = df.index,
    y = df['Percent'],
    name = 'Percent',
    text = df['Mean Age'], # text to show on hover from df column
    mode = 'lines+markers',
    line = dict(
        color = ('rgb(0,0,255)'), # blue
        width = 4)
)

layout = dict(title = 'Test Plot',
             xaxis = dict(title = 'Text Column'),
             yaxis = dict(title = 'Percent'),
              )

data = [trace0]
fig = dict(data=data, layout=layout)

py.offline.plot(fig, filename = 'Test_Plot.html')

I am looking to add another column's data to the text param. I can accomplish this by doing some list comprehensions but is there an easier/more efficient way to do this?

I am looking for an output similar to what is below but in a more efficient way than using list comprehension:

# column values to list
num = list(df['Number Column'])
age = list(df['Mean Age'])


# trace for Percent
trace0 = go.Scatter(
    x = df.index,
    y = df['Percent'],
    name = 'Percent',
    # list comprehension to get the data to show
    text = [f'Number Column: {x}; Mean Age: {y}' for x,y in list(zip(num, age))],
    mode = 'lines+markers',
    line = dict(
        color = ('rgb(0,0,255)'), # blue
        width = 4)
)

layout = dict(title = 'Test Plot',
             xaxis = dict(title = 'Text Column'),
             yaxis = dict(title = 'Percent'),
              )

data = [trace0]
fig = dict(data=data, layout=layout)

py.offline.plot(fig, filename = 'Test_Plot_Output.html')
3
  • 3
    text needs to be (string or array of strings) according to the documentation, so I guess you are stuck here. Optimizing the list comprehension seems the only option. Commented Jan 26, 2019 at 18:33
  • 2
    @MaximilianPeters thanks for that information. I just read the documentation and found something interesting...As you mentioned it can be an array of strings; however, the series or rather ndarray of df['Mean Age] is numpy.int32 and it works despite being array of int32. Irregardless, I suppose I can do something like list(map(str, zip(df['Mean Age'], df['Number Column']))), which should be faster than list comprehension. Commented Jan 26, 2019 at 20:46
  • 1
    In a lot of cases instead of arrays any iterable can be used with Plotly. In order to get the information from Python to Plotly's JS library everything will be serialized a JSON anyways. Commented Jan 27, 2019 at 0:06

1 Answer 1

9

You could also do something along the lines of the following:

trace0 = go.Scatter(
    x = df.index,
    y = df['Percent'],
    name = 'Percent',
    # string concatenation in pandas
    # also the <br> puts the data on a new line in the hover text
    text = "Number Column: " + df["Number Column"].astype(str) + "<br>Mean Age: " + df["Mean Age"].astype(str),
    mode = 'lines+markers',
    line = dict(
        color = ('rgb(0,0,255)'),  # blue
        width = 4)
)
Sign up to request clarification or add additional context in comments.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.