yuzie007 / mpltern

Ternary plots as projections of Matplotlib
https://yuzie007.github.io/mpltern
MIT License
39 stars 2 forks source link

Symbols not appearing entirely when on a side of the ternary #6

Closed charlesll closed 3 years ago

charlesll commented 3 years ago

The scatter symbols on the side of a ternary plot are not appearing entirely on top of the triangle. This makes them difficult to see. Is there a way to plot them on top of the triangle and avoid them to be partly hidden?

yuzie007 commented 3 years ago

Thank you for sharing the issue. Could you kindly share with me a minimum example to reproduce the issue? I am sorry but not yet sure what the problem you have is and also if this is the issue of mpltern or the matplotlib usage.

charlesll commented 3 years ago

Well I'm even able to provide the solution :)

Here is a piece of code with the good options from matplotlib to put markers above the grid and axes:

import numpy as np
import matplotlib.pyplot as plt 
import matplotlib, mpltern

data = np.array([[0,1,0], [0.2,0.2,0.6]])

fig = plt.figure()
ax = plt.subplot(1,1,1,projection='ternary',ternary_scale=100)

ax.grid(axis='t')
ax.grid(axis='l')
ax.grid(axis='r')

points = ax.scatter(data[:,0],data[:,1],data[:,2])

# this allows to put the points above the grid
ax.set_axisbelow(True)

# and this allows to put markers on top of the axes
points.set_clip_on(False)
charlesll commented 3 years ago

I must admit that the markers on the axes are still below the axis lines, but I don't know if we can solve this problem.

yuzie007 commented 3 years ago

Thanks for sharing the code! That helped to know your concern. First, this is basically the behavior of matplotlib (not specific for mpltern). To bring the borders behind the markers, you can modify "zorder" of each "spine" as follows:

import numpy as np
import matplotlib.pyplot as plt
import matplotlib, mpltern

data = np.array([[0,1,0], [0.2,0.2,0.6]])

fig = plt.figure()
ax = plt.subplot(1,1,1,projection='ternary',ternary_scale=100)

# This brings "spines" to the same "zorder" as ticks.
for spine in ax.spines.values():
    spine.set_zorder(0.5)

ax.grid(axis='t')
ax.grid(axis='l')
ax.grid(axis='r')

points = ax.scatter(data[:,0],data[:,1],data[:,2])

# this allows to put the points above the grid
ax.set_axisbelow(True)

# and this allows to put markers on top of the axes
points.set_clip_on(False)

Another solution may be to set some high value as "zorder" for "ax.scatter" explicitly.

Since this is the inherited behavior from matplotlib, and since I would like to keep the consistency with matplotlib as much as possible, I believe this not something to be "fixed" in mpltern.

I wish this helps your figure creation even a bit!

charlesll commented 3 years ago

Thanks, yes this helps !

I fully support the idea of keeping the consistency with matplotlib, this is important. e.g., it is this tight and transparent integration of mpltern and matplotlib that allowed me to solve my problem using matplotlib code!