-
Notifications
You must be signed in to change notification settings - Fork 39
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Provide data to graphs beyond Float pairs #27
Comments
@BradLarson @marcrasi, as the first evaluation is coming up on 24th, is there anything specific I need to complete before that? |
Now I am not sure if generics is the correct way to proceed. static func + (left: Point, right: Point) -> Point {
return Point(left.x + right.x, left.y + right.y)
} Even if I write a protocol Addable overloading the + operator, it wont work because then I still wont be able to use other operations like * - / etc. Making the input for each plot conform to specific protocols seems like the right way. But is that not kind of what we are doing right now? We are accepting only specific data types. Maybe we can also have overload for Int, Double, etc...but we'll have to add extra variables for them in the Point type like I did for String... How was this handled in CorePlot? |
No, you've already done everything I'm looking for in the first milestone and you're doing really great in everything the evaluation asks about :) |
about generics, I haven't thought much about how you could use them for plotting data types, but here's an initial answer to your question. If you make
|
Thanks! I didn't know that we could write such generic specific extensions. I'll try this and see if it helps. |
@KarthikRIyer - On the matter of evaluations, as Marc said, you're doing great. You've hit the initial milestone objectives and gotten this to a demonstrable state both at the console and in Jupyter notebooks. In fact, your work in using lodepng, setting up your Swift / C / C++ targets, and interacting with Jupyter was really informative to watch and helped me finally get my GPUImage framework operational once again on Linux and with Jupyter notebooks. Learning goes both ways on a project like this. |
@BradLarson glad that working together on this helped you too! |
@BradLarson @marcrasi I don't think generics is a good because when I started by turning the Point type to a generic, I eventually realised that I had to convert all types to generics. Even the types like Series, Axis, etc. It's also becoming kind of difficult to handle different types. For example: This didn't help. They seem to have used Double everywhere and have different data input types for each plot, like LineChartDataEntry, PieChartDataEntry, BarChartDataEntry. I had faced the same issue when working on my previous plotting project Graph-Kit. I'd opted to use float then. Can we use the same method we're using right now? Maybe use Double instead of Float? |
Till this is figured out I'll start work on histogram. |
Also could you give me an idea of how people would want to plot using Tensors? |
Sorry I've been away from this, have been busy with other matters. For types, I think it's worth approaching this from the standpoint of what is needed by the plot types and what people will want to provide as inputs. For a scatter plot, for example, your plots will need a type on the X and Y axes that can be converted to a floating-point number so that display arithmetic can be done with it. For a bar chart, the Y axis will need to be floating-point convertible, but the X axis will need hashable values (for binning) that can be represented as a String. You need to somehow define the inputs (probably using protocols) to a plot, and then allow users to supply the various types of input data that can be converted to that. You may not even need to use generics here, because I don't know that it's essential to preserve type information all the way through to your plot. We'd have to think about if type erasure would be acceptable. I'm thinking that Point might not be the most expressive name here, given the different input types you might be dealing with. I could see renaming it to Pair<T, U> and possibly Triplet<T, U, V> for 2-D and 3-D plots, respectively. If type erasure wasn't a concern, you could then have scatter plots take in series of |
Also, is pairing off each datapoint going to work for all cases? In a scatter plot, I can see people wanting to provide two or more series of Y values that share the same series of X values. Is this approach generic enough to support that? |
I'll try working with the Pair<> approach. Regarding the scatter plot, input is in given as an array for x and an array for y using the addSeries function.... |
@BradLarson just one clarification...On the user end API do we want the users to pass in arrays as it is being done now, or would they pass in an array of Pair<Float,Float>? |
Leaving this open for now. Just in case we need to make changes to this part in the near future. |
I have some things to add to this discussion (which is very old, I know). Over the last week or so, I added a heatmap (example output). While doing so, I started to wonder about a couple of things:
So given all of that, I made this Heatmap work with any The upshot of this is that I can draw a heatmap of a String (by its ASCII values). And rather than copying all the ASCII values or losing that type information in another way, the type is literally a Anyway, buoyed by this apparent success with Heatmaps, I tried to see if this could apply to other plots by prototyping a new BarGraph. It works in very much the same way, with any Then came stacking, and I thought - it would be kind of boring if I could only stack other ranges on top of my range - why not make the stack its own plot, with its own So yeah, those ugly names. They were a bit of a problem. For example, I have a test that creates a That issue can be solved by moving to more of a functional, declarative API. Luckily, that seems to be something of a trend these days, with things like SwiftUI (which also has to deal with enormous generic towers and solves it in a similar way). The resulting code does look very pretty: let barGraph = (5..<20).plots
.barChart() {
$0.label = "Existing product"
$0.color = .orange
$0.formatter = .custom { String(2000 + $1) }
$0.graphOrientation = .horizontal
$0.plotTitle.title = "Financial Results"
$0.plotLabel.xLabel = "Profit ($m)"
$0.plotLabel.yLabel = "Year"
}.stackedWith((0..<15)) {
$0.segmentLabel = "New product"
$0.segmentColor = .green
}.stackedWith(-10..<1) {
$0.segmentLabel = "Bad product"
$0.segmentColor = .red
} This creates a That heatmap I showed at the start was generated with the following: let data: [[Float]] = median_daily_temp_boston_2012
let heatmap = data.plots
.heatmap(interpolator: .linear) {
$0.plotTitle.title = "Maximum daily temperatures in Boston, 2012"
$0.plotLabel.xLabel = "Day of the Month"
$0.colorMap = ColorMap.fiveColorHeatMap.lightened(by: 0.35)
$0.showGrid = true
$0.grid.color = Color.gray.withAlpha(0.65)
} Anyway, I thought it would be a good idea to discuss this before moving much further. There is still some work to do and refinements to be made, but I think these are some pretty interesting results. This will all come after GCI, of course (or maybe after the current issues are done?), to avoid disturbing participants. |
@karwa the above results are really cool! Although I don't understand how all this works, I'm not as proficient in swift yet.
|
@KarthikRIyer Sure - so Then, for heatmaps for example, we extend I found this useful because autocomplete will show all of the available charts for your data, and type inference will pick up the correct type. Extending fundamental protocols like Oh, and all of those construction helpers end with a |
Thanks for the explanation @karwa! |
Initial discussion regarding this can be found here:
#23 (comment)
The text was updated successfully, but these errors were encountered: