17. Dataviz Workshop: objetos gráficos e Plotly Express#

17.1. Objetivos do workshop#

  • Reconhecer a estrutura hierárquica de objetos gráficos;

  • Criar e atualizar instâncias do módulo Plotly Express;

  • Renderizar RVs interativas prontas para publicação na web;

17.2. Ferramentas utilizadas#

  • Módulos Python

    • plotly.express

    • pandas

17.3. Objetos gráficos#

Objetos gráficos são estruturas de dados hierárquicas (na forma de árvore) que descrevem uma RV em linguagem de máquina através de um esquema predefinido. O módulo Plotly Express é alimentado por esses objetos. O que ele faz é basicamente converter estruturas de dados Python em JSON serializados para pronta renderização na web. O termo objeto gráfico refere-se a instâncias de classes Python que são hierarquicamente organizadas para cada tipo de RV. As principais classes são Figure e FigureWidget. Ambas permitem que os elementos do objeto JSON (nós da árvore), chamados de “atributos”, sejam manipuláveis para controlar todas as características da RV, tais como o layout, os traços, a renderização e a exportação para diferentes formatos.

A construção de um objeto gráfico requer muitas linhas de código. Abaixo, mostramos um exemplo para um banco de dados de livros de uma biblioteca.

import pandas as pd

# Livros disponíveis na biblioteca
df = pd.DataFrame({
    "Livro": ['Teoria da Computação','Ciência de Dados para Energia','Linguagens de Programação', 
              'Teoria da Computação','Ciência de Dados para Energia','Linguagens de Programação'],
    "Autor": ['Etelvin','Bruff','Non','Deltin','Fargo','Folly'],
    "Quantidade disponível": [10,6,4,6,8,2]
})
df
Livro Autor Quantidade disponível
0 Teoria da Computação Etelvin 10
1 Ciência de Dados para Energia Bruff 6
2 Linguagens de Programação Non 4
3 Teoria da Computação Deltin 6
4 Ciência de Dados para Energia Fargo 8
5 Linguagens de Programação Folly 2
import plotly.graph_objects as go
from IPython.display import display, HTML
from plotly.offline import plot


# Objeto gráfico
fig = go.Figure()
for autor, grupo in df.groupby("Autor"):
    fig.add_trace(go.Bar(x=grupo["Livro"], y=grupo["Quantidade disponível"], name=autor,
      hovertemplate="Autor=%s<br>Livro=%%{x}<br>Quantidade disponível=%%{y}<extra></extra>" % autor))
fig.update_layout(legend_title_text = "Autor")
fig.update_xaxes(title_text="Livro")
fig.update_yaxes(title_text="Quantidade disponível")

plot(fig, show_link=False,filename='dw-plotly-exemplo-1.html')
display(HTML('dw-plotly-exemplo-1.html'))

A estrutura complexa acima é reproduzida de maneira equivalente com Plotly Express com apenas uma linha:

import plotly.express as px

fig = px.bar(df,x="Livro",y="Quantidade disponível",color="Autor",barmode="group")

plot(fig, show_link=False,filename='dw-plotly-exemplo-2.html')
display(HTML('dw-plotly-exemplo-2.html'))

17.4. Figuras como estruturas de dados#

Apesar de a Plotly ser uma API para renderização de RVs e trazer muita facilidades para plotoagem interativa, haverá casos em que precisaremos manipular os atributos de uma figura para criar visuais customizados. Por isso, é também importante compreender um pouco das estruturas das figuras utilizadas pela Plotly, que basicamente são do tipo dict ou instâncias da classe plotly.graph_objects.Figure.

  • Para visualizar a estrutura, podemos usar print:

import plotly.express as px

fig = px.line(x=["TC","CDIA","LP"], y=[16,14,6], title="Totais")

