So I'm surprised nobody mentions the pgf backend of matplotlib, with it I can get quite decent results when properly configured. Also, as the creator of robust-externalize (a very generic library to cache arbitrary content), let me do some shameful advertisement on how to include the diagram directly in your tex (which also has the benefit of configuring directly the width of the diagram to the current line width). Make sure to get version 2.6 or above (not to worry about indentation, if your distribution is too old, you can just save the .sty file to your main folder).
Then, just type (cf comments to tune the font size of title etc.):
\documentclass{article}
\usepackage{lipsum}
\usepackage{tikz}
\usepackage{robust-externalize}
\robExtConfigure{enable fallback to manual mode} % prints command to run in PDF if shell-escape is not used/forgotten
\def\mathdefault#1{#1} % Needed in matplotlib 3.8: https://github.com/matplotlib/matplotlib/issues/27907
\begin{document}
\lipsum[1]
\begin{figure}[ht]
\centering
\begin{CacheMeCode}{python, custom include command={\input{\robExtAddCachePathAndName{\robExtFinalHash.pgf}}}, set placeholder eval={LINEWIDTH}{\lenToCmNoUnit[in]{\linewidth}}}
import matplotlib.pyplot as plt
import matplotlib
from matplotlib.pyplot import figure
matplotlib.use("pgf")
# See this link for details on how to preview the image in jupyter
# https://matplotlib.org/stable/users/explain/text/pgf.html
matplotlib.rcParams.update({
"font.family": "serif",
"font.serif": [], # Use LaTeX default serif font.
"text.usetex": True, # use inline math for ticks
## You can change the font size of individual items with:
# "font.size": 11,
# "axes.titlesize": 11,
# "legend.fontsize": 11,
# "axes.labelsize": 11,
})
figure(figsize=(__LINEWIDTH__, 0.7*__LINEWIDTH__))
year = [2014, 2015, 2016, 2017, 2018, 2019]
tutorial_count = [39, 117, 111, 110, 67, 29]
plt.plot(year, tutorial_count, color="#6c3376", linewidth=2)
plt.title("Simple plot for $\delta = 2$")
plt.xlabel('Year')
plt.ylabel('Number of futurestud.io Tutorials')
print(get_filename_from_extension(".pgf"))
# https://stackoverflow.com/a/52587591/4987648
plt.savefig(get_filename_from_extension(".pgf"), bbox_inches="tight")
\end{CacheMeCode}
\caption{Test}%
\end{figure}
\end{document}
% Local Variables:
% TeX-command-extra-options: "--shell-escape -halt-on-error"
% End:
and compile with --shell-escape (see documentation if you do not want shell-escape) to get:

If you try to change the margins with \usepackage[margins=2.5cm]{geometry}, you can see that it will automatically adapt:

Create a style to avoid long copy/paste and increase reusability
You can also create based on the above template your own robust-externalize preset:
\documentclass[11pt]{article}
\usepackage{lipsum}
\usepackage{tikz}
\usepackage{robust-externalize}
\robExtConfigure{enable fallback to manual mode} % prints command to run in PDF if shell-escape is not used/forgotten
\def\mathdefault#1{#1} % Needed in matplotlib 3.8: https://github.com/matplotlib/matplotlib/issues/27907
\begin{PlaceholderFromCode}{MY_MATPLOTLIB_START}
import matplotlib.pyplot as plt
import matplotlib
from matplotlib.pyplot import figure
matplotlib.use("pgf")
https://matplotlib.org/stable/users/explain/text/pgf.html
matplotlib.rcParams.update({
"font.family": "serif",
"font.serif": [], # Use LaTeX default serif font.
"text.usetex": True, # use inline math for ticks
You can change the font size of individual items with:
"font.size": 11,
"axes.titlesize": 11,
"legend.fontsize": 11,
"axes.labelsize": 11,
})
figure(figsize=(MY_MATPLOTLIB_WIDTH, MY_MATPLOTLIB_HEIGHT))
\end{PlaceholderFromCode}
\begin{PlaceholderFromCode}{MY_MATPLOTLIB_END}
https://stackoverflow.com/a/52587591/4987648
plt.savefig(get_filename_from_extension(".pgf"), bbox_inches="tight")
\end{PlaceholderFromCode}
\robExtConfigure{
new preset={my matplotlib pgf}{
python,
% If you want to include it via a simple input
custom include command={\input{\robExtAddCachePathAndName{\robExtFinalHash.pgf}}},
% If you also want to cache the tikz code for faster rendering
% (otherwise only python -> tikz will be cached, but not tikz -> pdf)
% custom include command={\evalPlaceholder{\cacheMe[tikz]{\input{ROBEXT_OUTPUT_PREFIX.pgf}}}},
set placeholder eval={LINEWIDTH}{\lenToCmNoUnit[in]{\linewidth}},
add import={MY_MATPLOTLIB_START},
add to placeholder={ROBEXT_MAIN_CONTENT}{MY_MATPLOTLIB_END},
%% Create a few functions to change the width easily:
set size inches/.style 2 args={
set placeholder={MY_MATPLOTLIB_WIDTH}{#1},
set placeholder={MY_MATPLOTLIB_HEIGHT}{#2},
},
set size cm/.style 2 args={
set size inches={#1/2.54}{#2/2.54},
},
set size pc/.style 2 args={
set size inches={#1LINEWIDTH}{#2LINEWIDTH},
},
set size pc={1}{.7}, % default size
}
}
\begin{document}
\lipsum[1]
\begin{figure}[ht]
\centering
\begin{CacheMeCode}{my matplotlib pgf, set size pc={1}{.5}}
year = [2014, 2015, 2016, 2017, 2018, 2019]
tutorial_count = [39, 117, 111, 110, 67, 29]
plt.plot(year, tutorial_count, color="#6c3376", linewidth=2)
plt.title("Simple plot for $\delta = 2$")
plt.xlabel('Year')
plt.ylabel('Number of futurestud.io Tutorials')
\end{CacheMeCode}
\caption{Test}%
\end{figure}
\end{document}
% Local Variables:
% TeX-command-extra-options: "--shell-escape -halt-on-error"
% End: