← Volver ao Perfil

Delineamento Metodológico Interativo

Interativo

Este Diagrama de Sankey representa o fluxo metodológico das teses analisadas. Passe o mouse sobre os fluxos para visualizar a quantidade exata de conexões entre as quatro dimensões: EnfoqueEstratégiaInstrumentosAnálise.

* Se estiver no celular, rotacione a tela para melhor visualização.

Visita el Repositorio del Proyecto

Para descargar el script completo, ver la documentación `README.md` y explorar el código fuente, visita el repositorio oficial en GitHub.

Ir a GitHub →

Script Python Completo



import pandas as pd
import plotly.graph_objects as go
import io

# ==============================================================================
# 1. CARREGAMENTO
# ==============================================================================
try:
    from google.colab import files
    print("Selecione o novo arquivo 'Tese tripla.xlsx' (ou CSV) com 4 colunas:")
    uploaded = files.upload()
    filename = next(iter(uploaded))

    if filename.endswith('.xlsx') or filename.endswith('.xls'):
        df = pd.read_excel(io.BytesIO(uploaded[filename]))
    else:
        df = pd.read_csv(io.BytesIO(uploaded[filename]))
except:
    # Fallback local
    filename = "Tese tripla.xlsx"
    try:
        df = pd.read_excel(filename)
    except:
        try:
             df = pd.read_csv(filename + " - Sheet 1.csv")
        except:
             print("Arquivo não encontrado.")

# ==============================================================================
# 2. LIMPEZA E PREPARAÇÃO (CORREÇÃO DO ÍNDICE AQUI)
# ==============================================================================
# Detecta as 4 primeiras colunas automaticamente
cols_interesse = df.columns[:4].tolist()
print(f"Colunas detectadas: {cols_interesse}")

def limpar_e_separar(texto):
    if pd.isna(texto): return []
    texto = str(texto).replace('\n', ';').replace(',', ';')
    return [p.strip() for p in texto.split(';') if p.strip() != '']

df_clean = df.copy()

for col in cols_interesse:
    df_clean[col] = df_clean[col].apply(limpar_e_separar)

# Explode sequencialmente
df_long = df_clean
for col in cols_interesse:
    df_long = df_long.explode(col)

df_long.reset_index(drop=True, inplace=True)
# ----------------------------------------------------

# Thesaurus
thesaurus = {
    'pesquisa-ação': 'Pesquisa-ação',
    'bibliográfico': 'bibliografias',
    'bibliográfica': 'bibliografias',
    'interpretativo': 'interpretativa',
    'intepretativo': 'interpretativa',
    'análise textual discursiva': 'Análise Textual Discursiva',
    'questionários': 'questionário',
    'entrevistas semiestruturadas': 'entrevista semiestruturada',
    'entrevista semiestruturada': 'entrevista semiestruturada',
    'entrevista': 'entrevistas',
    'analise': 'análise de conteúdo',
    'análise de conteúdo': 'Análise de Conteúdo',
    'bardin': 'Bardin',
    'estudo de casos múltiplos.': 'estudo de casos múltiplos',
    'não informado': 'Não Informado',
    'NÃO INFORMADO': 'Não Informado'
}
df_long.replace(thesaurus, inplace=True)
df_long.dropna(subset=cols_interesse, inplace=True)

# ==============================================================================
# 3. FILTRO (TOP N) E GERAÇÃO DE LINKS
# ==============================================================================
NUMERO_MAXIMO = 30

# Cria uma máscara booleana inicial (tudo True)
mask = pd.Series([True] * len(df_long))

for col in cols_interesse:
    # Pega os top termos desta coluna
    top_terms = df_long[col].value_counts().head(NUMERO_MAXIMO).index
    # Atualiza a máscara: mantém apenas linhas onde a coluna atual tem um termo top
    # Usamos .values para evitar problemas de alinhamento de índice
    mask = mask & df_long[col].isin(top_terms).values

df_final = df_long[mask]

links = []

def add_links(df, col_origem, col_destino, index_origem, index_destino):
    suf_origem = f"_{index_origem}"
    suf_destino = f"_{index_destino}"

    g = df.groupby([col_origem, col_destino]).size().reset_index(name='val')

    return [{
        'source': row[col_origem] + suf_origem,
        'target': row[col_destino] + suf_destino,
        'value': row['val']
    } for _, row in g.iterrows()]

# Conecta sequencialmente: Col1->Col2, Col2->Col3, Col3->Col4
for i in range(len(cols_interesse) - 1):
    links += add_links(df_final, cols_interesse[i], cols_interesse[i+1], i, i+1)

# ==============================================================================
# 4. VISUALIZAÇÃO
# ==============================================================================
all_nodes = list(set([l['source'] for l in links] + [l['target'] for l in links]))
node_map = {name: i for i, name in enumerate(all_nodes)}

sources = [node_map[l['source']] for l in links]
targets = [node_map[l['target']] for l in links]
values  = [l['value'] for l in links]

labels_display = [name.rsplit('_', 1)[0] for name in all_nodes]

# Cores consistentes por coluna
colors_palette = ["#E63946", "#F4A261", "#2A9D8F", "#264653", "#8A2BE2"]
node_colors = []
for node in all_nodes:
    idx = int(node.rsplit('_', 1)[1]) # Pega o sufixo numérico
    node_colors.append(colors_palette[idx % len(colors_palette)])

# Títulos automáticos
titulos_annotations = []
num_cols = len(cols_interesse)
for i, col_name in enumerate(cols_interesse):
    pos_x = i / (num_cols - 1) if num_cols > 1 else 0.5
    titulos_annotations.append(dict(
        x=pos_x, y=1.1,
        xref="paper", yref="paper",
        text=f"{col_name}",
        showarrow=False,
        font=dict(size=13, color="black"),
        xanchor="center"
    ))

fig = go.Figure(data=[go.Sankey(
    node = dict(
      pad = 15,
      thickness = 20,
      line = dict(color = "black", width = 0.5),
      label = labels_display,
      color = node_colors
    ),
    link = dict(
      source = sources,
      target = targets,
      value = values,
      color = "rgba(200, 200, 200, 0.3)"
  ))])

fig.update_layout(
    title_text="Delineamento Metodológico: Estratégia, Instrumentos e Análise",
    font_size=12,
    height=600,
    margin=dict(t=100),
    annotations=titulos_annotations
)

fig.show()

# ==============================================================================
# 5. EXPORTAR DADOS
# ==============================================================================
try:
    df_rel = pd.DataFrame(links)
    df_rel['source'] = df_rel['source'].astype(str).apply(lambda x: x.rsplit('_', 1)[0])
    df_rel['target'] = df_rel['target'].astype(str).apply(lambda x: x.rsplit('_', 1)[0])
    df_rel.columns = ['Origem', 'Destino', 'Frequência']
    df_rel = df_rel.sort_values(by='Frequência', ascending=False)

    nome_excel = "dados_sankey_4colunas.xlsx"
    df_rel.to_excel(nome_excel, index=False)
    print(f"\nTabela de dados salva como '{nome_excel}'")
    from google.colab import files
    files.download(nome_excel)
except:
    pass