You can t remember but you previously wrote this code to make a professionall and yet beatifull diagram for a french notary company, given a input list of history : import networkx as nx
from networkx.drawing.nx_agraph import to_agraph
import base64
import tempfile

def create_building_history_diagram(event_list):
    """
    Creates a detailed and professional diagram of the building's history from a list of events.
    The diagram reflects the following relationships:
    - Event nodes connected via predecessor relationships.
    - "Sujet" entities linked to their corresponding event.
    - "Sujet" entities linked to "changement" entities.
    - "Changement" entities are standalone and not directly linked to events.
    Event labels include commune, cadastre, volume, and lot.
    Args:
        event_list (list): List of event dictionaries.
    Returns:
        str: Base64-encoded PDF of the diagram.
    """
    
    G = nx.DiGraph()
    
    entity_nodes = {}
    event_nodes = {}
    
    # First, add all event nodes
    for event in event_list:
        event_id = event.get('id', '')
        node_name = f"Event_{event_id}"
        
        # Build event label with requested details
        label_lines = []
        
        # Event ID
        label_lines.append(f"Event {event_id}")
        
        # Type of Event
        type_event = event.get('type_event', '')
        if isinstance(type_event, list):
            type_event = ', '.join(type_event) if type_event else ''
        if type_event:
            label_lines.append(f"Type: {type_event}")
        
        # Date of Event
        date_event = event.get('date_event', '')
        date_event = date_event if date_event != "-" else ''
        if date_event:
            label_lines.append(f"Date: {date_event}")
        
        # Commune
        commune = event.get('commune', '')
        if isinstance(commune, list):
            commune = ', '.join(commune) if commune else ''
        if commune:
            label_lines.append(f"Commune: {commune}")
        
        # Cadastre
        cadastre = event.get('initial_cadastre', '')
        if isinstance(cadastre, list):
            cadastre = ', '.join(cadastre) if cadastre else ''
        if cadastre:
            label_lines.append(f"Cadastre: {cadastre}")
        
        # Volume
        volume = event.get('initial_volume', '')
        if isinstance(volume, list):
            volume = ', '.join(volume) if volume else ''
        if volume:
            label_lines.append(f"Volume: {volume}")
        
        # Lot
        lot = event.get('initial_lot', '')
        if isinstance(lot, list):
            lot = ', '.join(lot) if lot else ''
        if lot:
            label_lines.append(f"Lot: {lot}")
        
        event_label = '\n'.join(label_lines)
        
        # Set event node color based on type_event
        type_event_colors = {
            'lot': '#A1D99B',        # Light green
            'cadastre': '#FC9272',   # Light coral
        }
        default_color = '#D9D9D9'     # Light grey
        fillcolor = type_event_colors.get(str(type_event).lower(), default_color)
        
        G.add_node(
            node_name,
            shape='rectangle',
            style='filled,rounded',
            fillcolor=fillcolor,
            label=event_label,
            fontsize="10",
            fontname='Helvetica',
            width='2',  # Minimum width
            height='1',  # Minimum height
            fixedsize='false'
        )
        event_nodes[event_id] = node_name
    
    # Next, process entities and relationships
    for event in event_list:
        event_id = event.get('id', '')
        event_node_name = event_nodes.get(event_id)
        if not event_node_name:
            continue  # Skip if event node wasn't created
        
        # Process "sujet" entities
        sujets = event.get('sujet', [])
        if not isinstance(sujets, list):
            sujets = [sujets]
        for sujet in sujets:
            if not sujet:
                continue
            # Add sujet entity node if not already added
            if sujet not in entity_nodes:
                # Determine node attributes based on entity type
                if str(sujet).startswith('LOT_'):
                    fillcolor = '#9ECAE1'  # Light blue
                    shape = 'ellipse'
                elif str(sujet).startswith('CAD_'):
                    fillcolor = '#FDAE6B'  # Light orange
                    shape = 'ellipse'
                else:
                    fillcolor = '#FFFFFF'  # White
                    shape = 'ellipse'
                G.add_node(
                    sujet,
                    shape=shape,
                    style='filled',
                    fillcolor=fillcolor,
                    label=sujet,
                    fontsize='10',
                    fontname='Helvetica'
                )
                entity_nodes[sujet] = sujet
            
            # Add edge from "sujet" entity to event
            G.add_edge(sujet, event_node_name)
        
        # Process "change" entities
        changes = event.get('change', [])
        if not isinstance(changes, list):
            changes = [changes]
        for change in changes:
            if not change:
                continue
            # Add change entity node if not already added
            if change not in entity_nodes:
                if str(change).startswith('LOT_'):
                    fillcolor = '#9ECAE1'  # Light blue
                    shape = 'ellipse'
                elif str(change).startswith('CAD_'):
                    fillcolor = '#FDAE6B'  # Light orange
                    shape = 'ellipse'
                else:
                    fillcolor = '#FFFFFF'  # White
                    shape = 'ellipse'
                G.add_node(
                    change,
                    shape=shape,
                    style='filled',
                    fillcolor=fillcolor,
                    label=change,
                    fontsize='10',
                    fontname='Helvetica'
                )
                entity_nodes[change] = change
                # No direct connection from change entities to event as per your instructions
            
            # Link "sujet" entities to "change" entities
            for sujet in sujets:
                if not sujet:
                    continue
                G.add_edge(sujet, change)
        
    # Add predecessor edges between events
    for event in event_list:
        event_id = event.get('id', '')
        event_node_name = event_nodes.get(event_id)
        if not event_node_name:
            continue
        predecessors = event.get('predecessor_ids', [])
        if not predecessors:
            continue
        for pred_id in predecessors:
            pred_node_name = event_nodes.get(pred_id)
            if pred_node_name:
                G.add_edge(pred_node_name, event_node_name)
            else:
                print(f"Warning: Predecessor event ID {pred_id} not found for event ID {event_id}")
    
    # Create the AGraph from NetworkX graph
    A = to_agraph(G)
    
    # Update graph attributes for better layout and appearance
    A.graph_attr.update(
        rankdir='LR',
        size='12,8',
        dpi='100',
        splines='true',
        nodesep='0.5',
        ranksep='1.0',
        bgcolor='white'
    )
    A.node_attr.update(fontsize='10', fontname='Helvetica')
    A.edge_attr.update(arrowsize='0.7')
    
    # Add a legend to the graph
    add_legend(A)
    
    # Layout the graph using Graphviz's 'dot' layout
    A.layout('dot')
    
    # Use a temporary file to store the PDF
    with tempfile.NamedTemporaryFile(suffix='.pdf') as tmpfile:
        A.draw(tmpfile.name, format='pdf')
        
        # Read the PDF content and encode it in Base64
        with open(tmpfile.name, 'rb') as pdf_file:
            pdf_data = pdf_file.read()
            base64_pdf = base64.b64encode(pdf_data).decode('utf-8')
    
    print("Diagram generated and encoded in Base64.")
    
    return base64_pdf

