如何从 pandas 数据框的每一列创建子图。

5

我有一个名为 'df' 的数据框,其中包含36列。使用以下代码将这些列绘制到单个 Plotly 图表中,并以 html 格式显示。

import plotly.offline as py
import plotly.io as pio

pio.write_html(py.offline.plot([{
'x': df.index,
'y': df[col],
'name': col
}for col in trend_data.columns], filename=new_file_path))

我希望能够遍历每一列,为每一列创建一个子图。我的尝试如下:

from plotly.subplots import make_subplots

sub_titles = df.columns()
fig = make_subplots(rows=6, cols=6, start_cell="bottom-left", subplot_titles=sub_titles)
for i in df.columns:
    fig.add_trace(i)

我创建了6行和列,这将给出36个图表,并尝试使用标题名称作为子图标题,但我得到了一个ValueError,指出它期望一个由字典组成的二维列表。

此外,我已尝试通过以下方式添加子图标题:

sub_titles = list(df)
fig = py.subplots.make_subplots(rows=6, cols=6, sub_titles=sub_titles)

这也返回一个错误。任何帮助都将不胜感激。
2个回答

7

情节:

输入图像描述

代码:

# imports
from plotly.subplots import make_subplots
import plotly.graph_objs as go
import pandas as pd
import numpy as np

# data
np.random.seed(123)
frame_rows = 50
n_plots = 36
frame_columns = ['V_'+str(e) for e in list(range(n_plots+1))]
df = pd.DataFrame(np.random.uniform(-10,10,size=(frame_rows, len(frame_columns))),
                  index=pd.date_range('1/1/2020', periods=frame_rows),
                    columns=frame_columns)
df=df.cumsum()+100
df.iloc[0]=100

# plotly setup
plot_rows=6
plot_cols=6
fig = make_subplots(rows=plot_rows, cols=plot_cols)

# add traces
x = 0
for i in range(1, plot_rows + 1):
    for j in range(1, plot_cols + 1):
        #print(str(i)+ ', ' + str(j))
        fig.add_trace(go.Scatter(x=df.index, y=df[df.columns[x]].values,
                                 name = df.columns[x],
                                 mode = 'lines'),
                     row=i,
                     col=j)

        x=x+1

# Format and show fig
fig.update_layout(height=1200, width=1200)
fig.show()

补充: 一列式解决方案:

代码:

# imports
from plotly.subplots import make_subplots
import plotly.graph_objs as go
import pandas as pd
import numpy as np

# data
np.random.seed(123)
frame_rows = 50
frame_columns = ['V_'+str(e) for e in list(range(1,37))]
df = pd.DataFrame(np.random.uniform(-8,10,size=(frame_rows, len(frame_columns))),
                  index=pd.date_range('1/1/2020', periods=frame_rows),
                    columns=frame_columns)
df=df.cumsum()+100
df.iloc[0]=100

# plotly setup
plot_rows=6
plot_cols=6

lst1 = list(range(1,plot_rows+1))
lst2 = list(range(1,plot_cols+1))

fig = make_subplots(rows=36, cols=1, subplot_titles=df.columns, insets=[{'l': 0.1, 'b': 0.1, 'h':1}])

# add traces
x = 1
for i in lst1:
    for j in lst2:
        #print(str(i)+ ', ' + str(j))
        fig.add_trace(go.Scatter(x=df.index, y=df[df.columns[x-1]].values,
                                 name = df.columns[x-1],
                                 mode = 'lines',
                                 ),

                      row=x,
                     col=1)

        x=x+1

fig.update_layout(height=12000, width=1200)

fig.show()

图表:

在此输入图片描述


谢谢您,有可能将图表放大,然后滚动页面以便更详细地查看它们吗?我无法想出如何实现这一点。 - Iceberg_Slim
1
@Jay 这取决于您在哪里生成图表。也许是在Jupyter Notebook中? - vestland
我正在使用PyCharm来生成图表。你刚刚调整了fig.update_layout以获得巨大的长度吗? - Iceberg_Slim
1
@Jay 是的,我做了:fig.update_layout(height=12000, width=1200) - vestland

3

请参阅文档,了解如何使用子图。 可以这样做:

更新包括子图标题

fig = py.subplots.make_subplots(rows=36, cols=1, subplot_titles=df.columns)
j = 1
for i in df.columns:
    fig.add_trace(
        go.Scatter(
            {'x': df.index, 
             'y': df[i]}), 
             row=j, col=1)
    j += 1

这导致以下图表显示(使用我的数据):
df = pd.DataFrame(np.random.randint(5, size=(5, 3)), columns=['one', 'two', 'three'])

subplots


很好运行!如果我想将列标题分配为子图名称,我该怎么做?我尝试了以下代码:sub_titles = list(df) fig = py.subplots.make_subplots(rows=6, cols=6, sub_titles=sub_titles) - Iceberg_Slim
1
@Jay,你想要这个以6x6的设置吗? - vestland
谢谢。@vestland 理想情况下,我希望只有一列,但这样会使图表变得非常小,难以查看。是否可以使生成的 HTML 页面可滚动? - Iceberg_Slim

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接