import numpy as np from numpy import genfromtxt from numpy import isnan import matplotlib.pyplot as plt import sys # see the below link for example of producing these plots: # https://stackoverflow.com/questions/59702884/plot-rgb-values-with-matplotlib ''' This script will take as input a file name (including path). The input file is a csv file of the following format: 0 141 62 88 0.67 107 58 83 0.6 97 56 78 0.77 106 66 90 0.97 110 68 94 1.17 112 68 94 1.37 100 56 80 1.57 104 63 85 1.67 106 62 85 1.8 100 56 79 1.94 86 52 72 2.11 98 56 59 2.25 105 62 85 e.g. four columns, the 1st is the variable data point, the 'x' axis the 2nd, 3rd, 4th columns are the colour of the data point as three RGB integers The script will also accept an image size parameter, defaulted if missing. The input csv data is used to create an array of length image size, populated proportionally from the input data. The resulting data is an array of RGB values: a line of colours. These are then passed to matplotlib.pyplot.imshow, which displays the line of colours as a 2D image, similar to a bar code. The plotted image is saved as an image file, with the same name as the input, but with the .csv replaced with .png ''' def convert_csv_to_rgb_and_plot(input_file, image_size, hide_axis_labels=True): output_image = input_file.replace(".csv", ".png")[0:] print('input:', input_file) print('output:', output_image) rgb_array = genfromtxt(input_file, delimiter=',') # clean up the data: zeros in Excel csv's come in a '0' and often don't convert into a python float nan_rows = isnan(rgb_array) rgb_array[nan_rows] = 0. # calculate the multipliers from each input point to each output pixel value_range = np.ptp(rgb_array[:, [0]], axis=0)[0] value_min = np.min(rgb_array[:, [0]], axis=0)[0] value_max = np.max(rgb_array[:, [0]], axis=0)[0] multiplier = image_size / value_max # apply the multipliers rgb_array[:, [0]] = rgb_array[:, [0]] * multiplier last_but_1 = rgb_array[-2] last = rgb_array[-1] last_diff = int(last[0] - last_but_1[0]) image_size = image_size + last_diff # create an array of zeros image_array = np.zeros((1, image_size, 3), dtype=int) # populate the image_array using the calculated values from the input array curr_image_index = 0 for index in range(0, len(rgb_array) - 1): # todo last point isn't plotted, so extend the image_array so we can plot the last point range_index = int(rgb_array[index + 1, [0]]) for image_index in range(curr_image_index, range_index): assign_image_row(image_array, image_index, index, rgb_array) curr_image_index = range_index # and fill out the last section of the image since not covered by loop above for image_index in range(curr_image_index, image_size): assign_image_row(image_array, image_index, len(rgb_array) - 1, rgb_array) # display the 1d line of rgb values as a 2d image plt.imshow(image_array, extent=[0, value_max, 0, 1], aspect='auto') if hide_axis_labels: plt.axis('off') plt.savefig(output_image) plt.show() def assign_image_row(image_array, image_index, index, rgb_array): image_array[0, image_index, 0] = int(rgb_array[index, 1]) image_array[0, image_index, 1] = int(rgb_array[index, 2]) image_array[0, image_index, 2] = int(rgb_array[index, 3]) if __name__ == "__main__": if len(sys.argv) < 2: print('Please pass the csv file name including path, image size is optional') else: file_path = sys.argv[1] image_size = 3000 hide_axis_labels = True if len(sys.argv) > 2: image_size = int(sys.argv[2]) if len(sys.argv) > 3: str_hide = sys.argv[3] if str_hide == 'False': hide_axis_labels = False print('Generating image for',file_path,'with size',image_size) convert_csv_to_rgb_and_plot(file_path, image_size, hide_axis_labels)