nschloe / tikzplotlib

:bar_chart: Save matplotlib figures as TikZ/PGFplots for smooth integration into LaTeX.
MIT License
2.42k stars 218 forks source link

scatter plot ignores marker sizes #414

Open jgmakin opened 4 years ago

jgmakin commented 4 years ago

MWE: This bit of code plots open circles of a fixed but non-default size:

import matplotlib.pyplot as plt
from tikzplotlib import get_tikz_code

max_marker_size = 300
fig, ax = plt.subplots()
ax.scatter(
    [1, 2, 3], [5, 7, 1],
    s=[max_marker_size]*3,
    facecolors='none', edgecolors='black', linewidths=3.0
)
get_tikz_code()

but the tex code it produces,

% This file was created by tikzplotlib v0.9.2.
\begin{tikzpicture}

\begin{axis}[
tick align=outside,
tick pos=left,
x grid style={white!69.0196078431373!black},
xmin=0.9, xmax=3.1,
xtick style={color=black},
y grid style={white!69.0196078431373!black},
ymin=0.7, ymax=7.3,
ytick style={color=black}
]
\addplot [only marks, mark=o, draw=black, colormap/viridis, visualization depends on={\thisrow{sizedata} \as\perpointmarksize}, scatter/@pre marker code/.append style={/tikz/mark size=\perpointmarksize}]
table{%
x                      y                      sizedata
1 5 9.7720502380584
2 7 9.7720502380584
3 1 9.7720502380584
};
\end{axis}

\end{tikzpicture}

does not use the size information to adjust the marks.

This can be remedied simply by pre-pending scatter to the list of \addplot options (see Sec. 4.5.12 of the pgfplots manual)--except that pgfplots will then try to impose a color scheme as well. That can be fixed by changing .append style to .style in scatter/@pre marker code/.append style={/tikz/mark size=\perpointmarksize}, and adding an empty post-marker: scatter/@post marker code/.style={}. Hence, the working tex code would be:

begin{tikzpicture}

\begin{axis}[
tick align=outside,
tick pos=left,
x grid style={white!69.0196078431373!black},
xmin=0.9, xmax=3.1,
xtick style={color=black},
y grid style={white!69.0196078431373!black},
ymin=0.7, ymax=7.3,
ytick style={color=black}
]
\addplot [
 scatter,
 only marks,
 mark=o,
 draw=black,
 colormap/viridis,
 visualization depends on={\thisrow{sizedata} \as\perpointmarksize},
 scatter/@pre marker code/.style={/tikz/mark size=\perpointmarksize},
 scatter/@post marker code/.style={}
]
table{%
x                      y                      sizedata
1 5 9.7720502380584
2 7 9.7720502380584
3 1 9.7720502380584
};
\end{axis}

\end{tikzpicture}

I can try to make the appropriate changes to tikzplotlib myself (presumably somewhere around here), but I don't think I have a good enough handle on all the cases this bit of code is supposed to cover.

(I note in passing that linewidths=3.0 also appears to have no effect; perhaps I should open this as a separate issue.)

youcann commented 4 years ago

Can confirm the issue!

braun-steven commented 3 years ago

Does anyone have a workaround for this?

ORippler commented 3 years ago

Possibly related due to scatter flag inconsistencies: #480 #479

J-Lips commented 1 year ago

Easiest workaround is to replace scatter by plot. This won't offer all functionality of scatter, but for the MWE it is sufficient:

import matplotlib.pyplot as plt
from tikzplotlib import get_tikz_code
import numpy as np

fig, ax = plt.subplots()
max_marker_size = 300
ax.plot(
   [1, 2, 3], [5, 7, 1],
   linestyle='None', marker='o', markersize=np.sqrt(max_marker_size), 
   markeredgecolor='black', markerfacecolor='none', linewidth=3.0
)
get_tikz_code()

gives the desired result. Note that the markersize setting of plot is not the same as the size setting of scatter, so you need to take the root of the scatter size to get the intended size.