Incoherent input shape requirements for 2D and 3D plots
EtienneDesticourt opened this issue · 4 comments
Hi,
When plotting a 3D function the input shape of the plot function is (3, num points):
x = [1, 2, 3, 4, 5, 6]
y = [0, 0, 0, 0, 0, 0]
z = [1, 2, 3, 4, 5, 6]
line = np.array([x, y, z])
print(line.shape) # -> (3, 6)
plot(line)
When plotting in 2D it's (num points, 2):
x = [1, 2, 3, 4, 5, 6]
y = [1, 2, 3, 4, 5, 6]
line = np.array([x, y]).T
print(line.shape) # -> (6, 2)
plot(line)
It should be standardized to (num points, dimensions) which is what's used in most scientific packages.
Cheers
I'd like to explain my thinking regarding your first example, because that is a special case which exists on top of the standardized shape that you describe
x = [1, 2, 3, 4, 5, 6]
y = [0, 0, 0, 0, 0, 0]
z = [1, 2, 3, 4, 5, 6]
line = np.array([x, y, z])
It's possible to plot using the standard array shape, e.g.
>>> x = np.array([(1,1,1),(2,2,2),(3,3,3),(4,4,4),(5,5,5),(6,6,6)])
>>> x.T.shape
(3, 6)
The idea I had in mind for the plot function was: try and guess what the user is thinking and then make it do what I think they want.
The other idea was: try to make it so the code used for creating plottable functions in python looks as much like the equations in math books as possible. That is why I added the extra case for 3d where it accepts non-standard shapes.
I felt it would clearly be better to support multiple shapes for doing 3d plots, instead of constraining the plot function to one specific shape. Curious for your thoughts?
P.S. It's clear that the way data formatting works for the plot function causes confusion. I had a funny idea to resolve this, which is to create an alternate version of the plot function which has identical arg/kwarg structure to matplotlib, and simply reimplements everything in matplot lib using the mathinspector plotting library. The goal being, you can search/replace any file which uses matplotlib.pyplot.plot
and replace it with mathinspector.plot
and it will work exactly as expected.
P.P.S Despite the confusion caused by the data formatting of the plot function, the reason I went with that system is because it felt like other solutions caused an explosion of boilerplate code to keep track of everything. It felt like python really wanted to have plot use data formatting like it does because the source code files are so much cleaner this way. In the past the code was not as clean, its been through over 5 massive refactors =) Now that everything is where I want it in the code, I'm open to the idea of experimenting with ways to modify the plot function and am not as concerned about how these changes might impat the integrity and purity of the code base because I understand every angle pretty well now.
You can't plot using this snippet, at least in the version I have.
>>> x = np.array([(1,1,1),(2,2,2),(3,3,3),(4,4,4),(5,5,5),(6,6,6)])
>>> x.T.shape
(3, 6)
The idea I had in mind for the plot function was: try and guess what the user is thinking and then make it do what I think they want.
I feel very strongly that this is an anti-pattern, when a program tries to guess what I want it just annoys me I don't want my computer to do things I didn't ask it to, first it often guesses wrong and second it breaks discoverability because you can't make assumptions about the way things work so you're left to guess what the program is trying to guess.
"One right way" is a big part of the zen of python.
Also what do you do if you have arrays with the shape (3, 2) or (2, 3) or (2, 2) or (3, 3) ?
Copying matplotlib's API could work, people would certainly be familiar with it. You could also copy ggplot2 from R it's less familiar to python users but it's considered the crème de la crème for scientific plotting and better than mpl.
You can't plot using this snippet, at least in the version I have.
That's a bug. Oops. It used to work.
I feel very strongly that this is an anti-pattern
I have to admit the results of the experiment with data-formatting has led to the conclusion it is an anti-pattern, just like you say.
I don't want my computer to do things I didn't ask it to, first it often guesses wrong and second it breaks discoverability because you can't make assumptions about the way things work so you're left to guess what the program is trying to guess.
I am sold. Let's reimagine the way passing arguments to plot
works from the ground up, and also reimagine how the visual interface on the right hand side of the node editor ("the output area") will handle various plotting functionality.
"One right way" is a big part of the zen of python.
It's important for the logical consistency of the UI/UX design that the plot
function has an arg/kwarg interface which directly corresponds to visual elements in the output area. Right now the output area is a thin vertical strip, which makes it hard to put labels on multiple output nodes.
Copying matplotlib's API could work
I would strongly prefer to create the best possible interface and not copy matplotlibs. There are some things matplotlib does that are ok in terms of the args/kwargs it accepts.
My preference is to take whats good about the matplotlib interface, get rid of whats bad, and then figure out what makes the most sense for mathinspector.
What do you think would be the ideal arg/kwarg interface for plot
?
Sounds good to me. I have no strong opinion on the plot interface for now, it's such a huge scope. If you implement something I'll try to implement one of my projects in it and check where I get stuck.