diff --git a/src/mavlink.rs b/src/mavlink.rs
index b0ce8e5e326e13b35d99981cab3b614be3bc6206..20ceffeb00839bf9b0d3ef0c354d983aee90170d 100644
--- a/src/mavlink.rs
+++ b/src/mavlink.rs
@@ -153,12 +153,15 @@ impl ReflectionContext {
         self.id_name_map.get(&message_id).map(|s| s.as_str())
     }
 
-    pub fn messages(&self) -> Vec<&str> {
-        self.mavlink_profile
+    pub fn sorted_messages(&self) -> Vec<&str> {
+        let mut msgs: Vec<&str> = self
+            .mavlink_profile
             .messages
             .keys()
             .map(|s| s.as_str())
-            .collect()
+            .collect();
+        msgs.sort();
+        msgs
     }
 
     pub fn get_fields_by_id(&self, message_id: u32) -> Vec<&str> {
diff --git a/src/ui/panes/plot_2d.rs b/src/ui/panes/plot_2d.rs
index 40cd5d8d9eddf5dd5c9def4b81534e7723a865c4..bcba91be186452658e408e19b5f1800e8d7abda0 100644
--- a/src/ui/panes/plot_2d.rs
+++ b/src/ui/panes/plot_2d.rs
@@ -2,8 +2,8 @@ use crate::{ui::composable_view::PaneResponse, MAVLINK_PROFILE, MSG_MANAGER};
 
 use super::PaneBehavior;
 
-use egui::Color32;
-use egui_plot::{Line, PlotPoints};
+use egui::{Color32, Vec2b};
+use egui_plot::{Legend, Line, PlotPoints};
 use serde::{Deserialize, Serialize};
 use skyward_mavlink::{
     lyra::{MavMessage, ROCKET_FLIGHT_TM_DATA},
@@ -12,7 +12,7 @@ use skyward_mavlink::{
 
 #[derive(Clone, Debug, Serialize, Deserialize)]
 struct PlotLineSettings {
-    field_y: String,
+    field: String,
     width: f32,
     color: Color32,
 }
@@ -20,7 +20,7 @@ struct PlotLineSettings {
 impl Default for PlotLineSettings {
     fn default() -> Self {
         Self {
-            field_y: "".to_owned(),
+            field: "".to_owned(),
             width: 1.0,
             color: Color32::BLUE,
         }
@@ -30,7 +30,7 @@ impl Default for PlotLineSettings {
 impl PlotLineSettings {
     fn new(field_y: String) -> Self {
         Self {
-            field_y,
+            field: field_y,
             ..Default::default()
         }
     }
@@ -68,26 +68,34 @@ impl PaneBehavior for Plot2DPane {
     fn ui(&mut self, ui: &mut egui::Ui) -> PaneResponse {
         let mut response = PaneResponse::default();
 
+        let Self {
+            settings_visible,
+            sources_visible,
+            plot_lines,
+            msg_id,
+            field_x,
+            plot_active,
+            ..
+        } = self;
+
         // Spawn windows
-        let mut settings_window_visible = self.settings_visible;
         egui::Window::new("Plot Settings")
             .id(ui.make_persistent_id("plot_settings"))
             .auto_sized()
             .collapsible(true)
             .movable(true)
-            .open(&mut settings_window_visible)
-            .show(ui.ctx(), |ui| self.settings_window(ui));
-        self.settings_visible = settings_window_visible;
+            .open(settings_visible)
+            .show(ui.ctx(), |ui| settings_window(ui, plot_lines));
 
-        let mut sources_window_visible = self.sources_visible;
         egui::Window::new("Plot Sources")
             .id(ui.make_persistent_id("plot_sources"))
             .auto_sized()
             .collapsible(true)
             .movable(true)
-            .open(&mut sources_window_visible)
-            .show(ui.ctx(), |ui| self.sources_window(ui));
-        self.sources_visible = sources_window_visible;
+            .open(sources_visible)
+            .show(ui.ctx(), |ui| {
+                sources_window(ui, msg_id, field_x, plot_lines, plot_active)
+            });
 
         let ctrl_pressed = ui.input(|i| i.modifiers.ctrl);
 
@@ -108,7 +116,7 @@ impl PaneBehavior for Plot2DPane {
                             let x = serde_json::from_value::<f64>(x.clone()).unwrap();
                             let mut ys = Vec::new();
                             for field in self.plot_lines.iter() {
-                                let y = value.get(field.field_y.as_str()).unwrap();
+                                let y = value.get(field.field.as_str()).unwrap();
                                 ys.push(serde_json::from_value::<f64>(y.clone()).unwrap());
                             }
                             (x, ys)
@@ -128,7 +136,9 @@ impl PaneBehavior for Plot2DPane {
             }
         }
 
-        let plot = egui_plot::Plot::new("plot").auto_bounds([true, true].into());
+        let plot = egui_plot::Plot::new("plot")
+            .auto_bounds(Vec2b::TRUE)
+            .legend(Legend::default());
         plot.show(ui, |plot_ui| {
             self.contains_pointer = plot_ui.response().contains_pointer();
             if plot_ui.response().dragged() && ctrl_pressed {
@@ -142,7 +152,9 @@ impl PaneBehavior for Plot2DPane {
                         .width(plot_settings.width),
                 );
             }
-            plot_ui.response().context_menu(|ui| self.menu(ui));
+            plot_ui
+                .response()
+                .context_menu(|ui| show_menu(ui, settings_visible, sources_visible));
         });
 
         response
@@ -153,143 +165,148 @@ impl PaneBehavior for Plot2DPane {
     }
 }
 
-impl Plot2DPane {
-    fn menu(&mut self, ui: &mut egui::Ui) {
-        ui.set_max_width(200.0); // To make sure we wrap long text
+fn settings_window(ui: &mut egui::Ui, plot_lines: &mut [PlotLineSettings]) {
+    egui::Grid::new(ui.id())
+        .num_columns(4)
+        .spacing([10.0, 5.0])
+        .show(ui, |ui| {
+            for plot_line in plot_lines.iter_mut() {
+                ui.label(&plot_line.field);
+                ui.color_edit_button_srgba(&mut plot_line.color);
+                ui.add(
+                    egui::DragValue::new(&mut plot_line.width)
+                        .speed(0.1)
+                        .suffix(" pt"),
+                )
+                .on_hover_text("Width of the line in points");
+                ui.end_row();
+            }
+        });
+}
 
-        if ui.button("Settings…").clicked() {
-            self.settings_visible = true;
-            ui.close_menu();
-        }
+fn sources_window(
+    ui: &mut egui::Ui,
+    msg_id: &mut u32,
+    field_x: &mut String,
+    plot_lines: &mut Vec<PlotLineSettings>,
+    plot_active: &mut bool,
+) {
+    // record msg id to check if it has changed
+    let old_msg_id = *msg_id;
+    // extract the msg name from the id to show it in the combo box
+    let msg_name = MAVLINK_PROFILE
+        .get_name_from_id(*msg_id)
+        .unwrap_or_default();
 
-        if ui.button("Sources…").clicked() {
-            self.sources_visible = true;
-            ui.close_menu();
-        }
-    }
+    // show the first combo box with the message name selection
+    egui::ComboBox::from_label("Message Kind")
+        .selected_text(msg_name)
+        .show_ui(ui, |ui| {
+            for msg in MAVLINK_PROFILE.sorted_messages() {
+                ui.selectable_value(msg_id, MavMessage::message_id_from_name(msg).unwrap(), msg);
+            }
+        });
 
-    fn settings_window(&mut self, ui: &mut egui::Ui) {
-        egui::Grid::new(ui.id())
-            .num_columns(4)
-            .spacing([10.0, 5.0])
-            .show(ui, |ui| {
-                for plot_line in self.plot_lines.iter_mut() {
-                    ui.label(&plot_line.field_y);
-                    ui.color_edit_button_srgba(&mut plot_line.color);
-                    ui.label("Width:");
-                    ui.add(egui::Slider::new(&mut plot_line.width, 0.1..=10.0).text("pt"));
-                    ui.end_row();
-                }
-            });
+    // reset fields if the message is changed
+    if *msg_id != old_msg_id {
+        plot_lines.truncate(1);
     }
 
-    fn sources_window(&mut self, ui: &mut egui::Ui) {
-        let old_msg_id = self.msg_id;
-        let msg_name = MAVLINK_PROFILE
-            .get_name_from_id(self.msg_id)
-            .unwrap_or_default();
-        egui::ComboBox::from_label("Message Kind")
-            .selected_text(msg_name)
-            .show_ui(ui, |ui| {
-                for msg in MAVLINK_PROFILE.messages() {
-                    ui.selectable_value(
-                        &mut self.msg_id,
-                        MavMessage::message_id_from_name(msg).unwrap(),
-                        msg,
-                    );
-                }
-            });
+    // check fields and assing a default field_x and field_y once the msg is changed
+    let fields = MAVLINK_PROFILE.get_plottable_fields_by_id(*msg_id);
+    // get the first field that is in the list of fields or the previous if valid
+    let new_field_x = fields
+        .contains(&field_x.as_str())
+        .then(|| field_x.to_owned())
+        .or(fields.first().map(|s| s.to_string()));
 
-        // reset fields if the message is changed
-        if self.msg_id != old_msg_id {
-            self.plot_lines.truncate(1);
-        }
+    // if there are no fields, reset the field_x and plot_lines
+    let Some(new_field_x) = new_field_x else {
+        *field_x = "".to_owned();
+        plot_lines.clear();
+        *plot_active = false;
+        return;
+    };
+    // update the field_x
+    *field_x = new_field_x;
 
-        // check fields and assing a default field_x and field_y once the msg is changed
-        let fields = MAVLINK_PROFILE.get_plottable_fields_by_id(self.msg_id);
-        // get the first field that is in the list of fields or the previous if valid
-        let mut field_x = fields
-            .contains(&self.field_x.as_str())
-            .then(|| self.field_x.clone())
-            .or(fields.first().map(|s| s.to_string()));
-        // get the second field that is in the list of fields or the previous if valid
-        let mut field_y = self
-            .plot_lines
-            .first()
-            .and_then(|s| {
-                fields
-                    .contains(&s.field_y.as_str())
-                    .then_some(s.field_y.to_owned())
-            })
-            .or(fields.get(1).map(|s| s.to_string()));
-
-        // if fields are valid, show the combo boxes for the x_axis
-        if field_x.is_some() {
-            let field_x = field_x.as_mut().unwrap();
-            egui::ComboBox::from_label("X Axis")
-                .selected_text(field_x.as_str())
-                .show_ui(ui, |ui| {
-                    for msg in fields.iter() {
-                        ui.selectable_value(field_x, (*msg).to_owned(), *msg);
-                    }
-                });
-        }
-        // if fields are more than 1, show the combo boxes for the y_axis
-        if field_y.is_some() {
-            let field_y = field_y.as_mut().unwrap();
-            let widget_label = if self.plot_lines.len() > 1 {
-                "Y Axis 1"
-            } else {
-                "Y Axis"
-            };
-            egui::ComboBox::from_label(widget_label)
-                .selected_text(field_y.as_str())
-                .show_ui(ui, |ui| {
-                    for msg in fields.iter() {
-                        ui.selectable_value(field_y, (*msg).to_owned(), *msg);
-                    }
-                });
-        }
-        // check how many fields are left and how many are selected
-        let fields_selected = self.plot_lines.len() + 1;
-        let fields_left_to_draw = fields.len().saturating_sub(2);
-        for i in 0..fields_left_to_draw.min(fields_selected.saturating_sub(2)) {
-            let field = &mut self.plot_lines.get_mut(1 + i).unwrap().field_y;
-            let widget_label = format!("Y Axis {}", i + 2);
-            egui::ComboBox::from_label(widget_label)
-                .selected_text(field.as_str())
-                .show_ui(ui, |ui| {
-                    for msg in fields.iter() {
-                        ui.selectable_value(field, (*msg).to_owned(), *msg);
-                    }
-                });
-            self.plot_lines[1 + i].field_y = field.clone();
-        }
+    // if fields are valid, show the combo boxes for the x_axis
+    egui::ComboBox::from_label("X Axis")
+        .selected_text(field_x.as_str())
+        .show_ui(ui, |ui| {
+            for msg in fields.iter() {
+                ui.selectable_value(field_x, (*msg).to_owned(), *msg);
+            }
+        });
 
-        // if we have fields left, show the add button
-        let fields_left_to_draw = fields.len().saturating_sub(fields_selected);
-        if fields_left_to_draw > 0
-            && ui
-                .button("Add Y Axis")
-                .on_hover_text("Add another Y axis")
-                .clicked()
-        {
-            self.plot_lines
-                .push(PlotLineSettings::new(fields[fields_selected].to_string()));
-        }
+    // populate the plot_lines with the first field if it is empty and there are more than 1 fields
+    if plot_lines.is_empty() && fields.len() > 1 {
+        plot_lines.push(PlotLineSettings::new(fields[1].to_string()));
+    }
 
-        // update fields and flag for active plot
-        self.field_x = field_x.unwrap_or_default();
-        if field_y.is_some() {
-            if self.plot_lines.first().is_none() {
-                self.plot_lines
-                    .push(PlotLineSettings::new(field_y.unwrap()));
-            } else {
-                self.plot_lines[0].field_y = field_y.unwrap();
+    // check how many fields are left and how many are selected
+    // let fields_selected = plot_lines.len() + 1;
+    // let fields_left_to_draw = fields.len().saturating_sub(2);
+    // fields_left_to_draw.min(fields_selected.saturating_sub(2)) {
+    let plot_lines_len = plot_lines.len();
+    egui::Grid::new(ui.auto_id_with("y_axis"))
+        .num_columns(3)
+        .spacing([10.0, 5.0])
+        .show(ui, |ui| {
+            for (i, line_settings) in plot_lines.iter_mut().enumerate() {
+                // let line_settings = &mut plot_lines.get_mut(1 + i).unwrap();
+                let PlotLineSettings {
+                    field,
+                    width,
+                    color,
+                } = line_settings;
+                let widget_label = if plot_lines_len > 1 {
+                    format!("Y Axis {}", i + 1)
+                } else {
+                    "Y Axis".to_owned()
+                };
+                egui::ComboBox::from_label(widget_label)
+                    .selected_text(field.as_str())
+                    .show_ui(ui, |ui| {
+                        for msg in fields.iter() {
+                            ui.selectable_value(field, (*msg).to_owned(), *msg);
+                        }
+                    });
+                ui.color_edit_button_srgba(color);
+                ui.add(egui::DragValue::new(width).speed(0.1).suffix(" pt"))
+                    .on_hover_text("Width of the line in points");
+                ui.end_row();
             }
-            self.plot_active = true;
-        } else {
-            self.plot_active = false;
-        }
+        });
+
+    // if we have fields left, show the add button
+    if fields.len().saturating_sub(plot_lines_len + 1) > 0
+        && ui
+            .button("Add Y Axis")
+            .on_hover_text("Add another Y axis")
+            .clicked()
+    {
+        let next_field = fields
+            .iter()
+            .find(|f| !plot_lines.iter().any(|l| l.field == **f))
+            .unwrap();
+        plot_lines.push(PlotLineSettings::new(next_field.to_string()));
+    }
+
+    // update fields and flag for active plot
+    *plot_active = !plot_lines.is_empty();
+}
+
+fn show_menu(ui: &mut egui::Ui, settings_visible: &mut bool, sources_visible: &mut bool) {
+    ui.set_max_width(200.0); // To make sure we wrap long text
+
+    if ui.button("Settings…").clicked() {
+        *settings_visible = true;
+        ui.close_menu();
+    }
+
+    if ui.button("Sources…").clicked() {
+        *sources_visible = true;
+        ui.close_menu();
     }
 }