0
votes

I am using plotly and python. The goal is to have a chart like this, where each bar represents the distribution of a particular series using different percentiles.

enter image description here

This is sample data ( this data has nothing to do with the above graph. )

Percentile      0.05      0.25      0.50      0.75      0.95
Timestep                                                    
2017M06     0.009531  0.009531  0.009531  0.009531  0.009531
2017M07    -0.098059 -0.096431  0.007171  0.076327  0.143442
2017M08    -0.040074 -0.035968  0.007923  0.043307  0.088125
2017M09    -0.042111 -0.025118  0.043147  0.056743  0.073169
2017M10    -0.044251 -0.014754  0.003749  0.060594  0.136222
2017M11    -0.097137 -0.068795 -0.068711  0.008935  0.048629
2017M12    -0.050702 -0.029305 -0.016308  0.002923  0.111673
2018M01    -0.013028  0.004550  0.010547  0.025975  0.045995
2018M02    -0.057814 -0.044448 -0.044320 -0.041016  0.051825
2018M03     0.009961  0.023378  0.058440  0.124610  0.152549
2018M04    -0.034927  0.025411  0.075795  0.095152  0.117307
2018M05    -0.023744 -0.005568  0.077677  0.137097  0.144172
2018M06    -0.048046 -0.007990 -0.006329  0.015632  0.019013

Here is the attempt to create something similar in Plotly, using "overlay" barchart mode.

which creates a graph likes this. enter image description here

As you can see, the colors are all messed up. Some numbers don't even show up since the smaller number is placed under the larger one.

How can I fix this ? What I need is at each bar, for positive values, the bars are plotted in descending order, from largest to smallest. For negative values, the bars need to be plotted in ascending order, from smallest to largest.

As a side note, I am aware that there are four kinds of plotly bar charts: stack, overlay, group and relative. I tested all those and overlay is the one that I want since I need stacked bar, where underlying data are both positive and negative.

Here is the code that produces the above graph.

iplot(
    {'data': [{
       'name': '0.05',
       'orientation': 'v',
       'text': '',
       'type': 'bar',
       'x': array(['2017M06', '2017M07', '2017M08', '2017M09', '2017M10', '2017M11',
              '2017M12', '2018M01', '2018M02', '2018M03', '2018M04', '2018M05',
              '2018M06'], dtype=object),
       'y': array([ 0.009531 , -0.098059 , -0.0400744, -0.0421108, -0.0442508,
              -0.0971366, -0.0507018, -0.0130276, -0.0578136,  0.0099612,
              -0.0349274, -0.023744 , -0.048046 ])},
      {
       'name': '0.25',
       'orientation': 'v',
       'text': '',
       'type': 'bar',
       'x': array(['2017M06', '2017M07', '2017M08', '2017M09', '2017M10', '2017M11',
              '2017M12', '2018M01', '2018M02', '2018M03', '2018M04', '2018M05',
              '2018M06'], dtype=object),
       'y': array([ 0.009531, -0.096431, -0.035968, -0.025118, -0.014754, -0.068795,
              -0.029305,  0.00455 , -0.044448,  0.023378,  0.025411, -0.005568,
              -0.00799 ])},
      {
       'name': '0.5',
       'orientation': 'v',
       'text': '',
       'type': 'bar',
       'x': array(['2017M06', '2017M07', '2017M08', '2017M09', '2017M10', '2017M11',
              '2017M12', '2018M01', '2018M02', '2018M03', '2018M04', '2018M05',
              '2018M06'], dtype=object),
       'y': array([ 0.009531,  0.007171,  0.007923,  0.043147,  0.003749, -0.068711,
              -0.016308,  0.010547, -0.04432 ,  0.05844 ,  0.075795,  0.077677,
              -0.006329])},
      {
       'name': '0.75',
       'orientation': 'v',
       'text': '',
       'type': 'bar',
       'x': array(['2017M06', '2017M07', '2017M08', '2017M09', '2017M10', '2017M11',
              '2017M12', '2018M01', '2018M02', '2018M03', '2018M04', '2018M05',
              '2018M06'], dtype=object),
       'y': array([ 0.009531,  0.076327,  0.043307,  0.056743,  0.060594,  0.008935,
               0.002923,  0.025975, -0.041016,  0.12461 ,  0.095152,  0.137097,
               0.015632])},
      {
       'name': '0.95',
       'orientation': 'v',
       'text': '',
       'type': 'bar',
       'x': array(['2017M06', '2017M07', '2017M08', '2017M09', '2017M10', '2017M11',
              '2017M12', '2018M01', '2018M02', '2018M03', '2018M04', '2018M05',
              '2018M06'], dtype=object),
       'y': array([ 0.009531 ,  0.1434422,  0.0881254,  0.0731686,  0.136222 ,
               0.0486294,  0.1116726,  0.045995 ,  0.0518248,  0.1525492,
               0.1173072,  0.1441722,  0.0190128])}],




     'layout': {'barmode': 'overlay'}}
       )
1
I'd say try to play with "opacity" for the colors, or go with stacked bars instead of overlay. Not sure which one will work best.FabienP

1 Answers

0
votes

Let's say the data we are interested in is 1 2 3 4 5 6 7 8 9

I want to plot from first row to second row and second row to third row. The following Python code would achieve that.

iplot(
{'data': [{'base': array([ 1,2,3]),
   'marker': {'color': 'rgba(0, 97, 37, 1.0)',
    'line': {'color': 'rgba(0, 97, 37, 1.0)', 'width': 1}},
   'name': 'first',
   'orientation': 'v',
   'text': '',
   'type': 'bar',
   'x': array(['dog', 'cat', 'monkey'], dtype=object),
   'y': array([ 3,3,3,])},
  {'base': array([4,5,6]),
   'marker': {'color': 'rgba(138, 33, 14, 1.0)',
    'line': {'color': 'rgba(138, 33, 14, 1.0)', 'width': 1}},
   'name': 'second',
   'orientation': 'v',
   'text': '',
   'type': 'bar',
   'x': array(['dog', 'cat', 'monkey'], dtype=object),
   'y': array([ 3,3,3])}],
 'layout': {'barmode': 'overlay',
  'legend': {'bgcolor': '#F5F6F9', 'font': {'color': '#4D5663'}},
  'paper_bgcolor': '#F5F6F9',
  'plot_bgcolor': '#F5F6F9',
  'title': 'main title',
  'titlefont': {'color': '#4D5663'},
  'xaxis1': {'gridcolor': '#E1E5ED',
   'showgrid': True,
   'tickfont': {'color': '#4D5663'},
   'title': '',
   'titlefont': {'color': '#4D5663'},
   'zerolinecolor': '#E1E5ED'},
  'yaxis1': {'gridcolor': '#E1E5ED',
 
   'showgrid': True,
   'tickfont': {'color': '#4D5663'},
   'title': '',
   'titlefont': {'color': '#4D5663'},
   'zerolinecolor': '#E1E5ED'}}}
)

This is the result.

enter image description here

The trick is to write the lower bound as base and the difference as y values. This also takes care of the fact that having both positive and negative values screw things up, since the user has complete control over where each color starts and ends.