Show Sidebar Hide Sidebar

Table and Chart Subplots in Python

How to create a subplot with tables and charts in Python with Plotly.

New to Plotly?¶

Plotly's Python library is free and open source! Get started by downloading the client and reading the primer.
You can set up Plotly to work in online or offline mode, or in jupyter notebooks.
We also have a quick-reference cheatsheet (new!) to help you get started!

Version Check¶

Note: Tables are available in version 2.1.0+
Run pip install plotly --upgrade to update your Plotly version

In [2]:
import plotly
plotly.__version__
Out[2]:
'2.2.2'

Import CSV Data¶

In [6]:
import plotly.plotly as py
import plotly.graph_objs as go

import pandas as pd
import re

df = pd.read_csv('https://raw.githubusercontent.com/plotly/datasets/master/Mining-BTC-180.csv')

# remove min:sec:millisec from dates 
for i, row in enumerate(df['Date']):
    p = re.compile(' 00:00:00')
    datetime = p.split(df['Date'][i])[0]
    df.iloc[i, 1] = datetime

table = go.Table(
    columnwidth=[0.4, 0.47, 0.48, 0.4, 0.4, 0.45, 0.5, 0.6],
    header=dict(
        #values=list(df.columns[1:]),
        values=['Date', 'Number<br>Transactions', 'Output<br>Volume (BTC)',
                'Market<br>Price', 'Hash<br>Rate', 'Cost per<br>trans-USD',
                'Mining<br>Revenue-USD', 'Trasaction<br>fees-BTC'],
        font=dict(size=10),
        line = dict(color='rgb(50, 50, 50)'),
        align = 'left',
        fill = dict(color='#d562be'),
    ),
    cells=dict(
        values=[df[k].tolist() for k in df.columns[1:]],
        line = dict(color='rgb(50, 50, 50)'),
        align = 'left',
        fill = dict(color='#f5f5fa')
    )
)
py.iplot([table], filename='table-of-mining-data')
Out[6]:

Table and Right Aligned Plots¶

In Plotly there is no native way to insert a Plotly Table into a Subplot. To do this, create your own Layout object and defining multiple xaxis and yaxis to split up the chart area into different domains. Then for the traces you wish to insert in your final chart, set their xaxis and yaxis individually to map to the domains definied in the Layout. See the example below to see how to align 3 Scatter plots to the right and a Table on the top.

In [4]:
import plotly.plotly as py
import plotly.graph_objs as go

import numpy as np
import pandas as pd

table_trace1 = go.Table(
    domain=dict(x=[0, 0.5],
                y=[0, 1.0]),
    columnwidth = [30] + [33, 35, 33],
    columnorder=[0, 1, 2, 3, 4],
    header = dict(height = 50,
                  values = [['<b>Date</b>'],['<b>Number<br>transactions</b>'],
                            ['<b>Output<br>volume(BTC)</b>'], ['<b>Market<br>Price</b>']],
                  line = dict(color='rgb(50, 50, 50)'),
                  align = ['left'] * 5,
                  font = dict(color=['rgb(45, 45, 45)'] * 5, size=14),
                  fill = dict(color='#d562be')),
    cells = dict(values = [df[k].tolist() for k in
                          ['Date', 'Number-transactions', 'Output-volume(BTC)', 'Market-price']],
                 line = dict(color='#506784'),
                 align = ['left'] * 5,
                 font = dict(color=['rgb(40, 40, 40)'] * 5, size=12),
                 format = [None] + [", .2f"] * 2 + [',.4f'],
                 prefix = [None] * 2 + ['$', u'\u20BF'],
                 suffix=[None] * 4,
                 height = 27,
                 fill = dict(color=['rgb(235, 193, 238)', 'rgba(228, 222, 249, 0.65)']))
)

trace1=go.Scatter(
    x=df['Date'],
    y=df['Hash-rate'],
    xaxis='x1',
    yaxis='y1',
    mode='lines',
    line=dict(width=2, color='#9748a1'),
    name='hash-rate-TH/s'
)

trace2=go.Scatter(
    x=df['Date'],
    y=df['Mining-revenue-USD'],
    xaxis='x2',
    yaxis='y2',
    mode='lines',
    line=dict(width=2, color='#b04553'),
    name='mining revenue'
)

trace3=go.Scatter(
    x=df['Date'],
    y=df['Transaction-fees-BTC'],
    xaxis='x3',
    yaxis='y3',
    mode='lines',
    line=dict(width=2, color='#af7bbd'),
    name='transact-fee'
)

axis=dict(
    showline=True,
    zeroline=False,
    showgrid=True,
    mirror=True,
    ticklen=4, 
    gridcolor='#ffffff',
    tickfont=dict(size=10)
)

