# Création et modification de graphiques

Tracez des graphiques prêts à publier à partir de vos données, puis modifiez-les avec de nouvelles instructions.

Source : https://scifig.ai/fr/docs/api/charts

## Champs du formulaire

`POST /charts/generations` accepte `multipart/form-data`. Portée requise : `figures:generate`.

| Champ | Type | Obligatoire | Valeur par défaut | Règles |
| --- | --- | --- | --- | --- |
| data | file | oui | — | CSV, TSV, TXT, XLSX ou XLS jusqu’à 8 MB, avec une ligne d’en-tête ; le séparateur des CSV, TSV et TXT, virgule, tabulation ou point-virgule, est détecté |
| request | string | oui | — | Ce qu’il faut tracer, en langage courant ; de 1 à 16 000 caractères |
| chart_types | string | non | choisi à partir des données | Valeurs séparées par des virgules ou tableau JSON ; voir la liste ci-dessous |
| journal_style | string | non | `default` | `default`, `nature`, `science`, `cell`, `plos` ou `acs` |
| figure_width | string | non | `double` | Largeur de colonne `single`, `onehalf` ou `double` ; PLOS et ACS n’ont pas de `onehalf` |
| color_palette | string | non | `okabe_ito` | `okabe_ito`, `wong`, `tol_bright`, `tol_muted`, `nature`, `science`, `nejm`, `lancet` ou `jama` |
| sheet_name | string | pour les classeurs comportant plusieurs feuilles | — | La feuille du fichier XLSX ou XLS à utiliser pour le graphique ; de 1 à 255 caractères |

## Erreurs de données

- Les données sont analysées avant toute création, avec le même analyseur que sur le site. Des données illisibles renvoient `400 INVALID_REQUEST` avec `details.field = data` et le code de l’analyseur dans `details.reason`, par exemple `DATACHART_CSV_INVALID` ou `DATACHART_TOO_MANY_ROWS`. Aucune tâche n’est exécutée et aucun crédit n’est utilisé.
- Un classeur comportant plusieurs feuilles sans `sheet_name` renvoie `400 INVALID_REQUEST` avec `DATACHART_WORKSHEET_REQUIRED` et les noms des feuilles dans `details.sheet_names`. Renvoyez la requête avec `sheet_name`. Un `sheet_name` inconnu renvoie `DATACHART_WORKSHEET_INVALID`, également avec `details.sheet_names`.
- Un type de fichier absent de la liste renvoie `UNSUPPORTED_DATA_FORMAT` ; un fichier dépassant la taille limite renvoie `DATA_FILE_TOO_LARGE`.
- Chaque nouveau fichier de données compte dans les limites d’importation du site ; au-delà, la réponse est `429 RATE_LIMITED` avec `UPLOAD_RATE_LIMITED` ou `UPLOAD_DAILY_LIMIT_REACHED`. Réessayer avec la même clé ne compte pas le fichier à nouveau.

## Types de graphiques

`bar`, `line`, `scatter`, `dot`, `frequency_dot`, `pie`, `nested_pie`, `timeseries`, `waterfall`, `stacked_area`, `radar`, `boxplot`, `violin`, `histogram`, `density`, `raincloud`, `beeswarm`, `qq`, `ogive`, `ecdf`, `ridgeline`, `regression`, `errorbar`, `correlation`, `bland_altman`, `funnel`, `standard_curve`, `bubble`, `hexbin`, `paired_dot`, `volcano`, `kaplan_meier`, `forest`, `roc`, `manhattan`, `ma_plot`, `enrichment`, `dose_response`, `growth_curve`, `enzyme_kinetics`, `precision_recall`, `calibration_curve`, `confusion_matrix`, `heatmap`, `dendrogram`, `upset`, `sankey`, `stem_leaf`, `calendar_heatmap`

## Résultats et crédits

100 crédits par graphique. Une tâche réussie fournit la même figure en PNG, PDF, TIFF et EPS, dimensionnée pour la colonne de la revue. Chaque résultat contient un `editor_url`, qui ouvre le graphique dans sa conversation DataChart sur le site.

## Modifications

`POST /charts/edits` avec le JSON `{"job": "<chart job id>", "instruction": "..."}` modifie le graphique produit par la tâche en conservant ses données, ses types de graphiques, son style de revue et sa palette. `instruction` contient de 1 à 16 000 caractères. 100 crédits, comme dans l’espace de travail.

- La tâche doit être l’une de vos tâches de graphique, sinon `400 INVALID_REQUEST` avec `JOB_NOT_FOUND`. Si elle a échoué, la réponse est `400 INVALID_REQUEST` avec `JOB_NOT_SUCCEEDED`.
- Si elle est encore en cours, la réponse est `409 REVISION_CONFLICT` avec `details.reason = PARENT_JOB_RUNNING` et `Retry-After`. Cette erreur permet une nouvelle tentative : envoyez la même requête avec la même clé une fois la tâche terminée.
- Seule la version la plus récente peut être modifiée, comme dans l’espace de travail. Modifiez la tâche la plus récente de la chaîne ; une version antérieure renvoie `409 REVISION_CONFLICT` avec `NOT_LATEST_REVISION`, également si une nouvelle version a été créée sur le site ou si une autre modification de la même version a été acceptée en premier.
- Une seule modification à la fois : tant qu’une modification de la version actuelle est en cours, une autre renvoie `409 REVISION_CONFLICT` avec `EDIT_IN_PROGRESS`. Attendez la tâche en cours, puis modifiez son résultat.
- Un graphique créé sur le site avant le format actuel ne peut pas être poursuivi via l’API : `400 INVALID_REQUEST` avec `JOB_NOT_EDITABLE`.
- Les modifications effectuées via l’API apparaissent dans la même conversation DataChart sur le site.

## cURL

```bash
curl -X POST https://scifig.ai/api/v1/charts/generations \
  -H "Authorization: Bearer $SCIFIG_API_KEY" \
  -H "Idempotency-Key: $(uuidgen)" \
  -H "Prefer: wait=25" \
  -F "data=@measurements.csv" \
  -F "request=Box plot of response by group with individual points" \
  -F "journal_style=nature"
```

## JavaScript

```javascript
import { readFile } from 'node:fs/promises';

const form = new FormData();
form.set('data', new Blob([await readFile('measurements.csv')]), 'measurements.csv');
form.set('request', 'Box plot of response by group with individual points');
form.set('journal_style', 'nature');

const response = await fetch('https://scifig.ai/api/v1/charts/generations', {
  method: 'POST',
  headers: {
    Authorization: `Bearer ${process.env.SCIFIG_API_KEY}`,
    'Idempotency-Key': crypto.randomUUID(),
    Prefer: 'wait=25',
  },
  body: form,
});
const result = await response.json();
console.log(response.status, result);
```

## Python

```python
import os
import uuid

import requests

headers = {
    "Authorization": f"Bearer {os.environ['SCIFIG_API_KEY']}",
    "Idempotency-Key": str(uuid.uuid4()),
    "Prefer": "wait=25",
}
response = requests.post(
    "https://scifig.ai/api/v1/charts/generations",
    headers=headers,
    files={"data": open("measurements.csv", "rb")},
    data={"request": "Box plot of response by group with individual points", "journal_style": "nature"},
    timeout=60,
)
print(response.status_code, response.json())
```