plot(fig, show_link=False,filename='dw-plotly-exemplo-3.html')
display(HTML('dw-plotly-exemplo-3.html'))
print(fig)
Figure({
    'data': [{'hovertemplate': 'x=%{x}<br>y=%{y}<extra></extra>',
              'legendgroup': '',
              'line': {'color': '#636efa', 'dash': 'solid'},
              'marker': {'symbol': 'circle'},
              'mode': 'lines',
              'name': '',
              'orientation': 'v',
              'showlegend': False,
              'type': 'scatter',
              'x': array(['TC', 'CDIA', 'LP'], dtype=object),
              'xaxis': 'x',
              'y': array([16, 14,  6]),
              'yaxis': 'y'}],
    'layout': {'legend': {'tracegroupgap': 0},
               'template': '...',
               'title': {'text': 'Totais'},
               'xaxis': {'anchor': 'y', 'domain': [0.0, 1.0], 'title': {'text': 'x'}},
               'yaxis': {'anchor': 'x', 'domain': [0.0, 1.0], 'title': {'text': 'y'}}}
})
  • Para visualizá-la como JSON, usamos:

fig.show("json") 
  • Para exportá-la para JSON:

fig.to_json() 
'{"data":[{"hovertemplate":"x=%{x}\\u003cbr\\u003ey=%{y}\\u003cextra\\u003e\\u003c\\u002fextra\\u003e","legendgroup":"","line":{"color":"#636efa","dash":"solid"},"marker":{"symbol":"circle"},"mode":"lines","name":"","orientation":"v","showlegend":false,"x":["TC","CDIA","LP"],"xaxis":"x","y":[16,14,6],"yaxis":"y","type":"scatter"}],"layout":{"template":{"data":{"histogram2dcontour":[{"type":"histogram2dcontour","colorbar":{"outlinewidth":0,"ticks":""},"colorscale":[[0.0,"#0d0887"],[0.1111111111111111,"#46039f"],[0.2222222222222222,"#7201a8"],[0.3333333333333333,"#9c179e"],[0.4444444444444444,"#bd3786"],[0.5555555555555556,"#d8576b"],[0.6666666666666666,"#ed7953"],[0.7777777777777778,"#fb9f3a"],[0.8888888888888888,"#fdca26"],[1.0,"#f0f921"]]}],"choropleth":[{"type":"choropleth","colorbar":{"outlinewidth":0,"ticks":""}}],"histogram2d":[{"type":"histogram2d","colorbar":{"outlinewidth":0,"ticks":""},"colorscale":[[0.0,"#0d0887"],[0.1111111111111111,"#46039f"],[0.2222222222222222,"#7201a8"],[0.3333333333333333,"#9c179e"],[0.4444444444444444,"#bd3786"],[0.5555555555555556,"#d8576b"],[0.6666666666666666,"#ed7953"],[0.7777777777777778,"#fb9f3a"],[0.8888888888888888,"#fdca26"],[1.0,"#f0f921"]]}],"heatmap":[{"type":"heatmap","colorbar":{"outlinewidth":0,"ticks":""},"colorscale":[[0.0,"#0d0887"],[0.1111111111111111,"#46039f"],[0.2222222222222222,"#7201a8"],[0.3333333333333333,"#9c179e"],[0.4444444444444444,"#bd3786"],[0.5555555555555556,"#d8576b"],[0.6666666666666666,"#ed7953"],[0.7777777777777778,"#fb9f3a"],[0.8888888888888888,"#fdca26"],[1.0,"#f0f921"]]}],"heatmapgl":[{"type":"heatmapgl","colorbar":{"outlinewidth":0,"ticks":""},"colorscale":[[0.0,"#0d0887"],[0.1111111111111111,"#46039f"],[0.2222222222222222,"#7201a8"],[0.3333333333333333,"#9c179e"],[0.4444444444444444,"#bd3786"],[0.5555555555555556,"#d8576b"],[0.6666666666666666,"#ed7953"],[0.7777777777777778,"#fb9f3a"],[0.8888888888888888,"#fdca26"],[1.0,"#f0f921"]]}],"contourcarpet":[{"type":"contourcarpet","colorbar":{"outlinewidth":0,"ticks":""}}],"contour":[{"type":"contour","colorbar":{"outlinewidth":0,"ticks":""},"colorscale":[[0.0,"#0d0887"],[0.1111111111111111,"#46039f"],[0.2222222222222222,"#7201a8"],[0.3333333333333333,"#9c179e"],[0.4444444444444444,"#bd3786"],[0.5555555555555556,"#d8576b"],[0.6666666666666666,"#ed7953"],[0.7777777777777778,"#fb9f3a"],[0.8888888888888888,"#fdca26"],[1.0,"#f0f921"]]}],"surface":[{"type":"surface","colorbar":{"outlinewidth":0,"ticks":""},"colorscale":[[0.0,"#0d0887"],[0.1111111111111111,"#46039f"],[0.2222222222222222,"#7201a8"],[0.3333333333333333,"#9c179e"],[0.4444444444444444,"#bd3786"],[0.5555555555555556,"#d8576b"],[0.6666666666666666,"#ed7953"],[0.7777777777777778,"#fb9f3a"],[0.8888888888888888,"#fdca26"],[1.0,"#f0f921"]]}],"mesh3d":[{"type":"mesh3d","colorbar":{"outlinewidth":0,"ticks":""}}],"scatter":[{"fillpattern":{"fillmode":"overlay","size":10,"solidity":0.2},"type":"scatter"}],"parcoords":[{"type":"parcoords","line":{"colorbar":{"outlinewidth":0,"ticks":""}}}],"scatterpolargl":[{"type":"scatterpolargl","marker":{"colorbar":{"outlinewidth":0,"ticks":""}}}],"bar":[{"error_x":{"color":"#2a3f5f"},"error_y":{"color":"#2a3f5f"},"marker":{"line":{"color":"#E5ECF6","width":0.5},"pattern":{"fillmode":"overlay","size":10,"solidity":0.2}},"type":"bar"}],"scattergeo":[{"type":"scattergeo","marker":{"colorbar":{"outlinewidth":0,"ticks":""}}}],"scatterpolar":[{"type":"scatterpolar","marker":{"colorbar":{"outlinewidth":0,"ticks":""}}}],"histogram":[{"marker":{"pattern":{"fillmode":"overlay","size":10,"solidity":0.2}},"type":"histogram"}],"scattergl":[{"type":"scattergl","marker":{"colorbar":{"outlinewidth":0,"ticks":""}}}],"scatter3d":[{"type":"scatter3d","line":{"colorbar":{"outlinewidth":0,"ticks":""}},"marker":{"colorbar":{"outlinewidth":0,"ticks":""}}}],"scattermapbox":[{"type":"scattermapbox","marker":{"colorbar":{"outlinewidth":0,"ticks":""}}}],"scatterternary":[{"type":"scatterternary","marker":{"colorbar":{"outlinewidth":0,"ticks":""}}}],"scattercarpet":[{"type":"scattercarpet","marker":{"colorbar":{"outlinewidth":0,"ticks":""}}}],"carpet":[{"aaxis":{"endlinecolor":"#2a3f5f","gridcolor":"white","linecolor":"white","minorgridcolor":"white","startlinecolor":"#2a3f5f"},"baxis":{"endlinecolor":"#2a3f5f","gridcolor":"white","linecolor":"white","minorgridcolor":"white","startlinecolor":"#2a3f5f"},"type":"carpet"}],"table":[{"cells":{"fill":{"color":"#EBF0F8"},"line":{"color":"white"}},"header":{"fill":{"color":"#C8D4E3"},"line":{"color":"white"}},"type":"table"}],"barpolar":[{"marker":{"line":{"color":"#E5ECF6","width":0.5},"pattern":{"fillmode":"overlay","size":10,"solidity":0.2}},"type":"barpolar"}],"pie":[{"automargin":true,"type":"pie"}]},"layout":{"autotypenumbers":"strict","colorway":["#636efa","#EF553B","#00cc96","#ab63fa","#FFA15A","#19d3f3","#FF6692","#B6E880","#FF97FF","#FECB52"],"font":{"color":"#2a3f5f"},"hovermode":"closest","hoverlabel":{"align":"left"},"paper_bgcolor":"white","plot_bgcolor":"#E5ECF6","polar":{"bgcolor":"#E5ECF6","angularaxis":{"gridcolor":"white","linecolor":"white","ticks":""},"radialaxis":{"gridcolor":"white","linecolor":"white","ticks":""}},"ternary":{"bgcolor":"#E5ECF6","aaxis":{"gridcolor":"white","linecolor":"white","ticks":""},"baxis":{"gridcolor":"white","linecolor":"white","ticks":""},"caxis":{"gridcolor":"white","linecolor":"white","ticks":""}},"coloraxis":{"colorbar":{"outlinewidth":0,"ticks":""}},"colorscale":{"sequential":[[0.0,"#0d0887"],[0.1111111111111111,"#46039f"],[0.2222222222222222,"#7201a8"],[0.3333333333333333,"#9c179e"],[0.4444444444444444,"#bd3786"],[0.5555555555555556,"#d8576b"],[0.6666666666666666,"#ed7953"],[0.7777777777777778,"#fb9f3a"],[0.8888888888888888,"#fdca26"],[1.0,"#f0f921"]],"sequentialminus":[[0.0,"#0d0887"],[0.1111111111111111,"#46039f"],[0.2222222222222222,"#7201a8"],[0.3333333333333333,"#9c179e"],[0.4444444444444444,"#bd3786"],[0.5555555555555556,"#d8576b"],[0.6666666666666666,"#ed7953"],[0.7777777777777778,"#fb9f3a"],[0.8888888888888888,"#fdca26"],[1.0,"#f0f921"]],"diverging":[[0,"#8e0152"],[0.1,"#c51b7d"],[0.2,"#de77ae"],[0.3,"#f1b6da"],[0.4,"#fde0ef"],[0.5,"#f7f7f7"],[0.6,"#e6f5d0"],[0.7,"#b8e186"],[0.8,"#7fbc41"],[0.9,"#4d9221"],[1,"#276419"]]},"xaxis":{"gridcolor":"white","linecolor":"white","ticks":"","title":{"standoff":15},"zerolinecolor":"white","automargin":true,"zerolinewidth":2},"yaxis":{"gridcolor":"white","linecolor":"white","ticks":"","title":{"standoff":15},"zerolinecolor":"white","automargin":true,"zerolinewidth":2},"scene":{"xaxis":{"backgroundcolor":"#E5ECF6","gridcolor":"white","linecolor":"white","showbackground":true,"ticks":"","zerolinecolor":"white","gridwidth":2},"yaxis":{"backgroundcolor":"#E5ECF6","gridcolor":"white","linecolor":"white","showbackground":true,"ticks":"","zerolinecolor":"white","gridwidth":2},"zaxis":{"backgroundcolor":"#E5ECF6","gridcolor":"white","linecolor":"white","showbackground":true,"ticks":"","zerolinecolor":"white","gridwidth":2}},"shapedefaults":{"line":{"color":"#2a3f5f"}},"annotationdefaults":{"arrowcolor":"#2a3f5f","arrowhead":0,"arrowwidth":1},"geo":{"bgcolor":"white","landcolor":"#E5ECF6","subunitcolor":"white","showland":true,"showlakes":true,"lakecolor":"white"},"title":{"x":0.05},"mapbox":{"style":"light"}}},"xaxis":{"anchor":"y","domain":[0.0,1.0],"title":{"text":"x"}},"yaxis":{"anchor":"x","domain":[0.0,1.0],"title":{"text":"y"}},"legend":{"tracegroupgap":0},"title":{"text":"Totais"}}}'
  • Adicionalmente, para exportá-la como um dict Python padrão, podemos usar:

