CityLearn UI

CityLearn UI is a visual dashboard for exploring simulation data generated by the CityLearn framework. It was developed to simplify the analysis of results from smart energy communities, district energy coordination, demand response (among other applications), allowing users to visually inspect building-level components, compare simulation KPIs, and create simulation schemas with ease.

The interface is available in two options:

You can check a tutorial at the official CityLearn website, in the CityLearn UI repository README, or at the help tooltip of the official webapp.

Compatibility: This version of the UI currently supports CityLearn v2.5.0 simulation data.

Developed by: José, a member of the SoftCPS, Software for Cyber-Physical Systems research group (ISEP, Portugal) in collaboration with the Intelligent Environments Lab, University of Texas at Austin.

Exporting Data From CityLearn into CityLearn UI

CityLearn automatically exports the folder structure expected by the UI. The behaviour depends on citylearn.citylearn.CityLearnEnv render_mode:

  • render_mode='none' (default): no CSVs are produced. Use this for fast headless runs where you do not need UI data, or call citylearn.citylearn.CityLearnEnv.export_final_kpis() manually afterwards to obtain the KPI table only.

  • render_mode='during': the environment writes a row for every simulation step directly to disk (<project>/SimulationData/<timestamp> by default). Final KPIs are appended automatically once the episode ends—no extra script code is required.

  • render_mode='end': per-step rows are buffered in memory and flushed to disk when the episode finishes (or whenever render() is invoked). As with 'during', the KPI export is triggered automatically at the end of the episode.

You can customise the export location with render_directory, render_directory_name and/or render_session_name when constructing the environment. When a session name is provided the folder is reused across runs; otherwise a timestamped folder is created.

Per-Step Export Example

from pathlib import Path
from citylearn.citylearn import CityLearnEnv

schema = 'data/datasets/citylearn_challenge_2022_phase_all_plus_evs/schema.json'

env = CityLearnEnv(
    schema,
    central_agent=True,
    episode_time_steps=48,
    render_mode='during',
    render_directory=Path('outputs/ui_exports'),  # optional custom base folder
    render_session_name='my_first_run',  # optional custom subfolder
)

observations, _ = env.reset()
while not env.terminated:
    actions = [env.action_space[0].sample()]
    observations, reward, terminated, truncated, info = env.step(actions)
    # CSV rows are appended at each step when render_mode='during'.

The code above writes per-step CSV files into outputs/ui_exports/<timestamp>/. Omitting render_directory stores the results in SimulationData/<timestamp>/ by default, and the episode summary KPIs are written automatically to exported_kpis.csv.

Export-at-the-End Example

from citylearn.citylearn import CityLearnEnv

env = CityLearnEnv(schema, central_agent=True, episode_time_steps=48, render_mode='none')
observations, _ = env.reset()
while not env.terminated:
    actions = [env.action_space[0].sample()]
    observations, reward, terminated, truncated, info = env.step(actions)

class _Model:
    pass

model = _Model()
model.env = env

env.export_final_kpis(model, filepath='exported_kpis.csv')
print('Render folder:', env.new_folder_path)

This pattern keeps rendering off (fastest) and emits only the KPI CSV once the run completes. Because timestep histories are not written, the resulting folder can be used with the KPIs page of the UI but not with the full time-series explorer.

Buffered End-of-Run Export Example

from pathlib import Path
from citylearn.citylearn import CityLearnEnv

schema = 'data/datasets/citylearn_challenge_2022_phase_all_plus_evs/schema.json'

env = CityLearnEnv(
    schema,
    central_agent=True,
    episode_time_steps=48,
    render_mode='end',
    render_directory=Path('outputs/ui_exports'),
    render_session_name='buffered_run',
)

observations, _ = env.reset()
while not env.terminated:
    actions = [env.action_space[0].sample()]
    observations, reward, terminated, truncated, info = env.step(actions)

With render_mode='end' the per-step histories accumulate in memory while the episode runs. At episode completion the environment writes the full SimulationData folder (all timesteps plus components) and the KPI summary; you may still call render() manually if you want to force a flush earlier than that.

The UI consumes the directory produced by the 'during' and 'end' approaches. The system uses the render() method to iterate over buildings, electric vehicles, batteries, chargers, pricing, etc., using their as_dict outputs to build CSV histories where each row corresponds to a time instant and columns include units. Timestamps are converted to calendar dates for display. You can disable step-wise exporting by keeping render_mode='none' and relying on the end-of-run exporter, but the resulting folder will only serve the KPI comparison page.

Pages within CityLearn UI

CityLearn UI has three main pages, described below. All referenced images should be placed under docs/source/_static/ui/ with the indicated filenames.

Dashboard Overview

This landing page lets you upload and explore simulations.

Uploading Simulations

  • Prepare a folder named SimulationData.

  • Inside, add subfolders per simulation.

  • Each simulation folder must contain CSVs named as follows: * Buildings: exported_data_building_X (where X is the building number) * Components: append suffixes such as _battery or _charger_X_Y * Episodes: end filenames with _epZ (episode number Z)

Structure example: SimulationData/MySim/exported_data_building_1_battery_ep3.csv.

Selecting Simulations

After uploading a valid folder, click Select Simulations to choose which runs to visualize. At least one simulation must be selected before confirming.

Selecting simulations

Viewing Simulation Data

Each chosen simulation appears as a tab. Within a tab:

  • The left sidebar lists buildings and their grouped components (Consumption, Production, Other Equipment).

  • Selecting a component displays its chart on the right.

This layout enables quick navigation across building-level data.

Simulation data view

Graphs and Filters

Graphs support multiple filtering controls:

  • Adjust time-step intervals (highlighted in red),

  • Toggle data series via checkboxes (green),

  • Restrict start/end dates using the slider (blue).

KPIs Page Overview

The KPIs page allows uploading folders and selecting simulations for KPI analysis. Once a simulation is active, its KPIs appear in a table (rows = KPIs, columns = buildings).

KPI table view

Comparing Simulations

When multiple simulations are loaded, a Compare button lets you choose a reference run. The comparison tab shows Simulation Y Simulation X deltas.

  • Positive values (improvements) appear in bold green.

  • Negative values (declines) appear in bold red.

  • Zero differences remain black.

KPI comparison view

Create Schema Overview

The Create Schema page guides dataset assembly via three sections.

Step 1: Dataset Information

Displays dataset metadata, period settings, selected observations, and actions.

Dataset information

Step 2: Agent & Reward Configuration

Define agent details, reward functions, and upload JSON configuration files. Uploaded files can be previewed and edited inline.

Agent and reward configuration

Step 3: Schema Structure (Canvas)

Provides a drag-and-drop canvas for constructing schemas:

  • The left panel lists components to add (buildings, equipment, etc.).

  • Drag components onto the canvas and fill in required fields.

  • Link equipment to buildings, rename items, and copy/paste repeating elements.

Schema canvas

This interface streamlines the creation and management of complex simulation schemas.

UI updates and improvements are ongoing. Feedback and contributions are welcome via the CityLearn UI repo

Contributors: José Oliveira and Tiago Fonseca (calof@isep.ipp.pt)