Plot quantized, binned data from pandas value_counts given intervals and counts

Viewed 26

I'm trying to create a bar chart in python using Pandas value_counts as the output. For background, the data are temperature measurements from a forest fire dataset. Below is the code I'm using to get bin_counts (which is a Series object)

def discretizeData(cur_dataset, col_name, num_bins, bin_opts):
    '''
    cur_dataset: dataset containing values to be discretized
    col_name: column name for discretization
    bin_opts: array, containing either single value for number of bins, or 
    discretization_type: type of discretization (either 'equal-width' or 'equal-frequency')
    '''
    
    # Select specific data column for binning
    data_to_bin = cur_dataset[col_name]
    
    # Choose between equal width or equal frequency
    if bin_opts=='equal-frequency':
        # If "equal-frequency", we want to use the pandas qcut option for binning
        binned_data = pd.qcut(data_to_bin, q=num_bins)
    else:
        # Use equl-width instead
        binned_data = pd.cut(data_to_bin, bins=num_bins)
    
    # Get the bin counts to return; this will be more useful
    bin_counts = binned_data.value_counts().sort_index()
    
    return bin_counts

Here's an example of running that function using the equal frequency binning option:

fires = dataset_dict['forestfires']
col_name = 'temp'
num_bins = 5
bin_opts='equal-frequency'

The output is a Pandas Series objects with an Interval object as index, and count for that interval as column values. It looks like this:

    Equal Frequency Binning Example:
(2.1990000000000003, 14.42]    104
(14.42, 17.9]                  104
(17.9, 20.6]                   106
(20.6, 23.58]                   99
(23.58, 33.3]                  104
Name: temp, dtype: int64

I tried also converting this to a Pandas DataFrame, using bin_width as one column and count as a second, but I can't find any plotting libraries that can handle intervals. I've tried matplotlib and plotly. Any suggestions?

1 Answers

You need to plot manually:

df = pd.DataFrame({'value': np.random.normal(10,size=1000)})

counts = discretizeData(df, 'value', 10, 'equal-frequency')

plt.bar([x.left for x in counts.index], counts, width=[x.right - x.left for x in counts.index])

Output:

enter image description here

Related