fig.to_dict() 
{'data': [{'hovertemplate': 'x=%{x}<br>y=%{y}<extra></extra>',
   'legendgroup': '',
   'line': {'color': '#636efa', 'dash': 'solid'},
   'marker': {'symbol': 'circle'},
   'mode': 'lines',
   'name': '',
   'orientation': 'v',
   'showlegend': False,
   'x': array(['TC', 'CDIA', 'LP'], dtype=object),
   'xaxis': 'x',
   'y': array([16, 14,  6]),
   'yaxis': 'y',
   'type': 'scatter'}],
 'layout': {'template': {'data': {'histogram2dcontour': [{'type': 'histogram2dcontour',
      'colorbar': {'outlinewidth': 0, 'ticks': ''},
      'colorscale': [[0.0, '#0d0887'],
       [0.1111111111111111, '#46039f'],
       [0.2222222222222222, '#7201a8'],
       [0.3333333333333333, '#9c179e'],
       [0.4444444444444444, '#bd3786'],
       [0.5555555555555556, '#d8576b'],
       [0.6666666666666666, '#ed7953'],
       [0.7777777777777778, '#fb9f3a'],
       [0.8888888888888888, '#fdca26'],
       [1.0, '#f0f921']]}],
    'choropleth': [{'type': 'choropleth',
      'colorbar': {'outlinewidth': 0, 'ticks': ''}}],
    'histogram2d': [{'type': 'histogram2d',
      'colorbar': {'outlinewidth': 0, 'ticks': ''},
      'colorscale': [[0.0, '#0d0887'],
       [0.1111111111111111, '#46039f'],
       [0.2222222222222222, '#7201a8'],
       [0.3333333333333333, '#9c179e'],
       [0.4444444444444444, '#bd3786'],
       [0.5555555555555556, '#d8576b'],
       [0.6666666666666666, '#ed7953'],
       [0.7777777777777778, '#fb9f3a'],
       [0.8888888888888888, '#fdca26'],
       [1.0, '#f0f921']]}],
    'heatmap': [{'type': 'heatmap',
      'colorbar': {'outlinewidth': 0, 'ticks': ''},
      'colorscale': [[0.0, '#0d0887'],
       [0.1111111111111111, '#46039f'],
       [0.2222222222222222, '#7201a8'],
       [0.3333333333333333, '#9c179e'],
       [0.4444444444444444, '#bd3786'],
       [0.5555555555555556, '#d8576b'],
       [0.6666666666666666, '#ed7953'],
       [0.7777777777777778, '#fb9f3a'],
       [0.8888888888888888, '#fdca26'],
       [1.0, '#f0f921']]}],
    'heatmapgl': [{'type': 'heatmapgl',
      'colorbar': {'outlinewidth': 0, 'ticks': ''},
      'colorscale': [[0.0, '#0d0887'],
       [0.1111111111111111, '#46039f'],
       [0.2222222222222222, '#7201a8'],
       [0.3333333333333333, '#9c179e'],
       [0.4444444444444444, '#bd3786'],
       [0.5555555555555556, '#d8576b'],
       [0.6666666666666666, '#ed7953'],
       [0.7777777777777778, '#fb9f3a'],
       [0.8888888888888888, '#fdca26'],
       [1.0, '#f0f921']]}],
    'contourcarpet': [{'type': 'contourcarpet',
      'colorbar': {'outlinewidth': 0, 'ticks': ''}}],
    'contour': [{'type': 'contour',
      'colorbar': {'outlinewidth': 0, 'ticks': ''},
      'colorscale': [[0.0, '#0d0887'],
       [0.1111111111111111, '#46039f'],
       [0.2222222222222222, '#7201a8'],
       [0.3333333333333333, '#9c179e'],
       [0.4444444444444444, '#bd3786'],
       [0.5555555555555556, '#d8576b'],
       [0.6666666666666666, '#ed7953'],
       [0.7777777777777778, '#fb9f3a'],
       [0.8888888888888888, '#fdca26'],
       [1.0, '#f0f921']]}],
    'surface': [{'type': 'surface',
      'colorbar': {'outlinewidth': 0, 'ticks': ''},
      'colorscale': [[0.0, '#0d0887'],
       [0.1111111111111111, '#46039f'],
       [0.2222222222222222, '#7201a8'],
       [0.3333333333333333, '#9c179e'],
       [0.4444444444444444, '#bd3786'],
       [0.5555555555555556, '#d8576b'],
       [0.6666666666666666, '#ed7953'],
       [0.7777777777777778, '#fb9f3a'],
       [0.8888888888888888, '#fdca26'],
       [1.0, '#f0f921']]}],
    'mesh3d': [{'type': 'mesh3d',
      'colorbar': {'outlinewidth': 0, 'ticks': ''}}],
    'scatter': [{'fillpattern': {'fillmode': 'overlay',
       'size': 10,
       'solidity': 0.2},
      'type': 'scatter'}],
    'parcoords': [{'type': 'parcoords',
      'line': {'colorbar': {'outlinewidth': 0, 'ticks': ''}}}],
    'scatterpolargl': [{'type': 'scatterpolargl',
      'marker': {'colorbar': {'outlinewidth': 0, 'ticks': ''}}}],
    'bar': [{'error_x': {'color': '#2a3f5f'},
      'error_y': {'color': '#2a3f5f'},
      'marker': {'line': {'color': '#E5ECF6', 'width': 0.5},
       'pattern': {'fillmode': 'overlay', 'size': 10, 'solidity': 0.2}},
      'type': 'bar'}],
    'scattergeo': [{'type': 'scattergeo',
      'marker': {'colorbar': {'outlinewidth': 0, 'ticks': ''}}}],
    'scatterpolar': [{'type': 'scatterpolar',
      'marker': {'colorbar': {'outlinewidth': 0, 'ticks': ''}}}],
    'histogram': [{'marker': {'pattern': {'fillmode': 'overlay',
        'size': 10,
        'solidity': 0.2}},
      'type': 'histogram'}],
    'scattergl': [{'type': 'scattergl',
      'marker': {'colorbar': {'outlinewidth': 0, 'ticks': ''}}}],
    'scatter3d': [{'type': 'scatter3d',
      'line': {'colorbar': {'outlinewidth': 0, 'ticks': ''}},
      'marker': {'colorbar': {'outlinewidth': 0, 'ticks': ''}}}],
    'scattermapbox': [{'type': 'scattermapbox',
      'marker': {'colorbar': {'outlinewidth': 0, 'ticks': ''}}}],
    'scatterternary': [{'type': 'scatterternary',
      'marker': {'colorbar': {'outlinewidth': 0, 'ticks': ''}}}],
    'scattercarpet': [{'type': 'scattercarpet',
      'marker': {'colorbar': {'outlinewidth': 0, 'ticks': ''}}}],
    'carpet': [{'aaxis': {'endlinecolor': '#2a3f5f',
       'gridcolor': 'white',
       'linecolor': 'white',
       'minorgridcolor': 'white',
       'startlinecolor': '#2a3f5f'},
      'baxis': {'endlinecolor': '#2a3f5f',
       'gridcolor': 'white',
       'linecolor': 'white',
       'minorgridcolor': 'white',
       'startlinecolor': '#2a3f5f'},
      'type': 'carpet'}],
    'table': [{'cells': {'fill': {'color': '#EBF0F8'},
       'line': {'color': 'white'}},
      'header': {'fill': {'color': '#C8D4E3'}, 'line': {'color': 'white'}},
      'type': 'table'}],
    'barpolar': [{'marker': {'line': {'color': '#E5ECF6', 'width': 0.5},
       'pattern': {'fillmode': 'overlay', 'size': 10, 'solidity': 0.2}},
      'type': 'barpolar'}],
    'pie': [{'automargin': True, 'type': 'pie'}]},
   'layout': {'autotypenumbers': 'strict',
    'colorway': ['#636efa',
     '#EF553B',
     '#00cc96',
     '#ab63fa',
     '#FFA15A',
     '#19d3f3',
     '#FF6692',
     '#B6E880',
     '#FF97FF',
     '#FECB52'],
    'font': {'color': '#2a3f5f'},
    'hovermode': 'closest',
    'hoverlabel': {'align': 'left'},
    'paper_bgcolor': 'white',
    'plot_bgcolor': '#E5ECF6',
    'polar': {'bgcolor': '#E5ECF6',
     'angularaxis': {'gridcolor': 'white', 'linecolor': 'white', 'ticks': ''},
     'radialaxis': {'gridcolor': 'white', 'linecolor': 'white', 'ticks': ''}},
    'ternary': {'bgcolor': '#E5ECF6',
     'aaxis': {'gridcolor': 'white', 'linecolor': 'white', 'ticks': ''},
     'baxis': {'gridcolor': 'white', 'linecolor': 'white', 'ticks': ''},
     'caxis': {'gridcolor': 'white', 'linecolor': 'white', 'ticks': ''}},
    'coloraxis': {'colorbar': {'outlinewidth': 0, 'ticks': ''}},
    'colorscale': {'sequential': [[0.0, '#0d0887'],
      [0.1111111111111111, '#46039f'],
      [0.2222222222222222, '#7201a8'],
      [0.3333333333333333, '#9c179e'],
      [0.4444444444444444, '#bd3786'],
      [0.5555555555555556, '#d8576b'],
      [0.6666666666666666, '#ed7953'],
      [0.7777777777777778, '#fb9f3a'],
      [0.8888888888888888, '#fdca26'],
      [1.0, '#f0f921']],
     'sequentialminus': [[0.0, '#0d0887'],
      [0.1111111111111111, '#46039f'],
      [0.2222222222222222, '#7201a8'],
      [0.3333333333333333, '#9c179e'],
      [0.4444444444444444, '#bd3786'],
      [0.5555555555555556, '#d8576b'],
      [0.6666666666666666, '#ed7953'],
      [0.7777777777777778, '#fb9f3a'],
      [0.8888888888888888, '#fdca26'],
      [1.0, '#f0f921']],
     'diverging': [[0, '#8e0152'],
      [0.1, '#c51b7d'],
      [0.2, '#de77ae'],
      [0.3, '#f1b6da'],
      [0.4, '#fde0ef'],
      [0.5, '#f7f7f7'],
      [0.6, '#e6f5d0'],
      [0.7, '#b8e186'],
      [0.8, '#7fbc41'],
      [0.9, '#4d9221'],
      [1, '#276419']]},
    'xaxis': {'gridcolor': 'white',
     'linecolor': 'white',
     'ticks': '',
     'title': {'standoff': 15},
     'zerolinecolor': 'white',
     'automargin': True,
     'zerolinewidth': 2},
    'yaxis': {'gridcolor': 'white',
     'linecolor': 'white',
     'ticks': '',
     'title': {'standoff': 15},
     'zerolinecolor': 'white',
     'automargin': True,
     'zerolinewidth': 2},
    'scene': {'xaxis': {'backgroundcolor': '#E5ECF6',
      'gridcolor': 'white',
      'linecolor': 'white',
      'showbackground': True,
      'ticks': '',
      'zerolinecolor': 'white',
      'gridwidth': 2},
     'yaxis': {'backgroundcolor': '#E5ECF6',
      'gridcolor': 'white',
      'linecolor': 'white',
      'showbackground': True,
      'ticks': '',
      'zerolinecolor': 'white',
      'gridwidth': 2},
     'zaxis': {'backgroundcolor': '#E5ECF6',
      'gridcolor': 'white',
      'linecolor': 'white',
      'showbackground': True,
      'ticks': '',
      'zerolinecolor': 'white',
      'gridwidth': 2}},
    'shapedefaults': {'line': {'color': '#2a3f5f'}},
    'annotationdefaults': {'arrowcolor': '#2a3f5f',
     'arrowhead': 0,
     'arrowwidth': 1},
    'geo': {'bgcolor': 'white',
     'landcolor': '#E5ECF6',
     'subunitcolor': 'white',
     'showland': True,
     'showlakes': True,
     'lakecolor': 'white'},
    'title': {'x': 0.05},
    'mapbox': {'style': 'light'}}},
  'xaxis': {'anchor': 'y', 'domain': [0.0, 1.0], 'title': {'text': 'x'}},
  'yaxis': {'anchor': 'x', 'domain': [0.0, 1.0], 'title': {'text': 'y'}},
  'legend': {'tracegroupgap': 0},
  'title': {'text': 'Totais'}}}

