Separate time series from a list

Jussi Jokinen's Avatar

Jussi Jokinen

27 Sep, 2022 08:10 PM

Hi,
I just started with Nodebox (yesterday!) and got instantly hooked. Even though the logic is pretty new to me after coding visualisations with javascript. A lot of stuff is very easy to achieve but now I got totally stuck and cannot find help from tutorials or documentation.

I have a dataset of medicines with dates of approval – my intension is to wrap each year as a "ray" of ellipses around a circle so that all medicines approved that year would stack along common line (if that makes sense).

I assume that involves calculating the count of medicines per year and use that info for positioning ellipses, but can't wrap my head around how to do it with nodes. In javascript I'd use counter variable, but here it's not an option (I guess)?

Find my project attached. On the left side I've calculated the count of medicines for one year. This I got. But how to automatically calculate all the years found in this data?
I'd be very thankful for any insights and give further explanation if needed.

  1. 1 Posted by Jussi Jokinen on 27 Sep, 2022 08:15 PM

    Jussi Jokinen's Avatar

    Forgot to include dateformatter clojure script that is used in the project. Here's new project archive.

  2. Support Staff 2 Posted by john on 28 Sep, 2022 03:52 AM

    john's Avatar

    Hi Jussi!

    Welcome to the Nodebox community. It is exciting to meet someone who gets hooked and makes such immediate progress.

    Counting data rows by year is not too hard in Nodebox, but does require one tricky concept: the subnetwork. Subnetworks allow you to define higher level functions by grouping nodes together. Crucially, they also allow you to control the way data is fed into your function, either one item at a time or all items at once.

    I made a demo to show you how this is done. See screenshot and attached zip file. My demo is called Year Counts.

    The first problem we have is that your original data file does not have a year column (which we will need to do the counts). So I first make a simple table with only two columns: the date for each row (PAATOSPVM) and the clean year derived from your Clojure function.

    I get a list of which years are in the data using a distinct node (there are 59 years from 1964 to 2022). I then feed that list of 59 years, plus the simple data table I just made, into a subnetwork called year_counts. Open it up (control-click "Edit Children") to see how it works.

    All I do is filter the data table to a single year and then count the rows. I then return another simple table with year and count.

    The reason I had to wrap this inside a subnetwork is that we need this function to fire once for each year, returning one row of the count table at a time. Each time the function fires we want to read in the entire data table, but only one year at a time.

    To do this you have to do something that is not at all obvious and is not well documented. Once you make your subnetwork and publish the data (just a null node renamed as "data") and the year, you need to select it and open the Metadata dialog (just above the parameter pane). You will see two ports, data and year. Select data and change the Range value on the left from "Value" (one at a time) to "List" (all at once). Verify that the Range value for the year port remains as "Value"

    Doing this ensures that each time the function fires the entire data file will be filtered against one year at a time. This is the least intuitive part of Nodebox and no one gets it without help. Fortunately, the rest of Nodebox is much more straightforward.

    Once you have the counts for each year, the rest is pretty easy. There are MANY ways to make rays of dots. I used another subnetwork to make a group of N dots in a horizontal line (where N is the count for each year). I displace these to the right by an arbitrary value (RADIUS) and then rotate them evenly around a circle.

    Tiny dots like this are a bit hard to see, so I lightened the color and placed them against a dark background. I also added labels for the years. Play with the demo to see how it works.

    I hope this gets you unstuck. Once you get used to subnetworks, you should quickly start to get the hang of Nodebox. Just think of each node as a javascript function with inputs and a single output. You will find that debugging is MUCH easier and the immediate feedback you get by adjusting parameters is great fun.

    Good luck and please don't hesitate to write again with more questions. I enjoy answering then and everyone benefits.

    John

  3. 3 Posted by Jussi Jokinen on 28 Sep, 2022 09:48 AM

    Jussi Jokinen's Avatar

    John, thank you so much!
    This was probably the best reply to a help request I've ever got. The range option was my blind spot, I did fiddle with subnetworks before but got confused about their inner workings related to lists – now it makes sense.

    My initial description of the problem wasn't clear though. The solution you provided does calculate the number of medicines. And that definitely gets me unstuck. My final goal though is that each dot on the rays represent one medicine so that I can bind some other variables to their appearances. For example, dots representing prescription medicines would be drawn with a different color.

    But I think I'll get forward by myself with this help. Thanks again!

  4. 4 Posted by Jussi Jokinen on 30 Sep, 2022 05:17 PM

    Jussi Jokinen's Avatar

    Here's a small follow-up to how this turned out.
    After understanding the list/value difference of the subnetwork inputs it still took me a while to figure out that subnetwork _output_ also can be set as list or value. But once I got that, I was able to put together a table where there's medicines per one year on one row. A list of lists, that is.
    Using that as a master table it was pretty straightforward to generate individual rays and use parallel import column of the data as the trigger for different fill colour.

    Now it's easy to add more visual properties based on any data column values if I wish so.

    This was a bit tricky so I guess I'll try to generalise the solution a bit more in order to use it in the future as well with different data sets.

    Find the project attached.
    Best,
    Jussi

  5. Support Staff 5 Posted by john on 30 Sep, 2022 11:36 PM

    john's Avatar

    Jussi,

    Thanks for sharing this! Very interesting. It's a nice looking visualization and also a functional one.

    Yes, you can also override the output of a subnetwork to be either list or value. It's not a technique I use very often, but, as you've shown, it works and can create a "list of lists". You could have achieved the same effect without doing this, but it is a clever solution.

    I learn new ways of using Nodebox every time I help someone. Thank you and please keep using Nodebox and sharing your work.

    John

Reply to this discussion

Internal reply

Formatting help / Preview (switch to plain text) No formatting (switch to Markdown)

Attaching KB article:

»

Already uploaded files

  • Screenshot_2022-09-27_at_23.10.44.png 257 KB
  • medics.zip 1020 KB

Attached Files

You can attach files up to 10MB

If you don't have an account yet, we need to confirm you're human and not a machine trying to post spam.

Keyboard shortcuts

Generic

? Show this help
ESC Blurs the current field

Comment Form

r Focus the comment reply box
^ + ↩ Submit the comment

You can use Command ⌘ instead of Control ^ on Mac

Recent Discussions

22 Nov, 2022 03:21 PM
22 Nov, 2022 10:40 AM
22 Nov, 2022 09:55 AM
20 Nov, 2022 12:06 PM
08 Nov, 2022 10:44 PM

 

05 Nov, 2022 08:40 AM
03 Nov, 2022 09:38 PM
24 Oct, 2022 11:32 AM
06 Oct, 2022 09:07 AM
05 Oct, 2022 02:22 AM
30 Sep, 2022 11:36 PM