Reputation: 107
I have the following matplotlib
snippet:
fig, ax = plt.subplots(figsize=(6,6))
values = np.random.normal(loc=0, scale=1, size=10)
ax.plot(range(10), values, 'r^', markersize=15, alpha=0.4);
which produces
as planned.
I'd like to make the line invisible where it overlaps with the points so that the points look more joined by the line rather than lying on top of the line. It is possible to do this by either making the line invisible where they overlap or to create a new line object that simply links the points rather than traces them?
To be explicit, I do not want the entire line removed, just the sections that overlap with the points.
Upvotes: 1
Views: 3010
Reputation: 339230
It is in general hard to let the lines stop at the edges of the markers. The reason is that lines are defined in data coordinates, while the markers are defined in points.
A workaround would be to hide the lines where the markers are. We may think of a three layer system. The lowest layer (zorder=1
) contains the lines, just as they are. The layer above contains markers of the same shape and size as those which are to be shown. Yet they would be colored in the same color as the background (usually white). The topmost layer contains the markers as desired.
import matplotlib.pyplot as plt
import numpy as np; np.random.seed(42)
fig, ax = plt.subplots(figsize=(6,5))
def plot_hidden_lines(x,y, ax = None, ms=15, color="r",
marker="^", alpha=0.4,**kwargs):
if not ax: ax=plt.gca()
ax.scatter(x,y, c=color, s=ms**2, marker=marker, alpha=alpha, zorder=3)
ax.scatter(x,y, c="w", s=ms**2, marker=marker, alpha=1, zorder=2)
ax.plot(x,y, color=color, zorder=1,alpha=alpha,**kwargs)
values1 = np.random.normal(loc=0, scale=1, size=10)
values2 = np.random.normal(loc=0, scale=1, size=10)
x = np.arange(len(values1))
plot_hidden_lines(x,values1)
plot_hidden_lines(x,values2, color="indigo", ms=20, marker="s")
plt.show()
Upvotes: 2
Reputation: 3648
I think the best way to go about it is to overlay the triangles over the lines:
import matplotlib.pyplot as plt
import numpy as np
values = np.random.normal(loc=0, scale=1, size=10)
plt.plot( range(10), values, marker='^', markerfacecolor='red', markersize=15, color='red', linewidth=2)
plt.show()
If you really want the see through aspect, I suggest you somehow calculate where the lines overlap with the markers and only draw the lines inbetween:
import numpy as np
import matplotlib.pyplot as plt
values = np.random.normal(loc= 0, scale=1, size=10)
for i in range(9):
start_coordinate, end_coordinate = some_function(values[i], values[i+1])
plt.plot([i, i+1], [start_coordinate, end_coordinate], *whatever_other_arguments)
plt.scatter(range(10), values, *whatever_other_arguments)
plt.show()
The hard part here is of course calculating these coordinates (if you want to zoom in this won't work), but honestly, given the difficulty of this question, I think you won't find anything much better...
Upvotes: 0