Search code examples
pythonpandasvegavincent

Creating a multiline graph using Vincent


I am attempting to create a multiline graph using Vincent.

I have a csv file with the following layout:

,wk1,wk2,wk3,wk4,wk5,wk6,wk7,wk8,wk9
Tom J,97,65,82,65,101,84,79,71,83
Lisa R,95,87,95,65,61,78,93,95,56
Rich F,51,111,50,119,84,77,73,84,60
Anne E,63,68,89,70,95,80,56,75,82
Dan M,83,95,36,115,79,79,65,55,69
Mack W,67,89,72,79,47,64,113,94,33

Here is my code:

import pandas as pd
import vincent

df = pd.read_csv('weekscores.csv', index_col=0)

lines = vincent.Line(df)
lines.axis_titles(x='WEEKS', y='SCORE')
lines.legend(title='Player')
lines.to_json('line.html',html_out=True,html_path='line_template.html')

This runs and a graph is generated but no lines are displayed in the graph:

enter image description here

Inspecting the data using .grammar() I see something like this for each week's score:

{'val': 97, 'col': 'wk1', 'idx': 'Tom J'}

Any assistance in getting this to render is appreciated.


Solution

  • There are a couple issues here: the first is that Vincent (naively) assumes that line charts are going to take linear scales, when in this case we actual need an ordinal scale. The second issue is that the dataframe needs to be transposed so that the weeks are on the index. So, to get the plot you're looking for:

    import vincent
    import pandas as pd
    
    df = pd.read_csv('weekscores.csv', index_col=0)
    df = df.T
    df
    Out[27]: 
    Name  Tom J  Lisa R  Rich F  Anne E  Dan M  Mack W
    wk1      97      95      51      63     83      67
    wk2      65      87     111      68     95      89
    wk3      82      95      50      89     36      72
    wk4      65      65     119      70    115      79
    wk5     101      61      84      95     79      47
    wk6      84      78      77      80     79      64
    wk7      79      93      73      56     65     113
    wk8      71      95      84      75     55      94
    wk9      83      56      60      82     69      33
    

    Now that we've got the data flipped, we can create the line chart, and ensure that the x-scale is ordinal:

    lines = vincent.Line(df)
    lines.scales[0].type = 'ordinal'
    lines.axis_titles(x='WEEKS', y='SCORE')
    lines.legend(title='Player')
    

    and you should end up with something like the following:

    Linechart

    Hope this helps!