Closed swharden closed 5 years ago
Color map for vertical axises looks ideal in this example. But what if there are 5 plots for main axis, and 5 for secondary. How to understand which graph on which axis?
How does the user know which graph is on which axis?
@StendProg this is a good question! The user can control plottable object colors and also axis colors. It will be the user's responsibility to color-code their data appropriately.
Axis can be rainbow color mapped. From top to bottom with plot colors. But it may be hard to implement. Numbers filled with 2 different colors may looks ugly. Not familar with graphic editors to easy test it..
Not familiar with graphic editors to test these ideas
I'm familiar with graphics editors! I'll make some example plots using different color schemes and post the examples here so we can look at them and see which color styles look best.
I'll make some example plots using different color schemes
I started doing this but decided to take a step back and see how other graphing libraries solve this problem. Rather than invent a new rainbow-based method, I think we should use the "principle of least astonishment" and choose a conventional method. Two primary methods are commonly used:
multiple floating Y axes: This is the only option if the goal is to plot 3 or more different scales. I don't think these look very nice, and it would be very complicated to implement.
two Y axes with color-coded labels: This option is simple to implement. However, as @StendProg noted, if there are 5 plots for each axis it could get difficult to tell them apart.
I have decided to develop the second option. We can always come back to this topic later and add the first option too.
Multi-axis plots with 5 datasets per axis looks ugly because it is bad figure design (not because it is a limitation of the graphing library). Users are encouraged not to do this with any plotting library.
import matplotlib.pyplot as plt
import numpy as np
def randomData():
return np.cumsum(np.random.random_sample(100)-.5)
plt.figure(figsize=(6, 4))
axis1 = plt.gca()
axis1.set_ylabel("primary Y", color='b', fontsize=16)
for i in range(5):
axis1.plot(randomData(), color='b')
axis2 = axis1.twinx()
axis2.set_ylabel("secondary Y", color='r', fontsize=16)
for i in range(5):
axis2.plot(randomData()*1000, color='r')
plt.title("Multi-Y Demo", fontsize=24)
plt.tight_layout()
plt.savefig("multi-y.png")
plt.show()
@StendProg I think this is looking pretty good! What do you think?
https://github.com/swharden/QuickPlot/blob/83bb510a1659412f0ec02fd0fe328a77d4a52bf2/demos/WinFormsDemos/FormMultiY.cs#L47 https://github.com/swharden/QuickPlot/blob/83bb510a1659412f0ec02fd0fe328a77d4a52bf2/demos/WinFormsDemos/FormMultiY.cs#L53
Maybe i am wrong, but i expected different result. During zoom i think it need to zoom both plots, and redraw both axises. In you demo zoom affected only primary plot and axis. Secondary stay AutoAxis all the time.
Also it would be nice to add some param(or default behavior). Then it enabled axis labels filled with plot color automatic, not but manual setup.
Setting secondary axis flag in Style
param also a bit confusing. I think Style
only about fonts and colors before taking deeper look.
As part of constructive criticism, you done great job anyway.
I prefer setup secondary axis with some of this interface:
What would you think?
The mouse should pan/zoom both Y axes at the same time
You're right. I checked, and this is how matplotlib does it too.
When data is plotted on the second axis, it would be nice if the second axis would get colored the same color as the data automatically
I like this idea too! I'll do this.
Setting secondary axis flag in
Style
param also a bit confusing. I thinkStyle
only about fonts and colors before taking deeper look. What aboutScatter(dataX, data2, style2, secondaryY: true);
?
Scatter plots will have customization options like color, linewidth, marker size, marker shape, anti-aliasing, secondary axis, errorbars, and maybe more. My hope is that all these options can be packaged into the Style
object. My goal is to avoid having a large number of arguments.
ScottPlot's argument list got out of control: Plot.cs#L277-L289
Ideally all the plotting functions would just take the data and the config object.
Maybe it would be more clear if I called it DataConfig
?
This still needs some work to figure out the best way to proceed 🤔
Config
or settings
would be good, Style
is confusing name, and i think not only for me.
Style class can be moved inside like Settings.Style
Maybe we should make two objects, one for config and one for style?
figure.plot.Scatter(double[] xs, double[] ys, DataConfig config, DataStyle style)
Take you own decission on api. I can add only one thing, people don't like to go deep in specs, and want to get best result with simple params. If Style
would be use frequent, it can be made separate param, otherwise 1 param object better
I modified the user controls so the mouse now controls both Y axes at the same time.
I'll come back around later and improve the style system.
following-up, argument-rich methods are used now and colors of axis labels and ticks are easy to configure:
double[] xs = QuickPlot.Generate.Consecutative(100);
double[] ysSmall = QuickPlot.Generate.Sin(100, mult: .01);
double[] ysBig = QuickPlot.Generate.Cos(100, mult: 100);
var figure = new QuickPlot.Figure();
figure.plot.Scatter(xs, ysSmall, color: SkiaSharp.SKColors.Blue);
figure.plot.Scatter(xs, ysBig, secondY: true, color: SkiaSharp.SKColors.Red);
figure.plot.YLabel("Primary Y", color: SkiaSharp.SKColors.Blue);
figure.plot.YLabel("Secondary Y", secondY: true, color: SkiaSharp.SKColors.Red);
figure.plot.XLabel("Horizontal Axis");
figure.plot.Title("Twin Y Axis Demo");
I'd like to be able to create a chart like the one below.