1
votes

Using pandas & matplotlib I've created a handy graphic for our team to monitor revenue. For each of our customers it shows last month (light grey), best month (dark grey), and the forecast range for this month (green).

revenue with forecast

It's basically two stacked bar charts of differing widths.

ax = df.plot(kind='barh', x='company', y=['last_month', 'best-last'], width=0.2, color=context_colors, lw=0, stacked=True)

df.plot(kind='barh', x='company', y=['forecast_low', 'hi-lo'], stacked=True, colors=range_colors, lw=0, ax=ax)

Works great in python. For reasons not worth going into, this image won't show up correctly-sized on the site it needs to go on. So I'm trying plotly for the first time.

I haven't been able to find similar functionality. I tried building separate stacked charts and then combining them by running sequential iplot, but it just builds two separate plots. eg

iplot(fig)
iplot(fig2)

And trying to combine figs is no good (eg iplot(fig, fig2)), which just plots the data in the first one.

Any suggestions for how to replicate in plotly?

1

1 Answers

4
votes

The graph could use some tweaking but it's definitely doable with Plotly.

  • Add orientation='h' to both traces to make them horizontal
  • Add barmode='stack' to your layout to stack the bars
  • Make sure that x and y match the right axis
  • The x values of the stacked trace should be just the difference between the two traces, i.e. x=df['best'] - df['last month']
  • For the forecast points you can either use a Scatter plot with mode set to markers or add shapes (the figure below has both).

enter image description here

import plotly.plotly as py
import plotly.graph_objs as go
import pandas as pd

df = pd.DataFrame(
    {'last month': [10, 15, 12],
     'best': [13, 20, 16],
     'forecast': [11, 17, 14],
     'animal': ['giraffe', 'orangutan', 'monkey']
     }
)

trace1 = go.Bar(
    y=df['animal'],
    x=df['last month'],
    name='last month',
    orientation='h'
)
trace2 = go.Bar(
    y=df['animal'],
    x=df['best'] - df['last month'],
    name='best month',
    orientation='h',
)
trace3 = go.Scatter(
    y=df['animal'],
    x=df['forecast'],
    name='forecasst',
    mode='markers',
    marker= {'size': 20, 'symbol': 'square'}
)
data = [trace1, trace2, trace3]

shapes = list()
for i, x in enumerate(df['animal']):
    shapes.append({
        'type': 'rect',
        'x0': df.forecast[i] - 1,
        'x1': df.forecast[i] + 1,
        'y0': i - 0.5,
        'y1': i + 0.5,
        'line': {
            'color': 'rgba(0, 128, 0, 1)',
            'width': 2,
            },
        'fillcolor': 'rgba(0, 128, 0, 0.5)'
        }
    )
layout = go.Layout(
    barmode='stack',
    shapes=shapes
)

fig = go.Figure(data=data, layout=layout)
plot_url = py.plot(fig)