17.5. Hierarquia do objeto Figure (esquema)#

O esquema de um objeto Figure manipulável pela Plotly possui três atributos de primeiro nível e vários atributos de níveis inferiores. Os três primários são:

  • data: contém uma lista de dicts que controlam os traços (substratos, vetores de dados, eixos, glifos etc.)

  • layout: dict de outros atributos que controlam o posicionamento e partes não relacionadas à figura (margens, cores, fontes, menus, sliders etc.)

  • frame: lista de dicts que definem sequências de frames em plots animados controlados por botões de menu ou sliders.

Podemos criar uma RV do zero a partir de um dataframe acrescentando valores aos atributos explicitamente. Vejamos um exemplo:

import plotly.express as px
import plotly.graph_objects as go

df = px.data.tips()
df
total_bill tip sex smoker day time size
0 16.99 1.01 Female No Sun Dinner 2
1 10.34 1.66 Male No Sun Dinner 3
2 21.01 3.50 Male No Sun Dinner 3
3 23.68 3.31 Male No Sun Dinner 2
4 24.59 3.61 Female No Sun Dinner 4
... ... ... ... ... ... ... ...
239 29.03 5.92 Male No Sat Dinner 3
240 27.18 2.00 Female Yes Sat Dinner 2
241 22.67 2.00 Male Yes Sat Dinner 2
242 17.82 1.75 Male No Sat Dinner 2
243 18.78 3.00 Female No Thur Dinner 2

