Setup and Installation
PGFPlots requires TikZ and comes with most modern LaTeX distributions. Load it in your preamble:
\documentclass{article}
\usepackage{pgfplots}
\pgfplotsset{compat=1.18} % Use latest version
\begin{document}
\begin{tikzpicture}
\begin{axis}
% Your plot code here
\end{axis}
\end{tikzpicture}
\end{document}
💡 Compatibility Tip: Always set \pgfplotsset{compat=1.18} (or latest version) to enable new features and ensure consistent behavior across LaTeX installations.
Common Package Options
% Load additional libraries
\usepackage{pgfplots}
\usepgfplotslibrary{
fillbetween, % Fill areas between curves
statistics, % Box plots, histograms
polar, % Polar coordinate plots
smithchart, % Smith chart plots
groupplots, % Multiple subplot arrangements
dateplot, % Date/time axis
colorbrewer % ColorBrewer color schemes
}
% Set global defaults
\pgfplotsset{
compat=1.18,
width=10cm,
height=7cm,
grid=major
}
Basic 2D Plots
The foundation of PGFPlots is the axis environment, which creates a coordinate system for plotting data.
Line Plots
\begin{tikzpicture}
\begin{axis}[
title={Simple Line Plot},
xlabel={$x$},
ylabel={$y$},
grid=major
]
% Add plot with coordinates
\addplot coordinates {
(0,0) (1,1) (2,4) (3,9) (4,16) (5,25)
};
\end{axis}
\end{tikzpicture}
Multiple Lines
\begin{tikzpicture}
\begin{axis}[
title={Multiple Functions},
xlabel={$x$},
ylabel={$f(x)$},
legend pos=north west,
grid=major
]
% Linear function
\addplot[blue, thick] coordinates {
(0,0) (1,1) (2,2) (3,3) (4,4) (5,5)
};
\addlegendentry{$y = x$}
% Quadratic function
\addplot[red, thick] coordinates {
(0,0) (1,1) (2,4) (3,9) (4,16) (5,25)
};
\addlegendentry{$y = x^2$}
% Cubic function
\addplot[green, thick] coordinates {
(0,0) (1,1) (2,8) (3,27) (4,64) (5,125)
};
\addlegendentry{$y = x^3$}
\end{axis}
\end{tikzpicture}
Scatter Plots
\begin{tikzpicture}
\begin{axis}[
title={Scatter Plot Example},
xlabel={Variable $X$},
ylabel={Variable $Y$},
grid=major,
only marks, % Show only markers, no lines
]
\addplot[
color=blue,
mark=*,
mark size=2pt
] coordinates {
(1,2.3) (2,4.1) (3,5.8) (4,7.2)
(5,9.5) (6,11.1) (7,12.8) (8,14.3)
};
\end{axis}
\end{tikzpicture}
Scatter with Different Markers
\begin{tikzpicture}
\begin{axis}[
title={Marker Styles},
legend pos=outer north east,
grid=major
]
% Circles
\addplot[only marks, mark=*, color=red]
coordinates {(1,1) (2,2) (3,3)};
\addlegendentry{Circle}
% Squares
\addplot[only marks, mark=square*, color=blue]
coordinates {(1,2) (2,3) (3,4)};
\addlegendentry{Square}
% Triangles
\addplot[only marks, mark=triangle*, color=green]
coordinates {(1,3) (2,4) (3,5)};
\addlegendentry{Triangle}
% Diamonds
\addplot[only marks, mark=diamond*, color=orange]
coordinates {(1,4) (2,5) (3,6)};
\addlegendentry{Diamond}
\end{axis}
\end{tikzpicture}
Function Plots
\begin{tikzpicture}
\begin{axis}[
title={Trigonometric Functions},
xlabel={$x$},
ylabel={$f(x)$},
domain=0:2*pi,
samples=100,
grid=major,
legend pos=south east
]
% Sine function
\addplot[blue, thick] {sin(deg(x))};
\addlegendentry{$\sin(x)$}
% Cosine function
\addplot[red, thick] {cos(deg(x))};
\addlegendentry{$\cos(x)$}
% Tangent function (limited range)
\addplot[green, thick, domain=0.1:1.4] {tan(deg(x))};
\addlegendentry{$\tan(x)$}
\end{axis}
\end{tikzpicture}
Exponential and Logarithmic Functions
\begin{tikzpicture}
\begin{axis}[
title={Exponential and Logarithmic},
xlabel={$x$},
ylabel={$y$},
domain=0.1:3,
samples=50,
grid=major,
legend pos=north west,
ymin=-2, ymax=20
]
% Exponential
\addplot[blue, thick] {exp(x)};
\addlegendentry{$e^x$}
% Natural logarithm
\addplot[red, thick] {ln(x)};
\addlegendentry{$\ln(x)$}
% Power function
\addplot[green, thick] {x^2};
\addlegendentry{$x^2$}
\end{axis}
\end{tikzpicture}
Axis and Grid Customization
Axis Range and Ticks
\begin{tikzpicture}
\begin{axis}[
title={Custom Axis Settings},
xlabel={Time (s)},
ylabel={Voltage (V)},
% Set axis ranges
xmin=0, xmax=10,
ymin=-5, ymax=5,
% Custom tick positions
xtick={0,2,4,6,8,10},
ytick={-5,-2.5,0,2.5,5},
% Grid styling
grid=both,
minor tick num=1,
grid style={line width=.1pt, draw=gray!30},
major grid style={line width=.2pt, draw=gray!50}
]
\addplot[blue, thick, domain=0:10] {3*sin(deg(x))};
\end{axis}
\end{tikzpicture}
Logarithmic Scales
% Semi-log plot (y-axis logarithmic)
\begin{tikzpicture}
\begin{semilogyaxis}[
title={Exponential Growth (Semi-log)},
xlabel={Time},
ylabel={Population},
grid=major
]
\addplot[blue, thick] coordinates {
(0,1) (1,10) (2,100) (3,1000) (4,10000)
};
\end{semilogyaxis}
\end{tikzpicture}
% Log-log plot (both axes logarithmic)
\begin{tikzpicture}
\begin{loglogaxis}[
title={Power Law (Log-log)},
xlabel={$x$},
ylabel={$y$},
grid=major
]
\addplot[red, thick, domain=1:100] {x^2};
\addlegendentry{$y = x^2$}
\end{loglogaxis}
\end{tikzpicture}
Styling Options
\begin{tikzpicture}
\begin{axis}[
title={Line Style Examples},
legend pos=north west
]
% Solid line, thick
\addplot[blue, thick] coordinates {
(0,1) (1,1.5) (2,2) (3,2.5) (4,3)
};
\addlegendentry{Solid thick}
% Dashed line
\addplot[red, dashed, thick] coordinates {
(0,2) (1,2.5) (2,3) (3,3.5) (4,4)
};
\addlegendentry{Dashed}
% Dotted line
\addplot[green, dotted, ultra thick] coordinates {
(0,3) (1,3.5) (2,4) (3,4.5) (4,5)
};
\addlegendentry{Dotted}
% Line with markers
\addplot[black, mark=*, mark options={fill=orange}]
coordinates {
(0,4) (1,4.5) (2,5) (3,5.5) (4,6)
};
\addlegendentry{With markers}
\end{axis}
\end{tikzpicture}
Legends and Labels
Legend Positioning
% Inside plot area
\begin{axis}[legend pos=north east] % or north west, south east, south west
\end{axis}
% Outside plot area
\begin{axis}[
legend pos=outer north east,
legend style={
at={(1.02,1)},
anchor=north west
}
]
\end{axis}
% Custom position (relative coordinates)
\begin{axis}[
legend style={
at={(0.5,0.97)},
anchor=north,
legend columns=3 % Horizontal legend
}
]
\end{axis}
Annotations and Text
\begin{tikzpicture}
\begin{axis}[
xlabel={$x$},
ylabel={$f(x)$}
]
\addplot[blue, thick, domain=0:4] {x^2};
% Add text node
\node[pin=120:{Maximum}] at (axis cs:2,4) {};
% Add arrow with text
\draw[red, ->] (axis cs:1,3)
node[above left] {Interesting point}
-- (axis cs:1.5,2.25);
% Add coordinate label
\node[circle, fill=red, inner sep=2pt]
at (axis cs:3,9) {};
\node[above] at (axis cs:3,9) {$(3,9)$};
\end{axis}
\end{tikzpicture}
Bar Charts and Histograms
Vertical Bar Chart
\begin{tikzpicture}
\begin{axis}[
ybar,
title={Sales by Quarter},
ylabel={Revenue (\$1000)},
xlabel={Quarter},
symbolic x coords={Q1, Q2, Q3, Q4},
xtick=data,
nodes near coords,
nodes near coords align={vertical},
ymin=0
]
\addplot coordinates {
(Q1,45) (Q2,52) (Q3,48) (Q4,63)
};
\end{axis}
\end{tikzpicture}
Grouped Bar Chart
\begin{tikzpicture}
\begin{axis}[
ybar,
bar width=8pt,
title={Product Comparison},
ylabel={Sales},
xlabel={Month},
symbolic x coords={Jan, Feb, Mar, Apr},
xtick=data,
legend pos=north west,
ymin=0
]
\addplot[fill=blue!60] coordinates {
(Jan,20) (Feb,25) (Mar,22) (Apr,30)
};
\addlegendentry{Product A}
\addplot[fill=red!60] coordinates {
(Jan,18) (Feb,28) (Mar,24) (Apr,26)
};
\addlegendentry{Product B}
\addplot[fill=green!60] coordinates {
(Jan,22) (Feb,23) (Mar,26) (Apr,28)
};
\addlegendentry{Product C}
\end{axis}
\end{tikzpicture}
Stacked Bar Chart
\begin{tikzpicture}
\begin{axis}[
ybar stacked,
title={Resource Allocation},
ylabel={Hours},
xlabel={Week},
symbolic x coords={W1, W2, W3, W4},
xtick=data,
legend pos=north west,
ymin=0
]
\addplot[fill=blue!60] coordinates {
(W1,15) (W2,18) (W3,16) (W4,20)
};
\addlegendentry{Development}
\addplot[fill=red!60] coordinates {
(W1,10) (W2,12) (W3,14) (W4,11)
};
\addlegendentry{Testing}
\addplot[fill=green!60] coordinates {
(W1,5) (W2,7) (W3,8) (W4,9)
};
\addlegendentry{Documentation}
\end{axis}
\end{tikzpicture}
Horizontal Bar Chart
\begin{tikzpicture}
\begin{axis}[
xbar,
title={Survey Results},
xlabel={Percentage (\%)},
ylabel={Category},
symbolic y coords={Excellent, Good, Fair, Poor},
ytick=data,
nodes near coords,
nodes near coords align={horizontal},
xmin=0, xmax=100
]
\addplot[fill=blue!60] coordinates {
(45,Excellent) (35,Good) (15,Fair) (5,Poor)
};
\end{axis}
\end{tikzpicture}
Multiple Plots
Subplots with Groupplots
\usepgfplotslibrary{groupplots}
\begin{tikzpicture}
\begin{groupplot}[
group style={
group size=2 by 2,
horizontal sep=2cm,
vertical sep=2cm
},
width=6cm,
height=5cm,
grid=major
]
% Plot 1 (top left)
\nextgroupplot[title={Linear}, ylabel={$y$}]
\addplot[blue] {x};
% Plot 2 (top right)
\nextgroupplot[title={Quadratic}]
\addplot[red] {x^2};
% Plot 3 (bottom left)
\nextgroupplot[title={Exponential}, xlabel={$x$}, ylabel={$y$}]
\addplot[green, domain=0:2] {exp(x)};
% Plot 4 (bottom right)
\nextgroupplot[title={Sine}, xlabel={$x$}]
\addplot[purple, domain=0:6.28] {sin(deg(x))};
\end{groupplot}
\end{tikzpicture}
Secondary Y-Axis
\begin{tikzpicture}
\begin{axis}[
scale only axis,
width=10cm, height=6cm,
xlabel={Time (s)},
ylabel={Temperature ($^\circ$C)},
ylabel style={blue},
ymin=0, ymax=100,
legend pos=north west
]
\addplot[blue, thick] coordinates {
(0,20) (1,35) (2,50) (3,70) (4,85)
};
\addlegendentry{Temperature}
\end{axis}
% Second y-axis
\begin{axis}[
scale only axis,
width=10cm, height=6cm,
xlabel={Time (s)},
ylabel={Pressure (kPa)},
ylabel style={red},
ymin=0, ymax=200,
axis y line*=right,
legend pos=south east
]
\addplot[red, thick, dashed] coordinates {
(0,50) (1,75) (2,110) (3,150) (4,180)
};
\addlegendentry{Pressure}
\end{axis}
\end{tikzpicture}
3D Plots and Surfaces
3D Surface Plot
\begin{tikzpicture}
\begin{axis}[
title={3D Surface: $z = \sin(x) \cdot \cos(y)$},
xlabel={$x$},
ylabel={$y$},
zlabel={$z$},
colormap/viridis,
view={60}{30}
]
\addplot3[
surf,
domain=-3:3,
domain y=-3:3,
samples=30
] {sin(deg(x)) * cos(deg(y))};
\end{axis}
\end{tikzpicture}
3D Mesh Plot
\begin{tikzpicture}
\begin{axis}[
title={Paraboloid: $z = x^2 + y^2$},
xlabel={$x$},
ylabel={$y$},
zlabel={$z$},
colormap/hot,
view={45}{30}
]
\addplot3[
mesh,
domain=-2:2,
domain y=-2:2,
samples=20
] {x^2 + y^2};
\end{axis}
\end{tikzpicture}
Contour Plot
\begin{tikzpicture}
\begin{axis}[
title={Contour Plot},
xlabel={$x$},
ylabel={$y$},
view={0}{90},
colorbar,
colormap/jet
]
\addplot3[
contour gnuplot={levels={-2,-1,0,1,2}},
domain=-2:2,
domain y=-2:2,
samples=40
] {x^2 - y^2};
\end{axis}
\end{tikzpicture}
Parametric 3D Curve
\begin{tikzpicture}
\begin{axis}[
title={Helix},
xlabel={$x$},
ylabel={$y$},
zlabel={$z$},
view={60}{30}
]
\addplot3[
blue,
thick,
domain=0:6*pi,
samples=200,
samples y=0
] ({cos(deg(x))}, {sin(deg(x))}, {x/(2*pi)});
\end{axis}
\end{tikzpicture}
Plotting from Data Files
Reading CSV Files
% Create data file: data.csv
% x, y1, y2
% 0, 1.2, 2.1
% 1, 2.5, 3.4
% 2, 3.8, 4.2
% 3, 5.1, 5.8
\begin{tikzpicture}
\begin{axis}[
title={Data from CSV},
xlabel={$x$},
ylabel={$y$},
legend pos=north west
]
% Read and plot column 1 vs column 2
\addplot[blue, mark=*] table[
x=x,
y=y1,
col sep=comma
] {data.csv};
\addlegendentry{Series 1}
% Read and plot column 1 vs column 3
\addplot[red, mark=square*] table[
x=x,
y=y2,
col sep=comma
] {data.csv};
\addlegendentry{Series 2}
\end{axis}
\end{tikzpicture}
Inline Data Tables
\begin{tikzpicture}
\begin{axis}[
title={Inline Table Data},
xlabel={Month},
ylabel={Revenue},
symbolic x coords={Jan, Feb, Mar, Apr},
xtick=data
]
\addplot table {
Jan 150
Feb 180
Mar 165
Apr 210
};
\end{axis}
\end{tikzpicture}
Advanced Techniques
Fill Between Curves
\usepgfplotslibrary{fillbetween}
\begin{tikzpicture}
\begin{axis}[
domain=0:2*pi,
samples=100
]
% Plot curves with names
\addplot[blue, name path=A] {sin(deg(x))};
\addplot[red, name path=B] {cos(deg(x))};
% Fill area between curves
\addplot[green!30] fill between[
of=A and B,
soft clip={domain=0:1.57}
];
\end{axis}
\end{tikzpicture}
Error Bars
\begin{tikzpicture}
\begin{axis}[
title={Experimental Data},
xlabel={Trial},
ylabel={Measurement},
error bars/y dir=both,
error bars/y explicit
]
\addplot[
blue,
mark=*,
error bars/.cd,
y dir=both,
y explicit
] coordinates {
(1,10) +- (0,0.5)
(2,15) +- (0,0.8)
(3,20) +- (0,1.2)
(4,22) +- (0,0.9)
(5,25) +- (0,1.5)
};
\end{axis}
\end{tikzpicture}
Box Plots
\usepgfplotslibrary{statistics}
\begin{tikzpicture}
\begin{axis}[
title={Box Plot Example},
ylabel={Distribution},
boxplot/draw direction=y
]
\addplot+[
boxplot prepared={
median=5,
upper quartile=6,
lower quartile=4,
upper whisker=8,
lower whisker=2
},
] coordinates {};
\end{axis}
\end{tikzpicture}
Frequently Asked Questions
How do I install PGFPlots?
PGFPlots comes with most LaTeX distributions. Add \usepackage{pgfplots} and \pgfplotsset{compat=1.18} to your preamble. For manual installation, use tlmgr install pgfplots (TeX Live) or the MiKTeX Package Manager.
Why is my plot compilation slow?
Complex plots (especially 3D surfaces with many samples) can be slow. Solutions: (1) Reduce sample count, (2) Use the externalize library: \usepgfplotslibrary{external} and \tikzexternalize, (3) Compile plots separately and include as images.
Can I plot data from external files?
Yes! PGFPlots supports CSV, DAT, and custom delimited files. Use \addplot table[options] {filename.csv}; with options like x=column1, y=column2, col sep=comma.
How do I change colors in my plots?
Use predefined colors (red, blue, green), color mixing (blue!50), or define custom colors with \definecolor{mycolor}{RGB}{255,100,50}. For color schemes, use colormap/viridis or other built-in colormaps.
Can I create polar plots?
Yes! Load the polar library with \usepgfplotslibrary{polar} and use the polaraxis environment instead of axis.
How do I export plots as standalone images?
Use the standalone document class:
\documentclass[tikz,border=5pt]{standalone}
\usepackage{pgfplots}
\pgfplotsset{compat=1.18}
\begin{document}
\begin{tikzpicture}
\begin{axis}
% Your plot here
\end{axis}
\end{tikzpicture}
\end{document}
What's the difference between samples and domain?
domain sets the x-range (e.g., domain=0:10), while samples sets how many points to calculate (e.g., samples=100). More samples = smoother curves but slower compilation.