4

how do I plot a histogram in c from 2 arrays?

small_potato
  • 3,127
  • 5
  • 39
  • 45
  • Are you expecting to use nice graphics or just some **** style text? – djna Oct 01 '10 at 06:32
  • petty much ** style, nothing fancy – small_potato Oct 01 '10 at 06:33
  • 1
    Pretty good duplicate at [Frequency Histogram in C](http://stackoverflow.com/questions/1413644/); the only difference being the nature of the data. On a less serious note, you can find implementations of histogram output in several language at [Code golf: Word frequency chart](http://stackoverflow.com/questions/3169051/), but *don't* use them as they are: code golf solutions generally break all kinds of good coding standards in search of brevity. – dmckee --- ex-moderator kitten Oct 01 '10 at 06:58
  • 1
    What is the connection between the 2 arrays? – pmg Oct 01 '10 at 08:23

4 Answers4

3

You could you this character(■) to represent the count in the graph. This is a character that can be printed by

printf("%c", (char)254u);

Consider some random float_arr and hist array that hold the count.

Code

// Function generating random data
for (i = 0; i < n; i++){
    float random = ((float)rand() / (float)(RAND_MAX));
    float_arr[i] = random;
    printf("%f  ", random);
}
//Dividing float data into bins
for (i = 0; i < n; i++){
    for (j = 1; j <= bins; j++){

        float bin_max = (float)j / (float)bins;
        if (float_arr[i] <= bin_max){
            hist[j]++;
            break;
        }
    }
}
// Plotting histogram
printf("\n\nHistogram of Float data\n");
for (i = 1; i <= bins; i++)
{
    count = hist[i];
    printf("0.%d |", i - 1);
    for (j = 0; j < count; j++)
    {
        printf("%c", (char)254u);
    }
    printf("\n");
}

Output

Histogram of Float data
0.0 |■■■■■■■■■■■■■■■■■■■■■■
0.1 |■■■■■■■■■■■■■■■■
0.2 |■■■■■
0.3 |■■■■■■■■■■■■■■
0.4 |■■■■■■■■
0.5 |■■■■■■■■■■■■■■■■
0.6 |■■■■■■■■■■
0.7 |■■■■■■■
0.8 |■■■■■■■■■■■■■■■
0.9 |■■■■■■■
Hemanth Kollipara
  • 902
  • 11
  • 16
2

For a histogram layed out on its side...

I suggest using printf("*") for each increment, and printf("\n") to start outputting a new row. (Changing the orientation is an excercise to the reader).

Arafangion
  • 11,517
  • 1
  • 40
  • 72
1

You can use ascii art for that

mamamia
  • 11
  • 1
1

Thinking about the problem a bit I'm not convinced that the "duplicate" I identified in the comments is really responsive. So I'll say a few words.

If you've settled on a ASCII art approach, then you have only one more decision to make: vertical or horizontal bars. Horizontal is easy: just decide on the scaling and then print bin_contents*scale symbols for each bin. The code-golf link really is useful as a model of what to do, even if not a good example of how to write it.

However, many fields have an expectation of vertical bar in the presentation of histograms. That's a little harder, but consider the pseudocode

sacle = find_scale(input_array)
max_height = find_max(input_array) * scale
for (i=max_height; i>=0; i--) 
   if (some condition)
      print_in_N_digits(round(i/scale)) // to label the scale
   else
      print_in_N_digits()               // lines with no labels
   print " |"                           // set up the vertical axis
   for (j=first_bin to lat_bin)
      if (input[j]*scale >= i)
         print("#")
      else
         print(" ")
      print_new_line
print_in_N_digits(0)
print(" +")
for (j=first_bin to last_bin)
   print("-")
print_new_line
print_in_N_digits()
print(" 0")
for (j=first_bin to last_bin)
   if (some other condition)
      print_bin_label

This just walks across the page, using on column per bin and at each level prints either " " or "#" for each column. The histogram printing part is really very easy. All the complexity arises from managing the axis and labels.

dmckee --- ex-moderator kitten
  • 98,632
  • 24
  • 142
  • 234