2

I have a dataFrame for example:

In [1]: import pandas as pd

In [2]: df = pd.DataFrame(data = [{'key': '1', 'value': '1', 'metadata': '3'}, {'key': '2', 'value': '2', 'metadata': '3'}, {'key': '1', 'value': '3', 'metadata': '3'}, {'key': '2', 'value': '4', 'metadata':
   ...: '3'}])

In [3]: df
Out[3]: 
  key value metadata
0   1     1        3
1   2     2        3
2   1     3        3
3   2     4        3

I want to split the df by the "key", i.e.

In [4]: df_list = [d for _, d in df.groupby(['key'])]

In [5]: df_list
Out[5]: 
[  key value metadata
 0   1     1        3
 2   1     3        3,
   key value metadata
 1   2     2        3
 3   2     4        3]

Now I have list of N (2) dataFrames based on number of unique keys. How can I plot this using plotly?

I can

In [6]: import plotly.express as px

In [7]: fig = px.line(df_list[0])

but how can I add the other lines? plotly.express.Figure has no add_line method...

1 Answer 1

4

Running plotly.express wil return a plotly.graph_objs._figure.Figure object. The same goes for plotly.graph_objects with go.Figure(). So after building a figure using plotly express, you can add lines or traces using:

fig.add_trace(go.Scatter)

Or:

fig.add_scatter()

Other options are:

fig.add_area()
fig.add_bar()

After building a fig you can run dir(fig) to learn more.

So in a dataframe such as this:

   2021  2022  2023
0     0     0     0
1     0    -1    -2
2    -1    -1    -3
3    -1    -2    -2
4    -1    -1    -3

You can add line / trace to an existing figure using:

fig.add_trace(go.Scatter(x = df.index, y = df['2023']))

If you prefer to keep control of subsets of your data through dictionaries, one approach to add several traces is this:

extra = {'2024': df['2024'],
         '2025': df['2025']}

for k, v in extra.items():
    fig.add_scatter(x=v.index, y = v, name = k + ' from dict' )

enter image description here

Complete code:

import pandas as pd
import numpy as np
import plotly
import plotly.express as px
import plotly.graph_objects as go

# data
np.random.seed(1)
start = 2021
ncols = 6
nrows = 1000
cols = [str(i) for i in np.arange(start, start+ncols)]
df = pd.DataFrame(np.random.randint(-1,2, (nrows,ncols)), columns = cols).cumsum()
df.iloc[0] = 0

# figure
fig = px.line(df, x=df.index, y=cols[:-4])
fig.update_layout(template = 'plotly_dark')

# fig.add_trace(go.Scatter(x = df.index, y = df['2023'], name = '2023 = added trace'))

fig.add_scatter(x = df.index, y = df['2023'], name = '2023 from add_trace')


extra = {'2024': df['2024'],
         '2025': df['2025']}

for k, v in extra.items():
    fig.add_scatter(x=v.index, y = v, name = k + ' from dict' )

fig.show()
Sign up to request clarification or add additional context in comments.

4 Comments

Your answer seems really great, but I think I had asked the wrong question... This is my csv: Device,Name,Stable Temperature (C),metadata 01:00.0,a,40,foo 03:00.0,a,42,foo 01:00.0,b,38,foo 03:00.0,b,44,foo 01:00.0,c,41,foo 03:00.0,c,42,foo 01:00.0,d,20,foo 03:00.0,d,28,foo And I want to plot it so that variable=device, x=name, y=temperature, and the metadata is a hover - I can't make your answer stick in this situation
@CIsForCookies Include a sample of your data as described here, and I'm sure we can make it stick.
{'Device': {0: '01:00.0', 1: '03:00.0', 2: '01:00.0', 3: '03:00.0', 4: '01:00.0', 5: '03:00.0', 6: '01:00.0', 7: '03:00.0'}, 'Name': {0: 'a', 1: 'a', 2: 'b', 3: 'b', 4: 'c', 5: 'c', 6: 'd', 7: 'd'}, 'Stable Temperature (C)': {0: 40, 1: 42, 2: 38, 3: 44, 4: 41, 5: 42, 6: 20, 7: 28}, 'metadata': {0: 'foo', 1: 'foo', 2: 'foo', 3: 'foo', 4: 'foo', 5: 'foo', 6: 'foo', 7: 'foo'}}
btw, I'm looking into pd.melt - as I think it will give a concise solution. No success yet..

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.