layout1 = dict(
    width=950,
    height=800,
    autosize=False,
    title='Bitcoin mining stats for 180 days',
    margin = dict(t=100),
    showlegend=False,   
    xaxis1=dict(axis, **dict(domain=[0.55, 1], anchor='y1', showticklabels=False)),
    xaxis2=dict(axis, **dict(domain=[0.55, 1], anchor='y2', showticklabels=False)),        
    xaxis3=dict(axis, **dict(domain=[0.55, 1], anchor='y3')), 
    yaxis1=dict(axis, **dict(domain=[0.66, 1.0], anchor='x1', hoverformat='.2f')),  
    yaxis2=dict(axis, **dict(domain=[0.3 + 0.03, 0.63], anchor='x2', tickprefix='$', hoverformat='.2f')),
    yaxis3=dict(axis, **dict(domain=[0.0, 0.3], anchor='x3', tickprefix=u'\u20BF', hoverformat='.2f')),
    plot_bgcolor='rgba(228, 222, 249, 0.65)'
)

fig1 = dict(data=[table_trace1, trace1, trace2, trace3], layout=layout1)
py.iplot(fig1, filename='table-right-aligned-plots')
Out[4]:

Vertical Table and Graph Subplot¶

In [5]:
import plotly.plotly as py
import plotly.graph_objs as go

table_trace2 = go.Table(
    domain=dict(x=[0, 1],
                y=[0.7, 1.0]),  
    columnwidth=[1, 2, 2, 2],
    columnorder=[0, 1, 2, 3, 4],
    header = dict(height = 50,
                  values = [['<b>Date</b>'],['<b>Hash Rate, TH/sec</b>'], 
                            ['<b>Mining revenue</b>'], ['<b>Transaction fees</b>']], 
                  line = dict(color='rgb(50, 50, 50)'),
                  align = ['left'] * 5,
                  font = dict(color=['rgb(45, 45, 45)'] * 5, size=14),
                  fill = dict(color='#d562be')),
    cells = dict(values = [df[k].tolist() for k in ['Date', 'Hash-rate', 'Mining-revenue-USD', 'Transaction-fees-BTC']],
                 line = dict(color='#506784'),
                 align = ['left'] * 5,
                 font = dict(color=['rgb(40, 40, 40)'] * 5, size=12),
                 format = [None] + [", .2f"] * 2 + [',.4f'],  
                 prefix = [None] * 2 + ['$', u'\u20BF'],
                 suffix=[None] * 4,
                 height = 27,
                 fill = dict(color=['rgb(235, 193, 238)', 'rgba(228, 222, 249, 0.65)']))
)

trace4=go.Scatter(
    x=df['Date'],
    y=df['Hash-rate'],
    xaxis='x1',
    yaxis='y1',
    mode='lines',
    line=dict(width=2, color='#9748a1'),
    name='hash-rate-TH/s'
)

trace5=go.Scatter(
    x=df['Date'],
    y=df['Mining-revenue-USD'],
    xaxis='x2',
    yaxis='y2',
    mode='lines',
    line=dict(width=2, color='#b04553'),
    name='mining revenue'
)

trace6=go.Scatter(
    x=df['Date'],
    y=df['Transaction-fees-BTC'],
    xaxis='x3',
    yaxis='y3',
    mode='lines',
    line=dict(width=2, color='#af7bbd'),
    name='transact-fee'
)

axis=dict(
    showline=True,
    zeroline=False,
    showgrid=True,
    mirror=True, 
    ticklen=4, 
    gridcolor='#ffffff',
    tickfont=dict(size=10)
)

layout2 = dict(
    width=950,
    height=800,
    autosize=False,
    title='Bitcoin mining stats for 180 days',
    margin = dict(t=100),
    showlegend=False,          
    xaxis1=dict(axis, **dict(domain=[0, 1], anchor='y1', showticklabels=False)),
    xaxis2=dict(axis, **dict(domain=[0, 1], anchor='y2', showticklabels=False)),          
    xaxis3=dict(axis, **dict(domain=[0, 1], anchor='y3')), 
    yaxis1=dict(axis, **dict(domain=[2 * 0.21 + 0.02 + 0.02, 0.68], anchor='x1', hoverformat='.2f')),  
    yaxis2=dict(axis, **dict(domain=[0.21 + 0.02, 2 * 0.21 + 0.02], anchor='x2', tickprefix='$', hoverformat='.2f')),
    yaxis3=dict(axis, **dict(domain=[0.0, 0.21], anchor='x3', tickprefix=u'\u20BF', hoverformat='.2f')),
    plot_bgcolor='rgba(228, 222, 249, 0.65)'
)

fig2 = dict(data=[table_trace2, trace4, trace5, trace6], layout=layout2)
py.iplot(fig2, filename='vertical-stacked-subplot-tables')
Out[5]:

Reference¶

See https://plot.ly/python/reference/#table for more information regarding chart attributes!
For examples of Plotly Tables, see: https://plot.ly/python/table/

Still need help?
Contact Us

For guaranteed 24 hour response turnarounds, upgrade to a Developer Support Plan.