Charity Comparison Plot


Over the holiday season I heard several discussions on which charities are best to donate to and why some are better than others. With this in mind, I thought it would be interesting to examine the stats which set one charity over another and find a way to visualize these in an effective manner. With some help from Charity Navigator, I was able to source and collect the appropriate information and thought it a great time to finally give Plotly a go.

Data Collection

Charity Navigator seems (from some quick research) to be one of the leading and trusted sources to grab charity ratings from. They analyze both the financial data and stats on the transparency and accountability of the organization. From this site, I manually listed some of the more important stats from each report, including charity navigator's overall rating. Some of the other features I grabbed were fund-raising efficiency, CEO compensation, annual contributions, and percentages of revenue towards programs. I opted to grab only 15 or so of the more known charities.. given more time I'm hoping to connect to their API and find a way to load in a much larger amount.
The rather simple csv sheet I'm working with:

      

Planning The visual

So I've wanted to create a parallel coordinate plot for awhile now; I think they can provide a very informative and intuitive method of comparison. With the charity organizations have numerous dimensions to compare, this seemed to fit perfectly.

Exploring routes to creating parallel coord charts in Python, I came across Plotly and thought its built-in interactive features for this type of plot were awesome. So, I went about running Python and plotly to create the visual.

The Code

I started with the required imports and by importing the data in with pandas:

import pandas as pd
import plotly 
import plotly.plotly as py
import plotly.graph_objs as go
import os

#Plotly credentials
plotly.tools.set_credentials_file(username='Andyjtrick', api_key= os.environ.get("PLOTLY_KEY"))


df = pd.read_csv('./data/test.csv')


Next was to detail the plot. The first section instructs Plotly to color the lines based upon their organization category. Following that is the code to set the numerous y axes, their ranges, and labels.

data = [
    go.Parcoords(
        line = dict(color = df['cat_num'],
                   colorscale = [[0, '#6C9E12'], ## social services
                                [0.25,'#0D5F67'], ## humanitarian
                                [0.5,'#AA1B13'], ## health
                                [0.75, '#69178C'], ## environmentla
                                [1, '#DE9733']]),  ## animal rights
        dimensions = list([
            dict(range = [70,100],
                 constraintrange = [93,100],
                label = 'Charity Navigator Rating', values = df['Rating']),
            dict(range = [10000000, 800000000],
                label = 'Annual Contribution', values = df['Annual Contributions']),
            dict(range = [55,90],
                label = 'Revenue Percent to Programs', values = df['Program Expenses']),
            dict(range = [0,0.4],
                label = 'Fundraising Efficiency', values = df['Efficiency']),
            dict(range = [75, 100],
                label = 'Transparency', values = df['Accountability and Transparency']),
            dict(range = [0, 1.2],
                label = 'CEO Compensation Percent', values = df['CEO Comp Percent']),
            dict(range = [15000, 775000],
                label = 'CEO Compensation (Actual)', values = df['CEO Compensation'])
        ]),
            showlegend = True
    )
]


Finally, I end up with some minor cosmetic edits and code to annotate the labels at the bottom of the page. The last two lines send the data and visual over to plotly for online hosting.

layout = go.Layout(
    autosize=False,
    width=1600,
    height=800,
    plot_bgcolor = '#E5E5E5',
    paper_bgcolor = '#E5E5E5',

    title='Charity Comparison Plot'
)

# Categorical Labels
labels = [
        dict(xref='paper', yref='paper', x=0.35, y=-0.085,
                              xanchor='center', yanchor='top',
                              text="Health",
                              font=dict(family='Arial',
                                        size=14,
                                        color='#AA1B13'),
                              showarrow=False),
        dict(xref='paper', yref='paper', x=0.5, y=-0.085,
                              xanchor='center', yanchor='top',
                              text="Social Services",
                              font=dict(family='Arial',
                                        size=14,
                                        color='#6C9E12'),
                              showarrow=False),
        dict(xref='paper', yref='paper', x=0.65, y=-0.085,
                              xanchor='center', yanchor='top',
                              text="Humanitarian",
                              font=dict(family='Arial',
                                        size=14,
                                        color='#0D5F67'),
                              showarrow=False),
        dict(xref='paper', yref='paper', x=0.20, y=-0.085,
                              xanchor='center', yanchor='top',
                              text="Environmental",
                              font=dict(family='Arial',
                                        size=14,
                                        color='#69178C'),
                              showarrow=False),
        dict(xref='paper', yref='paper', x=0.80, y=-0.085,
                              xanchor='center', yanchor='top',
                              text="Animal Rights",
                              font=dict(family='Arial',
                                        size=14,
                                        color='#DE9733'),
                              showarrow=False)

        ]
layout['annotations'] = labels

# print the plot
fig = go.Figure(data = data, layout = layout)
py.iplot(fig, filename = 'Charity_Rough')



The Final Visual

Click the image to go to the interactive version! (And try selecting different segments of the y axes) Plotly Visual