如何循环在Plotly中创建子图,其中每个子图上都有一些曲线? [英] how to loop to create subplots in Plotly, where each subplot has a few curves on it?

查看:40
本文介绍了如何循环在Plotly中创建子图,其中每个子图上都有一些曲线?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我已经在嵌套循环下面编写了成功的21张图表(每个国家一张图表,例如

I already wrote below nested loops to generate 21 charts with success (one chart for each country, for example german gas austrian gas)

dfs is a dict with 21 countries names as keys and their respective gas storage dfs as values

for country in list(dfs_storage.keys()):
    df_country=dfs_storage[country]
    month = list(set(df_country['month']))
    fig = go.Figure()
    for year in set(df_country['year']):
        workingGasVolume_peryear=df_country.loc[df_country['year']==year,'workingGasVolume']
        gasInStorage_peryear=df_country.loc[df_country['year']==year,'gasInStorage']
        # Create and style traces
        fig.add_trace(go.Scatter(x=month, y=workingGasVolume_peryear, name=f'workingGasVolume{year}',
                                 line=dict(width=4,dash='dash')))
        fig.add_trace(go.Scatter(x=month, y=gasInStorage_peryear, name=f'gasInStorage{year}',
                                 line = dict(width=4)))

    # Edit the layout
    fig.update_layout(title=f'{country} workingGasVolume gasInStorage',
                       xaxis_title='Month',
                       yaxis_title='Gas Volume')

    offline.plot({'data':fig},filename=f'{country} gas storage.html',auto_open=False)

Now I am asked to put these 21 charts in one HTML file without changing each chart, they can appear vertically one after another for example

I tried the "subplots" with Plotly with below code and modified a few times but never have the desired chart, I got one single useless chart where I can't see any values.. Can anyone help me? Thanks

countries=[]
for country in list(dfs_storage.keys()):
    countries.append(country)
fig = make_subplots(
    rows=len(list(dfs_storage.keys())),cols=1,
    subplot_titles=(countries))

for country in countries:
    df_country=dfs_storage[country]
    month = list(set(df_country['month']))
    for year in set(df_country['year']):
        workingGasVolume_peryear=df_country.loc[df_country['year']==year,'workingGasVolume']
        gasInStorage_peryear=df_country.loc[df_country['year']==year,'gasInStorage']
        # Create and style traces
        fig.add_trace(go.Scatter(x=month, y=workingGasVolume_peryear, name=f'workingGasVolume{year}',
                                 line=dict(width=4,dash='dash')))
        fig.add_trace(go.Scatter(x=month, y=gasInStorage_peryear, name=f'gasInStorage{year}',
                                 line = dict(width=4)))

    # Edit the layout
# fig.update_layout(title='workingGasVolume gasInStorage',
#                    xaxis_title='Month',
#                    yaxis_title='Gas Volume')

offline.plot({'data':fig},filename='gas storage.html',auto_open=False) 

Edit 7th June: as per jayveesea's advice, I added the row and col argument under add_trace, the code is below but still has Traceback:

countries=[]
for country in list(dfs_storage.keys()):
    countries.append(country)
fig = make_subplots(
    rows=len(list(dfs_storage.keys())),cols=1,
    subplot_titles=(countries))

for i in range(len(countries)):
    country=countries[i]
    df_country=dfs_storage[country]
    month = list(set(df_country['month']))
    for year in set(df_country['year']):
        workingGasVolume_peryear=df_country.loc[df_country['year']==year,'workingGasVolume']
        gasInStorage_peryear=df_country.loc[df_country['year']==year,'gasInStorage']
        # Create and style traces
        fig.add_trace(go.Scatter(x=month, y=workingGasVolume_peryear, name=f'workingGasVolume{year}',row=i,col=1,
                                 line=dict(width=4,dash='dash')))
        fig.add_trace(go.Scatter(x=month, y=gasInStorage_peryear, name=f'gasInStorage{year}',row=i,col=1,
                                 line = dict(width=4)))

    # Edit the layout
# fig.update_layout(title='workingGasVolume gasInStorage',
#                    xaxis_title='Month',
#                    yaxis_title='Gas Volume')

offline.plot({'data':fig},filename='gas storage.html',auto_open=False)

print('the Plotly charts are saved in the same folder as the Python code')

Edit 8th June: This is the code I am running now, copied from @jayveesea's answer and only modified the name of the df

countries=[]
for country in list(dfs_storage.keys()):
    countries.append(country)
# STEP 1
fig = make_subplots(
    rows=len(countries), cols=1,
    subplot_titles=(countries))

for i, country in enumerate(countries): #enumerate here to get access to i
    years = df_country.year[df_country.country==country].unique()
    for yrs in years:
        focus = (df_country.country==country) & (df_country.year==yrs)
        month = df_country.month[focus]
        workingGasVolume_peryear = df_country.workingGasVolume[focus]
        gasInStorage_peryear = df_country.gasInStorage[focus]

        # STEP 2, notice position of arguments!
        fig.add_trace(go.Scatter(x=month, 
                                 y=workingGasVolume_peryear, 
                                 name=f'workingGasVolume{yrs}',
                                 line=dict(width=4,dash='dash')),
                      row=i+1, #index for the subplot, i+1 because plotly starts with 1
                      col=1)
        fig.add_trace(go.Scatter(x=month, 
                                 y=gasInStorage_peryear, 
                                 name=f'gasInStorage{yrs}',
                                 line = dict(width=4)),
                      row=i+1,
                      col=1)      
fig.show()

Yet I still have Traceback message

Traceback (most recent call last):

  File "<ipython-input-27-513826172e49>", line 43, in <module>
    line=dict(width=4,dash='dash')),

