Black Lives Matter. Please consider donating to Black Girls Code today.

How to make Html Report readable from all browsers

Hi Team,
indent preformatted text by 4 spaces
Following this https://plot.ly/python/html-reports/.

I have two cufflinks plots which i have inputted into a HTML report.

Though the issues I face is:

  • It appears the report displays the graph only for me
  • The report is not viewable by other browsers.

here is my plotly graphs:

Graph1:

fig = ftj_plan.iplot(kind=‘bar’,
barmode=‘stack’,
sortbars=True,
title="{:%d/%m/%y} FTJ Report Update".format(datetime.today()),
asFigure=True,
theme=‘polar’,
symbol=‘dot’,
xTitle=‘Plan’,
yTitle=‘No.Items’,
keys = [‘Error’,‘Reviewed’,‘Posted’,‘To Be Reviewed’]
)

py.iplot(fig,filename=‘Dan.html’,config=UNBRAND_CONFIG)

second_url_plot = py.plot(fig,filename= file_path + “FTJ_Summary” + datetime.strftime(datetime.now(), ‘%d%m_%Y’) + “.html”,
config=UNBRAND_CONFIG, auto_open=False)
graph2:

fig = sun_total.iplot(kind=‘barh’,
barmode=‘stack’,
sortbars=True,
title="{:%d/%m/%y} Sundry Update".format(datetime.today()),
asFigure=True,
theme=‘polar’,
symbol=‘dot’,
xTitle=‘Plan’,
yTitle=‘No.Items’,
keys=[‘Over 28 Days’,‘Over 60 Days’, ‘Over 90 Days’, ‘Over 180 Days’]
)

py.iplot(fig,filename=‘Sundry_Update.html’,config=UNBRAND_CONFIG)

first_url_plot = py.plot(fig,filename= file_path + “Sundry” + datetime.strftime(datetime.now(), ‘%d%m_%Y’)+ “.html”,
config=UNBRAND_CONFIG, auto_open=False)

Html Report:

html_string = ‘’’

body{ margin:0 100; background:whitesmoke; }

Navigator Finance

    <!-- *** Section 1 *** --->
    <h2>Section 1: Oustanding Items - Sundry</h2>
    <iframe width="1000" height="550" frameborder="0" seamless="seamless" scrolling="no" \

src="’’’ + first_url_plot + ‘’’">

Apple stock price rose steadily through 2014.


Reference table: Sundry Changes


‘’’ + summary_table_3 + ‘’’
    <!-- *** Section 2 *** --->
    <h2>Section 2: Finance To Journal </h2>
    <iframe width="1000" height="550" frameborder="0" seamless="seamless" scrolling="no" \

src="’’’ + second_url_plot + ‘’’">

GE had the most predictable stock price in 2014. IBM had the highest mean stock price.
The red lines are kernel density estimations of each stock price - the peak of each red lines
corresponds to its mean stock price for 2014 on the x axis.


Reference table: FTJ Filenames


‘’’ + summary_table_1 + ‘’’
    <h3>Reference table: Links</h3>
    ''' + summary_table_2 + '''

</body>
'''

f = open(file_path + “Dashboard” + datetime.strftime(datetime.now(), ‘%d%m_%Y’) + “.html” ,‘w’)
f.write(html_string)
f.close()

Is possible to have the html report actually contain the graphs rather than link to it? When i save the outputs of the graph + html report to the same shared drive it works for myself but not for other users.

Any guidance would be greatly appreciated.

Regards,

Dan

Hi Guys Sorry some of the html code appeared as header,

Let me know if its still workable.

Cheers

Hi @ocelot911,

You can fix up the formatting of your code by placing it in a fenced code block (See https://help.github.com/articles/creating-and-highlighting-code-blocks/).

For you question itself, if you save the figure to HTML in offline mode it is self contained and should be viewable in any modern browser, even without an internet connection. See the plotly.offline.plot command.

Does that help?
-Jon

Hi @jmmease

Essentially I am exporting two offline ploty graphs to html then using both files to create a offline html report.

  • first_url_plot & second_url_plot = two separate offline plotly graphs saved as a offline html file.

So essentially i have 3 html files:
-2 relating to the plotly graph (~4mb)
-1 which is the dashboard(which references the 2 plotly graph)

Problem:

  1. Actually have the graphs in the Dashboard.html file rather than referencing it?(sorry if wrong terms am newb), so the file will be large around 5mb
  2. When i export the dashboard.html file only i can view the file with the plotly plots showing.

Sorry if this is confusing

html_string = '''
<html>
    <head>
        <link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.1/css/bootstrap.min.css">
        <style>body{ margin:0 100; background:whitesmoke; }</style>
    </head>
    <body>
        <h1>Navigator Finance</h1>

        <!-- *** Section 1 *** --->
        <h2>Section 1: Oustanding Items - Sundry</h2>
        <iframe width="1000" height="550" frameborder="0" seamless="seamless" scrolling="no" \
src="''' + first_url_plot + '''"></iframe>
        <p>Apple stock price rose steadily through 2014.</p>
        <h3>Reference table: Sundry Changes</h3>
        ''' + summary_table_3 + '''
        
        <!-- *** Section 2 *** --->
        <h2>Section 2: Finance To Journal </h2>
        <iframe width="1000" height="550" frameborder="0" seamless="seamless" scrolling="no" \
src="''' + second_url_plot + '''"></iframe>
        <p>GE had the most predictable stock price in 2014. IBM had the highest mean stock price. \
The red lines are kernel density estimations of each stock price - the peak of each red lines \
corresponds to its mean stock price for 2014 on the x axis.</p>
        <h3>Reference table: FTJ Filenames </h3>
        ''' + summary_table_1 + '''

        <h3>Reference table: Links</h3>
        ''' + summary_table_2 + '''

    </body>
</html>'''

f = open(file_path + "Dashboard" + datetime.strftime(datetime.now(), '_%d_%m_%Y') + ".html" ,'w')
f.write(html_string)
f.close()

I am referencing this https://plot.ly/python/html-reports/

Regards,

Dan

Hi @ocelot911,

I’m still not quite clear on what you’re currently doing. The https://plot.ly/python/html-reports/ link discusses creating plots in online (not offline) mode. Could you include a full self-contained code example in a fenced code block (including imports and some sample data)?

Thanks!

-Jon

@jmmease sorry for the delay,

here is an example in its entirety

import plotly.offline as py
import plotly.graph_objs as go


top_labels = ['Strongly<br>agree', 'Agree', 'Neutral', 'Disagree',
              'Strongly<br>disagree']

colors = ['rgba(38, 24, 74, 0.8)', 'rgba(71, 58, 131, 0.8)',
          'rgba(122, 120, 168, 0.8)', 'rgba(164, 163, 204, 0.85)',
          'rgba(190, 192, 213, 1)']

x_data = [[21, 30, 21, 16, 12],
          [24, 31, 19, 15, 11],
          [27, 26, 23, 11, 13],
          [29, 24, 15, 18, 14]]

y_data = ['The course was effectively<br>organized',
          'The course developed my<br>abilities and skills ' +
          'for<br>the subject', 'The course developed ' +
          'my<br>ability to think critically about<br>the subject',
          'I would recommend this<br>course to a friend']


traces = []

for i in range(0, len(x_data[0])):
    for xd, yd in zip(x_data, y_data):
        traces.append(go.Bar(
            x=[xd[i]],
            y=[yd],
            orientation='h',
            marker=dict(
                color=colors[i],
                line=dict(
                        color='rgb(248, 248, 249)',
                        width=1)
            )
        ))

layout = go.Layout(
    xaxis=dict(
        showgrid=False,
        showline=False,
        showticklabels=False,
        zeroline=False,
        domain=[0.15, 1]
    ),
    yaxis=dict(
        showgrid=False,
        showline=False,
        showticklabels=False,
        zeroline=False,
    ),
    barmode='stack',
    paper_bgcolor='rgb(248, 248, 255)',
    plot_bgcolor='rgb(248, 248, 255)',
    margin=dict(
        l=120,
        r=10,
        t=140,
        b=80
    ),
    showlegend=False,
)

annotations = []

for yd, xd in zip(y_data, x_data):
    # labeling the y-axis
    annotations.append(dict(xref='paper', yref='y',
                            x=0.14, y=yd,
                            xanchor='right',
                            text=str(yd),
                            font=dict(family='Arial', size=14,
                                      color='rgb(67, 67, 67)'),
                            showarrow=False, align='right'))
    # labeling the first percentage of each bar (x_axis)
    annotations.append(dict(xref='x', yref='y',
                            x=xd[0] / 2, y=yd,
                            text=str(xd[0]) + '%',
                            font=dict(family='Arial', size=14,
                                      color='rgb(248, 248, 255)'),
                            showarrow=False))
    # labeling the first Likert scale (on the top)
    if yd == y_data[-1]:
        annotations.append(dict(xref='x', yref='paper',
                                x=xd[0] / 2, y=1.1,
                                text=top_labels[0],
                                font=dict(family='Arial', size=14,
                                          color='rgb(67, 67, 67)'),
                                showarrow=False))
    space = xd[0]
    for i in range(1, len(xd)):
            # labeling the rest of percentages for each bar (x_axis)
            annotations.append(dict(xref='x', yref='y',
                                    x=space + (xd[i]/2), y=yd, 
                                    text=str(xd[i]) + '%',
                                    font=dict(family='Arial', size=14,
                                              color='rgb(248, 248, 255)'),
                                    showarrow=False))
            # labeling the Likert scale
            if yd == y_data[-1]:
                annotations.append(dict(xref='x', yref='paper',
                                        x=space + (xd[i]/2), y=1.1,
                                        text=top_labels[i],
                                        font=dict(family='Arial', size=14,
                                                  color='rgb(67, 67, 67)'),
                                        showarrow=False))
            space += xd[i]

layout['annotations'] = annotations

fig = go.Figure(data=traces, layout=layout)

fig['layout'].update(height=400,width=800)


second_plot_url = py.plot(fig, filename='bar-colorscale.html',auto_open=False)


import plotly.offline as py
import plotly.graph_objs as go
from plotly import tools
from IPython.display import HTML


import numpy as np

y_saving = [1.3586, 2.2623000000000002, 4.9821999999999997, 6.5096999999999996,
        7.4812000000000003, 7.5133000000000001, 15.2148, 17.520499999999998
        ]
y_net_worth = [93453.919999999998, 81666.570000000007, 69889.619999999995,
           78381.529999999999, 141395.29999999999, 92969.020000000004,
           66090.179999999993, 122379.3]
x_saving = ['Japan', 'United Kingdom', 'Canada', 'Netherlands',
        'United States', 'Belgium', 'Sweden', 'Switzerland']
x_net_worth = ['Japan', 'United Kingdom', 'Canada', 'Netherlands',
           'United States', 'Belgium', 'Sweden', 'Switzerland'
           ]
trace0 = go.Bar(
x=y_saving,
y=x_saving,
marker=dict(
    color='rgba(50, 171, 96, 0.6)',
    line=dict(
        color='rgba(50, 171, 96, 1.0)',
        width=1),
),
name='Household savings, percentage of household disposable income',
orientation='h',
)
trace1 = go.Scatter(
x=y_net_worth,
y=x_net_worth,
mode='lines+markers',
line=dict(
    color='rgb(128, 0, 128)'),
name='Household net worth, Million USD/capita',
)
layout = dict(
title='Household savings & net worth for eight OECD countries',
yaxis=dict(
    showgrid=False,
    showline=False,
    showticklabels=True,
    domain=[0, 0.85],
),
yaxis2=dict(
    showgrid=False,
    showline=True,
    showticklabels=False,
    linecolor='rgba(102, 102, 102, 0.8)',
    linewidth=2,
    domain=[0, 0.85],
),
xaxis=dict(
    zeroline=False,
    showline=False,
    showticklabels=True,
    showgrid=True,
    domain=[0, 0.42],
),
xaxis2=dict(
    zeroline=False,
    showline=False,
    showticklabels=True,
    showgrid=True,
    domain=[0.47, 1],
    side='top',
    dtick=25000,
),
legend=dict(
    x=0.029,
    y=1.038,
    font=dict(
        size=10,
    ),
),
margin=dict(
    l=100,
    r=20,
    t=70,
    b=70,
),
paper_bgcolor='rgb(248, 248, 255)',
plot_bgcolor='rgb(248, 248, 255)',
)

annotations = []

y_s = np.round(y_saving, decimals=2)
y_nw = np.rint(y_net_worth)

# Adding labels
for ydn, yd, xd in zip(y_nw, y_s, x_saving):
# labeling the scatter savings
annotations.append(dict(xref='x2', yref='y2',
                        y=xd, x=ydn - 20000,
                        text='{:,}'.format(ydn) + 'M',
                        font=dict(family='Arial', size=12,
                                  color='rgb(128, 0, 128)'),
                        showarrow=False))
# labeling the bar net worth
annotations.append(dict(xref='x1', yref='y1',
                        y=xd, x=yd + 3,
                        text=str(yd) + '%',
                        font=dict(family='Arial', size=12,
                                  color='rgb(50, 171, 96)'),
                        showarrow=False))
# Source
annotations.append(dict(xref='paper', yref='paper',
                    x=-0.2, y=-0.109,
                    text='OECD "' +
                         '(2015), Household savings (indicator), ' +
                         'Household net worth (indicator). doi: ' +
                         '10.1787/cfc6f499-en (Accessed on 05 June 2015)',
                    font=dict(family='Arial', size=10,
                              color='rgb(150,150,150)'),
                    showarrow=False))

layout['annotations'] = annotations

# Creating two subplots
fig = tools.make_subplots(rows=1, cols=2, specs=[[{}, {}]], shared_xaxes=True,
                      shared_yaxes=False, vertical_spacing=0.001)

fig.append_trace(trace0, 1, 1)
fig.append_trace(trace1, 1, 2)

fig['layout'].update(layout,height=800,width=1000)
py.iplot(fig, filename='oecd-networth-saving-bar-line')


first_plot_url = py.plot(fig, filename='bar_egg.html',auto_open=False)

html_string = '''
<html>
<head>
    <link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.1/css/bootstrap.min.css">
    <style>body{ margin:0 100; background:whitesmoke; }</style>