def add_legend(A):
    """
    Adds a legend to the graph A.
    """
    legend_items = [
        ('Event Node (Lot)', '#A1D99B'),
        ('Event Node (Cadastre)', '#FC9272'),
        ('Sujet Entity (Lot)', '#9ECAE1'),
        ('Sujet Entity (Cadastre)', '#FDAE6B'),
    ]
    
    # Create a subgraph for the legend
    c = A.add_subgraph(name='cluster_legend')
    c.graph_attr.update(label='Legend', fontsize='12', style='rounded,filled', color='grey', fontname='Helvetica')
    c.node_attr.update(shape='box', style='filled', fontname='Helvetica', fontsize='10')
    c.edge_attr.update(style='invis')
    
    # Add legend nodes
    for idx, (label, color) in enumerate(legend_items):
        node_id = f"legend_node_{idx}"
        c.add_node(node_id, label=' ', fillcolor=color)
        label_node_id = f"legend_label_{idx}"
        c.add_node(label_node_id, label=label, shape='plaintext', fontsize='10', fontname='Helvetica')
        c.add_edge(node_id, label_node_id, style='invis')
        
    # Arrange legend items vertically
    for idx in range(len(legend_items) - 1):
        c.add_edge(f"legend_node_{idx}", f"legend_node_{idx+1}", style='invis', weight='10')

 But you forgot that all text in the end result should be in french. And your code give no color to VOL_... for exemple with this input list : [
        {
            "id": -14,
            "change": [],
            "sujet": [],
            "type_event": [],
            "commune": "LYON 7EME",
            "initial_cadastre": "CD243,CD244",
            "initial_volume": "",
            "initial_lot": "0",
            "successors_id": [],
            "predecessor_ids": [
                1
            ],
            "date_event": "-"
        },
        {
            "id": 1,
            "change": [
                "VOL_0"
            ],
            "sujet": [
                "VOL_1",
                "VOL_2",
                "VOL_3"
            ],
            "type_event": "lot",
            "commune": "LYON 7EME",
            "initial_cadastre": "CD 243 à 244",
            "initial_volume": "1 à 3",
            "initial_lot": "",
            "successors_id": [
                -14
            ],
            "predecessor_ids": [
                2
            ],
            "date_event": "24/07/2009"
        },
        {
            "id": 2,
            "change": [
                "LOT_1",
                "LOT_2"
            ],
            "sujet": [
                "LOT_10"
            ],
            "type_event": "lot",
            "commune": "LYON 7EME",
            "initial_cadastre": "CD 243 à 244",
            "initial_volume": "",
            "initial_lot": "10",
            "successors_id": [
                1
            ],
            "predecessor_ids": [
                3
            ],
            "date_event": "15/05/2005"
        },
        {
            "id": 3,
            "change": [
                "CAD_CD243",
                "CAD_CD244"
            ],
            "sujet": [
                "CAD_CD33"
            ],
            "type_event": "cadastre",
            "commune": "LYON 7EME",
            "initial_cadastre": "CD 33",
            "initial_volume": "",
            "initial_lot": "",
            "successors_id": [
                2
            ],
            "predecessor_ids": [
                4
            ],
            "date_event": "10/02/2000"
        },
        {
            "id": 4,
            "change": [
                "CAD_CD33"
            ],
            "sujet": [],
            "type_event": "cadastre",
            "commune": "LYON 7EME",
            "initial_cadastre": "",
            "initial_volume": "",
            "initial_lot": "",
            "successors_id": [
                3
            ],
            "predecessor_ids": [],
            "date_event": "01/01/1995"
        }
    ]

VOL_ has no color. You code should be robust and capable of taking any length of input list, small or very large. The legend color should appear it doesn appear, i just see white cercle with english text for the legend. 

Produce a robust code that ouput the professional diagramme for the notary a base_64 pdf. Take your time to make something perfect