First of all some style comments:
- Please use spaces after commas and around operators – It is hard to read your sequence of values for the
y lists when they are all compressed. And the same applies for the
([2,7]) when setting limits. It reads a lot better with
[3, 3.2, 3.5, ..., 5.8, 5.9, 5] and
- Choose better names for variables – Why have you used uppercase
X and then lowercase
y? What does
m signify? General recommendation is to use variable names meaning something, longer than one character long. For loop counters there is an exception for
k, in that sequence.
- Strange combination of
k – When I read code having
k, by convention I'm assuming there to be an
j somewhere. This is missing. In addition the
i is not a loop counter, but some predicate function for use with numpy's boolean arrays. Try finding a better name for
i, possibly something like
And then some considerations regarding your coding algorithm:
- First of all I don't quite understand why you want to hide the
y-value and replace it with a flat value of
1, and then use markers to denote the few distinct y-values. To me, intuitively, it would make more sense to add markers for given y-ranges, and interconnect markers of a given style with lines. This would show corresponding x-ranges and y-ranges of values
- Limit the range of the plot – Your example plot has loads of empty space, which makes the entire plot look almost empty. If you use
max, you can limit the plot better. If you want to avoid having the min and max values on the axes, you could cheat a little and subtract/add
0.5 to those values. (An even better version would be to calculate the range, and add/subtract a percentage of that range to be used as limits)
Separate x-ranges with different y-values for each marker – In a comment you state that you want to see if the values are linearly separable. To me that read as you might have overlapping x-ranges for different x-values, and you want to visualize this.
In your current code, if you switch the fourth element to
y=2, the markers would overlap, so I suggest changing the
1 when you set
flat to be the current marker index, i.e.
k. This way you would easily see the line of a current marker, but can also see if they are overlapping.
Change size of markers – If adding a parameter,
s, to your call to
scatter, you can change the marker size, and make them a little more prominent. I found
200to a somewhat good size.
- Adding more markers? – I don't know if it's an alternative for you to use even more markers, but I tried adding some more and extended your data array with two extra x-values with a y-value of 2.
import numpy as np
import matplotlib.pyplot as plt
fig = plt.figure()
axes = fig.add_axes((1, 1, 1, 1))
x = np.array([3, 3.2, 3.5, 3.7, 3.8, 3.9, 5, 5.5, 5.8, 5.9, 5, 5.8])
y = np.array([1, 1, 1, 3, 2, 1, 2, 2, 2, 1, 2, 3])
markers = ['^', 'o', 's', 'v', 'p']
for idx, marker in enumerate(markers):
i = (y == idx + 1)
flat = [idx + 1 for val in y[i]]
axes.scatter(x[i], flat, marker=marker, s=200)
axes.set_xlim([min(x) - 0.5, max(x) + 0.5])
axes.set_ylim([min(y) - 0.5, max(y) + 0.5])
This resulted in the following figure:
As you can see there is a lot more empty space, bigger markers, and even easier to see that in my slightly changed base data the x-ranges are not totally separable.