</head>
<body>
    <h1>2014 technology and CPG stock prices</h1>

    <!-- *** Section 1 *** --->
    <h2>Section 1: Apple Inc. (AAPL) stock in 2014</h2>
    <iframe width="1000" height="550" frameborder="0" seamless="seamless" scrolling="no" \
src="''' + first_plot_url + '''</iframe>
    <p>Apple stock price rose steadily through 2014.</p>
    
    <!-- *** Section 2 *** --->
    <h2>Section 2: AAPL compared to other 2014 stocks</h2>
    <iframe width="1000" height="550" frameborder="0" seamless="seamless" scrolling="no" \
src="''' + second_plot_url + '''</iframe>
    <p>GE had the most predictable stock price in 2014. IBM had the highest mean stock price. \
The red lines are kernel density estimations of each stock price - the peak of each red lines \
corresponds to its mean stock price for 2014 on the x axis.</p>


</body>
</html>'''

f = open('Dan_DFDFFF.html','w')
f.write(html_string)
f.close()

Hi @ocelot911,

Thanks for the example! So I was able to run it, and it produced Dan_DFDFFF.html, bar_egg.html, and bar-colorscale.html. When I opened bar_egg.html and bar-colorscale.html they seemed to render fine, but Dan_DFDFFF.html doesn’t display the other plots.

When I opened Dan_DFDFFF.html in a text editor, I noticed that the <iframe> elements seem to have a error. This is what was produced:

<iframe width="1000" height="550" frameborder="0" seamless="seamless" scrolling="no" src="file:///Users/jmmease/Plotly/notebook/community_examples/bar_egg.html</iframe>

The problem is that the closing double quote for the src attribute’s string is missing. And the closing > character for the opening iframe element is missing. It should look like this:

<iframe width="1000" height="550" frameborder="0" seamless="seamless" scrolling="no" src="file:///Users/jmmease/Plotly/notebook/community_examples/bar_egg.html"></iframe>

When I make these fixes in the text editor, and then reopen in chrome, it looks like it’s working.

So check through your code to see if you can work out where to add these missing characters.

Hope that helps!
-Jon

1 Like

Sorry @jmmease,

The Code I am using for work is displaying I did get a bit careless with the one given but yes correct.

My current output for work is working in chrome only but not the other browsers and I was wondering if the Report File does not have to link to the other plots and is inclusive of one file?

example Dan_DFDFFF.html file does not have to refer to bar_egg and bar-colorscale i can just send the Dan_DFDFF file and whoever opens it does not need access to the other files.

Hopefully I am making sense haha

Thanks for your patience.

Regards,

Dan

Hi @ocelot911,

Ok, if I understand correctly you would like the Dan_DFDFFF.html file to be self contained and not have references to other files. Is that correct?

This would be possible using plain plotly.py by bassing output_type='div' option to plotly.offline.plot. This returns a string with an HTML div element that could be placed directly in your top-level HTML file. For example

import plotly.graph_objs as go
from plotly.offline import plot

fig1 = go.Figure(data=[{'type': 'bar', 'y': [1, 3, 2]}],
                layout={'height': 400})

fig2 = go.Figure(data=[{'type': 'scatter', 'y': [1, 3, 2]}],
                layout={'height': 400})

div1 = plot(fig1, output_type='div', include_plotlyjs=False)
div2 = plot(fig2, output_type='div', include_plotlyjs=False)

html = """\
<html>
    <head>
        <script src="https://cdn.plot.ly/plotly-latest.min.js"></script>
    </head>
    <body>
    {div1}
    {div2}
    </body>
</html>
""".format(div1=div1, div2=div2)

with open('multi_plot.html', 'w') as f:
    f.write(html)

I don’t know if cufflinks supports this through the DataFrame iplot interface. But I suppose you could use the cufflinks asFigure=True option (https://plot.ly/ipython-notebooks/cufflinks/#customizing-figures) to get the plotly.py figures (fig1 and fig2 in the example above) and then call plotly.offline.plot with output_type='div'.

Hope that helps :slightly_smiling_face:
-Jon