I mostly use matplotlib+seaborn in a python code block, and tell matplotlib to write pdf output. Then I'll include the pdf with a link. Here's a sketch:
# first run this code block:
#+begin_src python
# some code to generate a plot at images/plot.pdf
#+end_src
# then put the image where you want it:
#+CAPTION: Some plot or other
#+NAME: fig:asdfhjkl
#+ATTR_LATEX: :width 0.7\textwidth
[[file:./images/plot.pdf]]
You can put some incantation on the top of your .org file to make it run all the code blocks before exporting, but I usually just run them manually if I need to make a change to a figure.
Here's a full example from one of my papers. You can see I made quite a few revisions with all the commented-out lines. Note the :results none :exports none arguments to the org-babel code block, which makes the code itself invisible in the resulting paper.
#+begin_src python :results none :exports none
import matplotlib.pyplot as plt
import seaborn as sns
def get_loss(filename):
loss = []
with open(filename) as f:
for line in f:
loss.append(float(line.split(' = ')[-1]))
return loss
data = {}
# data['NLP (P=0.1)'] = get_loss( '../sample-programs/loss-epochs-nlp-0.1-30.txt')
# data['NLP (P=0.2)'] = get_loss( '../sample-programs/loss-epochs-nlp-0.2-30.txt')
# data['NLP (P=0.4)'] = get_loss( '../sample-programs/loss-epochs-nlp-0.4-30.txt')
# data['NLP (P=0.8)'] = get_loss( '../sample-programs/loss-epochs-nlp-0.8-30.txt')
data['NLP (P=0.1)'] = get_loss( '../sample-programs/loss-epochs-both-0.1-30.txt')
data['NLP (P=0.2)'] = get_loss( '../sample-programs/loss-epochs-both-0.2-30.txt')
data['NLP (P=0.4)'] = get_loss( '../sample-programs/loss-epochs-both-0.4-30.txt')
# data['NLP (P=0.8)'] = get_loss( '../sample-programs/loss-epochs-both-0.8-30.txt')
data['Plain'] = get_loss( '../sample-programs/loss-epochs-30.txt')
sns.lineplot(data=data, palette='deep')
# TODO add plots for combined Plain+NLP at other probabilities
plt.xlabel('Epoch')
plt.ylabel('Loss')
plt.legend()
filename = 'images/loss-plot.pdf'
plt.savefig(filename)
return filename
#+end_src
#+CAPTION: Training loss for data augmentation
#+LABEL: fig:loss
#+ATTR_LATEX: :width 0.5\textwidth
#+RESULTS: fig:loss
[[file:./images/loss-plot.pdf]]
Here's a full example from one of my papers. You can see I made quite a few revisions with all the commented-out lines. Note the :results none :exports none arguments to the org-babel code block, which makes the code itself invisible in the resulting paper.