Beispiel #1
0
def compchart_2dbarchart_jsonlogdata(settings, dataset):
    """This function is responsible for creating bar charts that compare data."""

    dataset_types = shared.get_dataset_types(dataset)
    data = shared.get_record_set_improved(settings, dataset, dataset_types)

    # pprint.pprint(data)

    fig, (ax1, ax2) = plt.subplots(nrows=2,
                                   gridspec_kw={"height_ratios": [7, 1]})
    ax3 = ax1.twinx()
    fig.set_size_inches(10, 6)

    #
    # Puts in the credit source (often a name or url)
    supporting.plot_source(settings, plt, ax1)
    supporting.plot_fio_version(settings, data["fio_version"][0], plt, ax1)

    ax2.axis("off")

    return_data = create_bars_and_xlabels(settings, data, ax1, ax3)
    rects1 = return_data["rects1"]
    rects2 = return_data["rects2"]
    ax1 = return_data["ax1"]
    ax3 = return_data["ax3"]
    #
    # Set title
    settings["type"] = ""
    settings["iodepth"] = dataset_types["iodepth"]
    if settings["rw"] == "randrw":
        supporting.create_title_and_sub(settings, plt, skip_keys=["iodepth"])
    else:
        supporting.create_title_and_sub(settings, plt, skip_keys=[])

    #
    # Labeling the top of the bars with their value
    shared.autolabel(rects1, ax1)
    shared.autolabel(rects2, ax3)

    tables.create_stddev_table(settings, data, ax2)

    if settings["show_cpu"] and not settings["show_ss"]:
        tables.create_cpu_table(settings, data, ax2)

    if settings["show_ss"] and not settings["show_cpu"]:
        tables.create_steadystate_table(settings, data, ax2)

    # Create legend
    ax2.legend(
        (rects1[0], rects2[0]),
        (data["y1_axis"]["format"], data["y2_axis"]["format"]),
        loc="center left",
        frameon=False,
    )

    #
    # Save graph to PNG file
    #
    supporting.save_png(settings, plt, fig)
Beispiel #2
0
def chart_latency_histogram(settings, dataset):
    """This function is responsible to draw the 2D latency histogram,
    (a bar chart)."""

    record_set = shared.get_record_set_histogram(settings, dataset)

    # We have to sort the data / axis from low to high
    sorted_result_ms = sort_latency_data(record_set["data"]["latency_ms"])
    sorted_result_us = sort_latency_data(record_set["data"]["latency_us"])
    sorted_result_ns = sort_latency_data(record_set["data"]["latency_ns"])

    # This is just to use easier to understand variable names
    x_series = sorted_result_ms["keys"]
    y_series1 = sorted_result_ms["values"]
    y_series2 = sorted_result_us["values"]
    y_series3 = sorted_result_ns["values"]

    # us/ns histogram data is missing 2000/>=2000 fields that ms data has
    # so we have to add dummy data to match x-axis size
    y_series2.extend([0, 0])
    y_series3.extend([0, 0])

    # Create the plot
    fig, ax1 = plt.subplots()
    fig.set_size_inches(10, 6)

    # Make the positioning of the bars for ns/us/ms
    x_pos = np.arange(0, len(x_series) * 3, 3)
    width = 1

    # how much of the IO falls in a particular latency class ns/us/ms
    coverage_ms = round(sum(y_series1), 2)
    coverage_us = round(sum(y_series2), 2)
    coverage_ns = round(sum(y_series3), 2)

    # Draw the bars
    rects1 = ax1.bar(x_pos, y_series1, width, color="r")
    rects2 = ax1.bar(x_pos + width, y_series2, width, color="b")
    rects3 = ax1.bar(x_pos + width + width, y_series3, width, color="g")

    # Configure the axis and labels
    ax1.set_ylabel("Percentage of I/O")
    ax1.set_xlabel("Latency")
    ax1.set_xticks(x_pos + width / 2)
    ax1.set_xticklabels(x_series)

    # Make room for labels by scaling y-axis up (max is 100%)
    ax1.set_ylim(0, 100 * 1.1)

    label_ms = "Latency in ms ({0:05.2f}%)".format(coverage_ms)
    label_us = "Latency in us  ({0:05.2f}%)".format(coverage_us)
    label_ns = "Latency in ns  ({0:05.2f}%)".format(coverage_ns)

    # Configure the title
    settings["type"] = ""
    supporting.create_title_and_sub(settings, plt, ["type", "filter"])
    # Configure legend
    ax1.legend(
        (rects1[0], rects2[0], rects3[0]),
        (label_ms, label_us, label_ns),
        frameon=False,
        loc="best",
    )

    # puts a percentage above each bar (ns/us/ms)
    autolabel(rects1, ax1)
    autolabel(rects2, ax1)
    autolabel(rects3, ax1)

    supporting.plot_source(settings, plt, ax1)
    supporting.plot_fio_version(settings, record_set["fio_version"], plt, ax1)

    # if settings['source']:
    #    sourcelength = len(settings['source'])
    #    offset = 1.0 - sourcelength / 120
    #    fig.text(offset, 0.03, settings['source'])
    #
    # Save graph to PNG file
    #
    supporting.save_png(settings, plt, fig)
Beispiel #3
0
def chart_2d_log_data(settings, dataset):
    #
    # Raw data must be processed into series data + enriched
    #
    data = supporting.process_dataset(settings, dataset)
    datatypes = data["datatypes"]
    directories = logdata.get_unique_directories(dataset)

    # pprint.pprint(data)
    #
    # Create matplotlib figure and first axis. The 'host' axis is used for
    # x-axis and as a basis for the second and third y-axis
    #
    fig, host = plt.subplots()
    fig.set_size_inches(9, 5)
    plt.margins(0)
    #
    # Generates the axis for the graph with a maximum of 3 axis (per type of
    # iops,lat,bw)
    #
    axes = supporting.generate_axes(host, datatypes)
    #
    # Create title and subtitle
    #
    supporting.create_title_and_sub(settings, plt)

    #
    # The extra offsets are requred depending on the size of the legend, which
    # in turn depends on the number of legend items.
    #
    if settings["colors"]:
        support2d.validate_colors(settings["colors"])

    extra_offset = (len(datatypes) * len(settings["iodepth"]) *
                    len(settings["numjobs"]) * len(settings["filter"]))

    bottom_offset = 0.18 + (extra_offset / 120)
    if "bw" in datatypes and (len(datatypes) > 2):
        #
        # If the third y-axis is enabled, the graph is ajusted to make room for
        # this third y-axis.
        #
        fig.subplots_adjust(left=0.21)

    try:
        fig.subplots_adjust(bottom=bottom_offset)
    except ValueError as v:
        print(f"\nError: {v} - probably too many lines in the graph.\n")
        sys.exit(1)

    supportdata = {
        "lines": [],
        "labels": [],
        "colors": support2d.get_colors(settings),
        "marker_list": list(markers.MarkerStyle.markers.keys()),
        "fontP": FontProperties(family="monospace"),
        "maximum": supporting.get_highest_maximum(settings, data),
        "axes": axes,
        "host": host,
        "maxlabelsize": support2d.get_max_label_size(settings, data,
                                                     directories),
        "directories": directories,
    }

    supportdata["fontP"].set_size("xx-small")

    #
    # Converting the data and drawing the lines
    #
    for item in data["dataset"]:
        for rw in settings["filter"]:
            if rw in item.keys():
                support2d.drawline(settings, item, rw, supportdata)

    #
    # Generating the legend
    #
    values, ncol = support2d.generate_labelset(settings, supportdata)

    host.legend(
        supportdata["lines"],
        values,
        prop=supportdata["fontP"],
        bbox_to_anchor=(0.5, -0.18),
        loc="upper center",
        ncol=ncol,
        frameon=False,
    )

    def get_axis_for_label(axes):
        axis = list(axes.keys())[0]
        ax = axes[axis]
        return ax

    #
    # A ton of work to get the Fio-version from .json output if it exists.
    #
    jsondata = support2d.get_json_data(settings)
    ax = get_axis_for_label(axes)
    if jsondata[0]["data"] and not settings["disable_fio_version"]:
        fio_version = jsondata[0]["data"][0]["fio_version"]
        supporting.plot_fio_version(settings, fio_version, plt, ax, -0.12)
    else:
        supporting.plot_fio_version(settings, None, plt, ax, -0.12)

    #
    # Print source
    #
    ax = get_axis_for_label(axes)
    supporting.plot_source(settings, plt, ax, -0.12)

    #
    # Save graph to PNG file
    #
    supporting.save_png(settings, plt, fig)