244 rows × 7 columns

# Figura vazia
fig = go.Figure() 
print(fig)
Figure({
    'data': [], 'layout': {'template': '...'}
})
# Adiciona traço do tipo histograma
fig.add_trace(go.Histogram(x=df['total_bill']),)
print(fig)
Figure({
    'data': [{'type': 'histogram',
              'x': array([16.99, 10.34, 21.01, ..., 22.67, 17.82, 18.78])}],
    'layout': {'template': '...'}
})
# Atualiza layout
fig.update_layout(
    title='Histogram of Bills',
    xaxis_title='Total',
    yaxis_title='Frequency',
    bargap=0.05,    
    showlegend=False
)
print(fig)
Figure({
    'data': [{'type': 'histogram',
              'x': array([16.99, 10.34, 21.01, ..., 22.67, 17.82, 18.78])}],
    'layout': {'bargap': 0.05,
               'showlegend': False,
               'template': '...',
               'title': {'text': 'Histogram of Bills'},
               'xaxis': {'title': {'text': 'Total'}},
               'yaxis': {'title': {'text': 'Frequency'}}}
})
# Visualização
plot(fig, show_link=False,filename='dw-plotly-exemplo-4.html')
display(HTML('dw-plotly-exemplo-4.html'))
# Atualiza cor do traço
fig.update_traces(marker_color='#02a5e2')

