简体   繁体   English

Plotly:将多个图形绘制为子图

[英]Plotly: Plot multiple figures as subplots

These resources show how to take data from a single Pandas DataFrame and plot different columns subplots on a Plotly graph.这些资源展示了如何从单个 Pandas DataFrame 获取数据并在 Plotly 图上绘制不同的列子图。 I'm interested in creating figures from separate DataFrames and plotting them to the same graph as subplots.我有兴趣从单独的 DataFrame 创建图形并将它们绘制到与子图相同的图形中。 Is this possible with Plotly?这可以用 Plotly 实现吗?

https://plot.ly/python/subplots/ https://plot.ly/python/subplots/

https://plot.ly/pandas/subplots/ https://plot.ly/pandas/subplots/

I'm creating each figure from a dataframe like this:我正在从这样的数据框中创建每个图形:

import pandas as pd
import cufflinks as cf
from plotly.offline import download_plotlyjs, plot,iplot
cf.go_offline()

fig1 = df.iplot(kind='bar',barmode='stack',x='Type',
                       y=mylist,asFigure=True)

Edit: Here is an example based on Naren's feedback:编辑:这是一个基于 Naren 反馈的示例:

Create the dataframes:创建数据框:

a={'catagory':['loc1','loc2','loc3'],'dogs':[1,5,6],'cats':[3,1,4],'birds':[4,12,2]}
df1 = pd.DataFrame(a)
b={'catagory':['loc1','loc2','loc3'],'dogs':[12,3,5],'cats':[4,6,1],'birds':[7,0,8]}
df2 = pd.DataFrame(b)

The plot will just show the information for the dogs, not the birds or cats:该图将只显示狗的信息,而不是鸟或猫的信息:

fig = tls.make_subplots(rows=2, cols=1)

fig1 = df1.iplot(kind='bar',barmode='stack',x='catagory',
                       y=['dogs','cats','birds'],asFigure=True)

fig.append_trace(fig1['data'][0], 1, 1)

fig2 = df2.iplot(kind='bar',barmode='stack',x='catagory',
                       y=['dogs','cats','birds'],asFigure=True)

fig.append_trace(fig2['data'][0], 2, 1)

iplot(fig)

只显示了狗,而不是猫或鸟:

Here's a short function in a working example to save a list of figures all to a single HTML file.这是一个工作示例中的一个简短函数,用于将所有图形列表保存到单个 HTML 文件中。

def figures_to_html(figs, filename="dashboard.html"):
    dashboard = open(filename, 'w')
    dashboard.write("<html><head></head><body>" + "\n")
    for fig in figs:
        inner_html = fig.to_html().split('<body>')[1].split('</body>')[0]
        dashboard.write(inner_html)
    dashboard.write("</body></html>" + "\n")


# Example figures
import plotly.express as px
gapminder = px.data.gapminder().query("country=='Canada'")
fig1 = px.line(gapminder, x="year", y="lifeExp", title='Life expectancy in Canada')
gapminder = px.data.gapminder().query("continent=='Oceania'")
fig2 = px.line(gapminder, x="year", y="lifeExp", color='country')
gapminder = px.data.gapminder().query("continent != 'Asia'")
fig3 = px.line(gapminder, x="year", y="lifeExp", color="continent",
               line_group="country", hover_name="country")

figures_to_html([fig1, fig2, fig3])

在此处输入图片说明

You can get a dashboard that contains several charts with legends next to each one:您可以获得一个仪表板,其中包含多个图表,每个图表旁边都有图例:

import plotly
import plotly.offline as py
import plotly.graph_objs as go
fichier_html_graphs=open("DASHBOARD.html",'w')
fichier_html_graphs.write("<html><head></head><body>"+"\n")