TypeError: 'dict' object is not callable

解决方案

To use subplots in plotly you need to:

  1. use make_subplots to initialize the layout specifying the row and column
  2. then use row and col as arguments to fig.add_trace. NOTE: subplots row and columns start at 1 (not zero)

In your case, step2 is where you are getting stuck. Initially this part was missing (first post), but now in your update it's added in as an argument to go.Scatter. Carefully look over the examples here as the differences are just commas and parentheses and their placement.

To clarify, this:

fig.add_trace(go.Scatter(x=month, 
                         y=workingGasVolume_peryear, 
                         name=f'workingGasVolume{year}',
                         row=i,
                         col=1,
                         line=dict(width=4,dash='dash')))

should be:

fig.add_trace(go.Scatter(x=month, 
                         y=workingGasVolume_peryear, 
                         name=f'workingGasVolume{year}',
                         line=dict(width=4,dash='dash')),
              row=i+1,
              col=1)

I'm having difficulty with your code and data, which could be on my end as I do not use dictionaries like this, but here is a working example with your data in a csv and the use of pandas. Also, I changed one of the years to a different country so that there would be another plot.

import pandas as pd
import plotly.graph_objects as go  
from plotly.subplots import make_subplots

df = pd.read_csv('someData.csv')
countries = df.country.unique()

# STEP 1
fig = make_subplots(
    rows=len(countries), cols=1,
    subplot_titles=(countries))

for i, country in enumerate(countries): #enumerate here to get access to i
    years = df.year[df.country==country].unique()
    for yrs in years:
        focus = (df.country==country) & (df.year==yrs)
        month = df.month[focus]
        workingGasVolume_peryear = df.workingGasVolume[focus]
        gasInStorage_peryear = df.gasInStorage[focus]

        # STEP 2, notice position of arguments!
        fig.add_trace(go.Scatter(x=month, 
                                 y=workingGasVolume_peryear, 
                                 name=f'workingGasVolume{yrs}',
                                 line=dict(width=4,dash='dash')
                                ),
                      row=i+1, #index for the subplot, i+1 because plotly starts with 1
                      col=1)
        fig.add_trace(go.Scatter(x=month, 
                                 y=gasInStorage_peryear, 
                                 name=f'gasInStorage{yrs}',
                                 line = dict(width=4)),
                      row=i+1,
                      col=1)      
fig.show()

这篇关于如何循环在Plotly中创建子图,其中每个子图上都有一些曲线?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
相关文章
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