plot(fig, show_link=False,filename='dw-plotly-exemplo-5.html')
display(HTML('dw-plotly-exemplo-5.html'))

17.5.1. Estilos personalizados#

Quando não há necessidade de se criar algo do zero, pode-se usar as interfaces disponíveis. O dado anterior pode ser manipulado através dos passos a seguir:

df = px.data.tips()
fig = px.histogram(df,x="total_bill",title="Histogram of Bills")
fig.update_traces(marker_color='#02a5e2')
fig.update_layout(
    title='Histogram of Bills',
    xaxis_title='Total',
    yaxis_title='Frequency',
    bargap=0.05,    
    showlegend=False
)

plot(fig, show_link=False,filename='dw-plotly-exemplo-6.html')
display(HTML('dw-plotly-exemplo-6.html'))

Agora, vamos manipular o estilo para ter uma RV melhor:

# interface
fig = px.histogram(df,x="day",
                   y="total_bill",
                   title="Histogram of Bills",
                   color="sex",
                   width=450,
                   height=350,
                   labels={
                       "sex": 'Gender',
                       "day": "Day of Week",
                       "total_bill": "Receipts"
                   },
                   category_orders={
                       "day": ['Thur','Fri', 'Sat','Sun'],
                       "sex": ['Male','Female']
                   },
                   color_discrete_map={
                       "Male": "orange", # CSS colors
                       "Female": "orchid"
                   },
                   template="plotly" # ['ggplot2', 'seaborn', 'simple_white', 
                                     # 'plotly','plotly_white', 'plotly_dark', 
                                     # 'presentation', 'xgridoff','ygridoff', 
                                     # 'gridon', 'none']
                   )

# atualizações
fig.update_yaxes(
    tickprefix="US$", 
    showgrid=True)

fig.update_layout(
    font_family="Rockwell",
    legend=dict(title=None, orientation="v", y=1, yanchor="bottom", x=0.8, xanchor="center"))

fig.add_shape(
    type="line", 
    line_color="black", 
    line_width=1.0, 
    opacity=1, 
    line_dash="dash",
    x0=0, x1=1, xref="paper", y0=950, y1=950, yref="y")

fig.add_annotation(
    text="below!", 
    x="Fri",
    y=400, 
    arrowhead=1, 
    showarrow=True)


plot(fig, show_link=False,filename='dw-plotly-exemplo-7.html')
display(HTML('dw-plotly-exemplo-7.html'))