Xiangxi Zheng1, Kuang He2, Jiayi Hu3, Ping Yu1, Rui Yan4, Yuan Yao1†, Peng Hou2, Anxiang Zeng2, Alex Jinpeng Wang5†
CharTide is a data-centric framework that systematically redesigns both training and alignment data for chart-to-code generation. Existing approaches are fundamentally constrained by data-centric limitations: simply scaling homogeneous chart-code pairs conflates visual perception with program logic, preventing models from fully leveraging the richness of multimodal supervision. To break this bottleneck, CharTide introduces (i) a Tri-Perspective Tuning strategy that explicitly decouples training into visual perception, pure-text code logic, and modality fusion streams, yielding a 2M-sample dataset that enables a 7B model to surpass specialized baselines using only supervised data; and (ii) an Inquiry-Driven RL framework grounded in the principle of information invariance, where a frozen Inspector objectively verifies generated charts through atomic QA tasks to provide verifiable, low-variance reward signals. Experiments on ChartMimic, Plot2Code, and ChartX show that CharTide-7B/8B significantly outperforms open-source baselines, surpasses GPT-4o, and is competitive with GPT-5.
2026.04.15We upload our model weights CharTide-7B and CharTide-8B to HuggingFace.2026.04.07🎉 Our CharTide is accepted by ACL 2026 Main!
| Model | Backbone | Download Link |
|---|---|---|
| CharTide-7B | Qwen2.5-VL-7B-Instruct | Fengx1nn/CharTide-7B |
| CharTide-8B | Qwen3-VL-8B-Instruct | Fengx1nn/CharTide-8B |
We compare CharTide against proprietary and open-source models on ChartMimic, Plot2Code, and ChartX. For Plot2Code we replace the GPT-4V evaluator with GPT-4o and report normalized scores over the full test set to avoid survivorship bias (see paper Appendix for details). In each column bold marks the best open-source result and underline marks the second-best.
| Model | ChartMimic | Plot2Code* | ChartX | ||||
|---|---|---|---|---|---|---|---|
| Exec.Rate | Low-Level | High-Level | Exec.Rate | Text Match | Rating | GPT score | |
| Proprietary | |||||||
| GPT-4o | 94.7 | 80.0 | 87.7 | 87.1 | 52.6 | 5.66 | 2.61 |
| GPT-5 | 96.8 | 82.1 | 94.7 | 87.8 | 61.9 | 7.28 | 3.59 |
| Gemini-2.5-Pro | 94.7 | 79.2 | 92.5 | 88.6 | 69.1 | 7.45 | 3.27 |
| Open-Source General-Domain | |||||||
| Qwen2.5-VL-7B | 75.0 | 49.0 | 51.8 | 68.9 | 33.7 | 3.04 | 2.74 |
| Qwen2.5-VL-72B | 75.3 | 51.9 | 56.6 | 59.3 | 33.2 | 3.61 | 2.85 |
| Qwen3-VL-8B | 81.7 | 63.7 | 71.5 | 76.5 | 36.3 | 3.91 | 2.93 |
| Qwen3-VL-30B-A3B | 85.2 | 67.7 | 76.5 | 87.1 | 46.7 | 4.85 | 2.73 |
| Qwen3-VL-235B-A22B | 93.3 | 76.8 | 87.6 | 84.8 | 46.2 | 5.19 | 3.35 |
| Open-Source Chart-Domain | |||||||
| ChartCoder-7B | 89.5 | 72.1 | 78.5 | 68.9 | 31.1 | 2.73 | 2.79 |
| ChartMaster-7B | 93.5 | 77.1 | 83.3 | 89.4 | 53.6 | 4.73 | 2.82 |
| MSRL-7B-SFT | 92.6 | 71.2 | 82.8 | 77.3 | 34.7 | 3.71 | 3.19 |
| MSRL-7B | 94.3 | 76.1 | 87.4 | 62.9 | 31.9 | 3.24 | 3.22 |
| VinciCoder-7B | 91.2 | 77.0 | 83.4 | 68.9 | 33.6 | 3.39 | 3.18 |
| VinciCoder-8B | 90.2 | 75.8 | 81.4 | 85.6 | 49.8 | 4.49 | 3.21 |
| CharTide-7B-SFT | 94.3 | 79.3 | 86.4 | 88.6 | 58.2 | 5.17 | 3.00 |
| CharTide-7B | 96.7 | 81.7 | 91.6 | 89.4 | 59.6 | 5.60 | 3.22 |
| CharTide-8B-SFT | 93.7 | 80.9 | 89.4 | 86.4 | 58.1 | 5.46 | 3.19 |
| CharTide-8B | 97.3 | 83.0 | 92.7 | 91.7 | 64.6 | 5.93 | 3.23 |
Versions:
transformers>=4.57,qwen-vl-utils==0.0.10for CharTide-7B;qwen-vl-utils>=0.0.11for CharTide-8B (Qwen3-VL backbone).
import re
import torch
from transformers import AutoProcessor, Qwen2_5_VLForConditionalGeneration
from qwen_vl_utils import process_vision_info # qwen-vl-utils==0.0.10
model_path = "Fengx1nn/CharTide-7B"
model = Qwen2_5_VLForConditionalGeneration.from_pretrained(
model_path,
torch_dtype=torch.bfloat16,
device_map="cuda",
attn_implementation="sdpa",
)
processor = AutoProcessor.from_pretrained(
model_path,
min_pixels=256 * 28 * 28,
max_pixels=1280 * 28 * 28,
)
instruction = (
"You are an expert Python developer who specializes in writing matplotlib code "
"based on a given picture. I found a very nice picture in a STEM paper, but there "
"is no corresponding source code available. I need your help to generate the "
"Python code that can reproduce the picture based on the picture I provide.\n"
"Now, please give me the matplotlib code that reproduces the picture below, "
"starting with \"```python\" and ending with \"```\"."
)
messages = [{
"role": "user",
"content": [
{"type": "image", "image": "assets/example_input.png"},
{"type": "text", "text": instruction},
],
}]
text = processor.apply_chat_template(messages, tokenize=False, add_generation_prompt=True)
images, videos = process_vision_info(messages)
inputs = processor(text=[text], images=images, videos=videos, padding=True, return_tensors="pt").to(model.device)
with torch.inference_mode():
generated_ids = model.generate(**inputs, max_new_tokens=4096, do_sample=False)
generated_ids = [o[len(i):] for i, o in zip(inputs.input_ids, generated_ids)]
output = processor.tokenizer.batch_decode(generated_ids, skip_special_tokens=True, clean_up_tokenization_spaces=False)[0]
m = re.search(r"```python\s*(.*?)```", output, re.DOTALL)
generated_code = m.group(1) if m else output
print(generated_code)The 8B model uses a different model class (Qwen3VLForConditionalGeneration) and a newer qwen-vl-utils. Everything else is identical to the 7B example above.
# pip install -U "qwen-vl-utils>=0.0.11" # required for Qwen3-VL
import torch
from transformers import AutoProcessor, Qwen3VLForConditionalGeneration
from qwen_vl_utils import process_vision_info
model_path = "Fengx1nn/CharTide-8B"
model = Qwen3VLForConditionalGeneration.from_pretrained(
model_path,
torch_dtype=torch.bfloat16,
device_map="cuda",
attn_implementation="sdpa",
)
processor = AutoProcessor.from_pretrained(
model_path,
min_pixels=256 * 28 * 28,
max_pixels=1280 * 28 * 28,
)
# ... same `messages` / `apply_chat_template` / `generate` as the 7B exampleThe left chart is the user-provided input, the middle and right are rendered from the matplotlib code produced by CharTide-7B and CharTide-8B respectively.
If you find this project useful, please feel free to leave a star and cite our paper:
@misc{zheng2026chartidedatacentriccharttocodegeneration,
title={CharTide: Data-Centric Chart-to-Code Generation via Tri-Perspective Tuning and Inquiry-Driven Evolution},
author={Xiangxi Zheng and Kuang He and Jiayi Hu and Ping Yu and Rui Yan and Yuan Yao and Peng Hou and Anxiang Zeng and Alex Jinpeng Wang},
year={2026},
eprint={2604.22192},
archivePrefix={arXiv},
primaryClass={cs.CV},
url={https://arxiv.org/abs/2604.22192},
}