i=0
while 1:
    if i<=40:
        i=i+1


        #______________________________--Plotly--______________________________________


        color1 = '#00bfff'
        color2 = '#ff4000'

        trace1 = go.Bar(
            x = ['2017-09-25','2017-09-26','2017-09-27','2017-09-28','2017-09-29','2017-09-30','2017-10-01'],
            y = [25,100,20,7,38,170,200],
            name='Debit',
            marker=dict(
                color=color1
            )

        )
        trace2 = go.Scatter(

            x=['2017-09-25','2017-09-26','2017-09-27','2017-09-28','2017-09-29','2017-09-30','2017-10-01'],
            y = [3,50,20,7,38,60,100],
            name='Taux',
            yaxis='y2'

        )
        data = [trace1, trace2]
        layout = go.Layout(
            title= ('Chart Number: '+str(i)),
            titlefont=dict(
            family='Courier New, monospace',
            size=15,
            color='#7f7f7f'
            ),
            paper_bgcolor='rgba(0,0,0,0)',
            plot_bgcolor='rgba(0,0,0,0)',

            yaxis=dict(
                title='Bandwidth Mbit/s',
                titlefont=dict(
                    color=color1
                ),
                tickfont=dict(
                    color=color1
                )
            ),
            yaxis2=dict(
                title='Ratio %',
                overlaying='y',
                side='right',
                titlefont=dict(
                    color=color2
                ),
                tickfont=dict(
                    color=color2
                )

            )

        )
        fig = go.Figure(data=data, layout=layout)
        plotly.offline.plot(fig, filename='Chart_'+str(i)+'.html',auto_open=False)
        fichier_html_graphs.write("  <object data=\""+'Chart_'+str(i)+'.html'+"\" width=\"650\" height=\"500\"></object>"+"\n")
    else:
        break


fichier_html_graphs.write("</body></html>")
print("CHECK YOUR DASHBOARD.html In the current directory")

Result:结果:

在此处输入图片说明

You can also try the following using cufflinks:您还可以使用袖扣尝试以下方法:

cf.subplots([df1.figure(kind='bar',categories='category'),
         df2.figure(kind='bar',categories='category')],shape=(2,1)).iplot()

And this should give you:这应该给你:

New Answer:新答案:

We need to loop through each of the animals and append a new trace to generate what you need.我们需要遍历每个动物并附加一个新的跟踪以生成您需要的内容。 This will give the desired output I am hoping.这将提供我希望的所需输出。

import pandas as pd
import numpy as np
import cufflinks as cf
import plotly.tools as tls
from plotly.offline import download_plotlyjs, plot,iplot
cf.go_offline()
import random

def generate_random_color():
    r = lambda: random.randint(0,255)
    return '#%02X%02X%02X' % (r(),r(),r())

a={'catagory':['loc1','loc2','loc3'],'dogs':[1,5,6],'cats':[3,1,4],'birds':[4,12,2]}
df1 = pd.DataFrame(a)
b={'catagory':['loc1','loc2','loc3'],'dogs':[12,3,5],'cats':[4,6,1],'birds':[7,0,8]}
df2 = pd.DataFrame(b)

#shared Xaxis parameter can make this graph look even better
fig = tls.make_subplots(rows=2, cols=1)

for animal in ['dogs','cats','birds']: 
    animal_color = generate_random_color()
    fig1 = df1.iplot(kind='bar',barmode='stack',x='catagory',
                       y=animal,asFigure=True,showlegend=False, color = animal_color)
    fig.append_trace(fig1['data'][0], 1, 1)

    fig2 = df2.iplot(kind='bar',barmode='stack',x='catagory',
                       y=animal,asFigure=True, showlegend=False, color = animal_color)
    #if we do not use the below line there will be two legend
    fig2['data'][0]['showlegend'] = False

    fig.append_trace(fig2['data'][0], 2, 1)
    #additional bonus
    #use the below command to use the bar chart three mode
    # [stack, overlay, group]
    #as shown below
    #fig['layout']['barmode'] = 'overlay'
iplot(fig)

Output:输出: 堆积子图条形图

Old Answer:旧答案:

This will be the solution这将是解决方案

Explanation:说明:

Plotly tools has a subplot function to create subplots you should read the documentation for more details here . Plotly 工具有一个 subplot 函数来创建子图,您应该在这里阅读文档以获取更多详细信息。 So I first use cufflinks to create a figure of the bar chart.所以我首先使用袖扣来创建条形图的图形。 One thing to note is cufflinks create and object with both data and layout.需要注意的一件事是袖扣使用数据和布局创建和对象。 Plotly will only take one layout parameter as input, hence I take only the data parameter from the cufflinks figure and append_trace it to the make_suplots object. Plotly 将只采用一个布局参数作为输入,因此我只采用袖扣图中的数据参数并将其 append_trace 附加到 make_suplots 对象。 so fig.append_trace() the second parameter is row number and third parameter is column number所以 fig.append_trace() 第二个参数是行号,第三个参数是列号

import pandas as pd
import cufflinks as cf
import numpy as np
import plotly.tools as tls
from plotly.offline import download_plotlyjs, plot,iplot
cf.go_offline()

fig = tls.make_subplots(rows=2, cols=1)

df = pd.DataFrame(np.random.randint(0,100,size=(100, 4)), columns=list('ABCD'))
fig1 = df.iplot(kind='bar',barmode='stack',x='A',
                       y='B',asFigure=True)
fig.append_trace(fig1['data'][0], 1, 1)
df2 = pd.DataFrame(np.random.randint(0,100,size=(100, 4)), columns=list('EFGH'))
fig2 = df2.iplot(kind='bar',barmode='stack',x='E',
                       y='F',asFigure=True)
fig.append_trace(fig2['data'][0], 2, 1)
iplot(fig)

If you want to add a common layout to the subplot I suggest that you do如果您想向子图添加通用布局,我建议您这样做

fig.append_trace(fig2['data'][0], 2, 1)
fig['layout']['showlegend'] = False
iplot(fig)

or even甚至

fig.append_trace(fig2['data'][0], 2, 1)
fig['layout'].update(fig1['layout'])
iplot(fig)

So in the first example before plotting, I access the individual parameters of the layout object and change them, you need to go through layout object properties for refernce.所以在绘图前的第一个示例中,我访问了布局对象的各个参数并对其进行了更改,您需要通过布局对象属性进行参考。

In the second example before plotting, I update the layout of the figure with the cufflinks generated layout this will produce the same output as we see in cufflinks.在绘图之前的第二个示例中,我使用袖扣生成的布局更新图形的布局,这将产生与我们在袖扣中看到的相同的输出。

You've already received a few suggestions that work perfectly well.您已经收到了一些非常有效的建议。 They do however require a lot of coding.然而,它们确实需要大量编码。 Facet / trellis plots using px.bar() will let you produce the plot below using ( almost ) only this:使用px.bar()面/格状图将使您仅使用(几乎)生成以下图:

px.bar(df, x="category", y="dogs", facet_row="Source")

在此处输入图片说明

The only extra steps you'll have to take is to introduce a variable on which to split your data, and then gather or concatenate your dataframes like this:您唯一需要采取的额外步骤是引入一个用于拆分数据的变量,然后像这样收集或连接数据帧:

df1['Source'] = 1
df2['Source'] = 2
df = pd.concat([df1, df2])

And if you'd like to include the other variables as well, just do:如果您还想包含其他变量,只需执行以下操作:

fig = px.bar(df, x="category", y=["dogs", "cats", "birds"], facet_row="Source")
fig.update_layout(barmode = 'group')

在此处输入图片说明

Complete code:完整代码:

# imports
import plotly.express as px
import pandas as pd

# data building
a={'category':['loc1','loc2','loc3'],'dogs':[1,5,6],'cats':[3,1,4],'birds':[4,12,2]}
df1 = pd.DataFrame(a)
b={'category':['loc1','loc2','loc3'],'dogs':[12,3,5],'cats':[4,6,1],'birds':[7,0,8]}
df2 = pd.DataFrame(b)

# data processing 
df1['Source'] = 1
df2['Source'] = 2
df = pd.concat([df1, df2])

# plotly figure
fig = px.bar(df, x="category", y="dogs", facet_row="Source")
fig.show()

#fig = px.bar(df, x="category", y=["dogs", "cats", "birds"], facet_row="Source")
#fig.update_layout(barmode = 'group')

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM