MATLAB Onramp Progress after Session 3 Modules 1–9 of 12  (75%)
🔁

Sessions 1 & 2 Recap

Session 1 — Variables
Store single values. Arithmetic on named variables. Workspace panel.
Session 2 — Vectors
Ordered lists. Colon op & linspace(). 1-based indexing. Element-wise ops.
Session 3 — Today
Turning data into graphs. plot(), labels, multi-line figures, find().
The Gap
After Session 2 you had a drive cycle stored as a vector — [0, 20, 40, 60, 60, 80, ...]. Looking at a list of numbers is not the most natural way to understand what happened. A plot of speed vs time shows acceleration, cruising, and braking phases at a glance. Session 3 bridges calculation and communication.
📢

Why Visualisation is a Core Engineering Skill

Numbers in the Command Window tell you what happened. A graph shows you why it matters. Engineers communicate findings and make decisions with graphs, not with raw tables of values.

Diagram — where plotting fits in the engineering workflow
flowchart LR A["Sensor /\nSimulation\nData"]:::data B["Store in\nVariables &\nVectors\nSessions 1–2"]:::store C["Calculate\n& Process\nSessions 1–2"]:::calc D["Visualise\n& Interpret\nSession 3"]:::vis E["Communicate\n& Decide"]:::decide A --> B --> C --> D --> E classDef data fill:#E0F2FE,stroke:#0284C7,color:#0369A1,font-weight:bold classDef store fill:#E0F2FE,stroke:#0284C7,color:#0369A1 classDef calc fill:#E0F2FE,stroke:#0284C7,color:#0369A1 classDef vis fill:#FEF3C7,stroke:#D97706,color:#92400E,font-weight:bold,font-size:15px classDef decide fill:#D1FAE5,stroke:#059669,color:#065F46,font-weight:bold

In EV Engineering

  • Battery engineers plot SoC vs time to detect cell degradation
  • Controls engineers plot speed error vs time to tune a motor controller
  • Range engineers overlay measured vs predicted SoC to validate models
  • Thermal engineers plot temperature vs time to verify cooling performance

Common EV Plot Types

  • Speed vs time — drive cycle profile
  • SoC vs time — discharge and charge curves
  • Torque vs speed — motor operating envelope
  • Voltage vs SoC — open-circuit voltage (OCV) curve
  • Temperature vs time — thermal management
🔬

Anatomy of an Engineering Plot

A complete engineering plot has six elements. All six are required. A plot missing any of them is an incomplete engineering document.

① Battery SoC During Drive
② SoC (%) ③ Time (s)
50% 100 50 0 1 5 10
Line style = 'b-o' (blue, solid, circles) Dashed red = threshold reference line ylim([0 100]) fixes the y-axis to 0–100%
#ElementMATLAB CommandRule
Titletitle('...')Describe what the plot shows — not just "Plot 1"
Y-axis labelylabel('...')Always include the quantity and unit, e.g. ylabel('SoC (%)')
X-axis labelxlabel('...')Same rule — quantity and unit, e.g. xlabel('Time (s)')
Line styleformat string 'b-o'Choose deliberately — especially when comparing two series
Legendlegend('...')Required whenever there are two or more lines on the same figure
Axis limitsylim([0 100])Set scale deliberately — SoC should always span 0–100%
The Rule
A plot without axis labels and units is an incomplete engineering document. Treat it the same way you would treat a calculation without units — it is not finished. This standard applies at every level of the industry.
⌨️

Core Plotting Commands

Diagram — plotting command sequence
flowchart TD A["plot(t, soc, 'b-o')"]:::cmd B["xlabel('Time (s)')"]:::label C["ylabel('SoC (%)')"]:::label D["title('Battery SoC...')"]:::label E["grid on"]:::optional F["ylim([0 100])"]:::optional G["Figure is complete ✓"]:::done A --> B --> C --> D --> E --> F --> G classDef cmd fill:#FEF3C7,stroke:#D97706,color:#92400E,font-weight:bold classDef label fill:#E0F2FE,stroke:#0284C7,color:#0369A1,font-weight:bold classDef optional fill:#EDE9FE,stroke:#7C3AED,color:#5B21B6 classDef done fill:#D1FAE5,stroke:#059669,color:#065F46,font-weight:bold
% Minimum complete plot — try this in Onramp t = 1:10; soc = [100, 97, 93, 88, 82, 75, 67, 58, 48, 37]; plot(t, soc, 'b-o') % blue line, solid, circle markers xlabel('Time (s)') % x-axis: quantity + unit ylabel('State of Charge (%)') % y-axis: quantity + unit title('Battery SoC Discharge') % descriptive title grid on % add gridlines ylim([0 100]) % fix scale to 0–100%
CommandPurposeNotes
plot(x, y)Basic line plotx and y must have the same number of elements
xlabel('...')Label the x-axisAlways include units in brackets: 'Time (s)'
ylabel('...')Label the y-axisSame rule: 'SoC (%)', 'Speed (km/h)'
title('...')Add a plot titleShould describe what the plot shows, not just the variable name
grid onAdd gridlinesMakes reading values off the graph much easier
ylim([min max])Set y-axis rangeUse ylim([0 100]) for SoC so scale is always consistent
xlim([min max])Set x-axis rangeUseful when zooming into a specific time window
find(v < x)Locate threshold crossingsReturns indices where the condition is true
find()
find() is not strictly a plotting command, but it works alongside plots. After you see a threshold crossing in a graph, use find(soc < 50) to locate the exact index where it happens. It returns the indices (positions) in the vector where the condition is true — not the values themselves.
🎨

Format Strings

A format string is a short text argument passed to plot() that controls the appearance of a line in one compact expression. The string can contain a colour code, a line style, and a marker — in any order.

Syntax
plot(x, y, 'ColourLineMarker') — for example 'r--s' means red, dashed line, square markers. All three parts are optional — you can use one, two, or all three. No spaces inside the string.
Colour
bblue
rred
ggreen
kblack
mmagenta
ccyan
Line Style
-solid
--dashed
:dotted
-.dash-dot
(none)no line — markers only
Marker
ocircle
ssquare
^triangle (up)
xcross
+plus
*asterisk
% Format string examples plot(t, soc, 'b-o') % blue, solid line, circle markers plot(t, soc2, 'r--s') % red, dashed line, square markers plot(t, soc3, 'k:') % black, dotted line, no markers plot(t, soc, 'b-o', 'LineWidth', 2) % add LineWidth for thicker lines
No Spaces
Format strings have no spaces. 'r--s' is correct. 'r -- s' will error. The three parts (colour, line, marker) are written together as a single string.
📈

Multiple Lines & Legends

To plot two or more data series on the same figure, you need hold on. Without it, each new plot() call replaces the previous figure.

Diagram — hold on workflow for a comparison plot
flowchart TD A["plot(t, soc1, 'b-o')"]:::first B["Add labels:\nxlabel / ylabel / title / grid"]:::labels C["hold on"]:::holdon D["plot(t, soc2, 'r--s')"]:::second E["legend('Normal Load', 'Heavy Load')"]:::leg F["Both lines visible\non one figure ✓"]:::done A --> B --> C --> D --> E --> F WRONG["❌ Without hold on:\nplot(t, soc2) replaces\nthe first line entirely"]:::bad C -.->|"if you skip hold on"| WRONG classDef first fill:#E0F2FE,stroke:#0284C7,color:#0369A1,font-weight:bold classDef labels fill:#EDE9FE,stroke:#7C3AED,color:#5B21B6 classDef holdon fill:#FEF3C7,stroke:#D97706,color:#92400E,font-weight:bold,font-size:15px classDef second fill:#FEE2E2,stroke:#DC2626,color:#991B1B,font-weight:bold classDef leg fill:#D1FAE5,stroke:#059669,color:#065F46,font-weight:bold classDef done fill:#D1FAE5,stroke:#059669,color:#065F46,font-weight:bold classDef bad fill:#FEE2E2,stroke:#DC2626,color:#991B1B,font-style:italic
% Comparing two SoC curves on one figure t = 0:1:9; soc1 = [100, 97, 93, 88, 82, 75, 67, 58, 48, 37]; % normal load soc2 = [100, 94, 87, 79, 70, 60, 49, 37, 24, 10]; % heavy load plot(t, soc1, 'b-o') % first line xlabel('Time (s)') ylabel('State of Charge (%)') title('SoC Comparison: Normal vs Heavy Load') grid on ylim([0 100]) hold on % ← keep first line, add to same figure plot(t, soc2, 'r--s') % second line legend('Normal Load', 'Heavy Load') % label both series
Order Matters
hold on must appear between the two plot() calls — not before both or after both. The sequence is always: first plot → hold on → second plot. legend() must come after all plot() calls and labels its series in the order they were plotted.
EV Insight
Overlaying a normal-load and heavy-load SoC curve on one figure immediately shows how much faster the battery depletes under high demand. The gap between the two lines at any given time represents the energy cost of additional load — a key input for EV thermal and range management decisions.
🔧

Block D — EV Task

Block D ⏱ 15 min Plot a SoC Discharge Curve

Open your Onramp Command Window and complete the three steps below.

1
Define the data

Create a time vector t with values 1 through 10 using the colon operator. Then create a SoC vector with the values [100, 97, 93, 88, 82, 75, 67, 58, 48, 37] in percent. These represent a battery discharging over 10 seconds of a drive test.

2
Plot with full formatting

Produce a complete, labelled plot of SoC vs time. Your plot must include all six elements from the Anatomy section: a line with a format string, x-axis label with unit, y-axis label with unit, a descriptive title, gridlines, and a y-axis limit fixed to 0–100%.

Also apply 'LineWidth', 2 as a name-value pair after the format string to make the line slightly thicker.

Before moving to Step 3, ask yourself: is this plot something you could hand to another engineer and they would understand it without any further explanation?

3
Observe and reflect

Look at the shape of the curve and use indexing tools to answer the questions below. For Q2, use MATLAB in Onramp to find the answer rather than reading it off the graph.

Q1 — Is the discharge rate linear or nonlinear? Look at the spacing between data points. What does the shape of the curve tell you about how the battery discharges?
Hint: if it were linear, the SoC would drop by the same amount each second. Is that the case here?
Q2 — At what second does SoC first drop below 50%? Use find() to locate the answer programmatically — do not read it off the graph.
Hint: find() returns the indices where a condition is true. What condition do you need?
Q3 — What would change about this plot if the battery were a higher capacity pack (say 100 kWh instead of 75 kWh) undergoing the same drive test? Would the curve shape change, or the axis, or something else?
Hint: think about what the SoC values represent — percentage of total capacity, not absolute energy
Q4 — How would you add a horizontal dashed reference line at SoC = 20% (the low-battery warning threshold) to your existing plot? Think through the MATLAB commands you would need.
Hint: you need hold on, a new plot() call, and you already know the format string for a dashed line
Note
The steps give you the structure. The commands, observations, and reasoning are yours to work through. If a step is unclear, reread the relevant section above before asking for help.

Troubleshooting — if something goes wrong

❌ Second plot() replaces the first line
Cause: hold on was not used, or was placed after both plot() calls
Fix: The sequence must be: first plot()hold on → second plot(). Rerun in that order.
❌ Two separate figure windows instead of one
Cause: hold on was missing entirely — each plot() opened a new figure
Fix: Close extra windows, then rerun the full sequence with hold on between the two plot() calls.
⚠️ Format string error
Cause: Spaces inside the format string — e.g. 'r -- s' instead of 'r--s'
Fix: Format strings have no spaces. Write all parts together: 'r--s'.
⚠️ Axis labels have no units
Cause: Label written as xlabel('Time') without the unit
Fix: Always include unit in brackets: xlabel('Time (s)'), ylabel('SoC (%)').
⚠️ legend() shows wrong labels
Cause: legend() called before the second plot(), or labels listed in wrong order
Fix: legend() must come after all plot() calls. It labels series in the order they were plotted.
🔍 find() returns an empty result
Cause: The condition is never true in the data — e.g. all SoC values are above 50
Fix: Check your data and your condition. find(soc < 50) will return nothing if all values are ≥ 50. Adjust the threshold or confirm the vector values.
🔍 Figure window not visible
Cause: Window opened behind the browser
Fix: Check your taskbar or use the Onramp interface panel — in Onramp the figure typically appears in a dedicated panel within the browser window.

Key Takeaways

📈 plot(x, y) creates a line graph — the most-used visualisation command in engineering
🏷️ xlabel, ylabel, and title are not optional — an unlabelled plot is an incomplete engineering document
🔒 hold on keeps the current figure active so you can overlay multiple data series — position it between your two plot() calls
🗂️ legend() identifies each data series — required whenever two or more lines share a figure
🎨 Format strings like 'r--o' control colour, line style, and markers in a single argument — no spaces
🔍 find() locates the indices where a condition is true — used for threshold crossings, anomaly detection, and event logging
📏 ylim([0 100]) fixes the y-axis scale — always set this for SoC plots so comparisons across tests are fair

Before Session 4 — think about this

You can now store data, process it, and visualise it. But every time you want to run the same analysis you have to retype all the commands. And your graph is produced once — you cannot tell MATLAB to decide what to display based on the data values.

What would it look like to write MATLAB code that makes decisions — for example, displaying a warning message when SoC drops below 20%? How would you structure that logic? — Session 4 answers this, and also completes the MATLAB Onramp certificate.

Session 4 →