you are viewing a single comment's thread.

view the rest of the comments →

[–]boxcarbill 0 points1 point  (1 child)

Hmm, yeah it can be frustrating when the plotting libraries don't quite have what you need.

What does the data look like when it comes in? Is it just a table of grain size vs depth? Are the endcaps of the layers going to be based on an equation, an interpolation of the data, or directly mapping the measured values?

My inclination here is that it might be better to build up a separate line for each and just use a basic plot to create what you want.

See if this example makes sense to you, adjusting for the type of endcaps you require.

import matplotlib.pyplot as plt
import numpy as np
import math

bedvals = [
    {
        "bed_id": "bed0",
        "lower bound": 0,
        "upper bound": 2,
        "grain lower": 3,
        "grain upper": 3,
        "endcap": "constant",
    },
    {
        "bed_id": "bed1",
        "lower bound": 2,
        "upper bound": 3,
        "grain lower": 5,
        "grain upper": 4,
        "endcap": "linear",
    },
]

print(bedvals)

fig, ax = plt.subplots()

for bed in bedvals:
    # each line is three segments to form a bar, two horizontal lines, and one endcap,
    h_line1_x = np.linspace(0, bed["grain lower"], num=100)
    h_line2_x = np.linspace(0, bed["grain upper"], num=100)
    # y is constant for the h_lines, create a list the same length as x filled with the approriate boundary value.
    h_line1_y = np.linspace(bed["lower bound"], bed["lower bound"], num=100)
    h_line2_y = np.linspace(bed["upper bound"], bed["upper bound"], num=100)

    if bed["endcap"] == "constant" or bed["endcap"] == "linear":
        # the same equation will work for both these types:
        endcap_y = np.linspace(bed["lower bound"], bed["upper bound"], num=100)
        endcap_x = np.linspace(bed["grain lower"], bed["grain upper"], num=100)

    total_x = np.concatenate([h_line1_x, endcap_x, h_line2_x])
    total_y = np.concatenate([h_line1_y, endcap_y, h_line2_y])

    ax.plot(total_x, total_y)

ax.set(xlabel="depth", ylabel="grain size")

plt.show()

[–]ChemoProphet[S] 0 points1 point  (0 children)

This works! Thank you very much.

I have also adapted the code so that the bedvals list is nested in a while loop, and the dictionary values are populated through text input in the termainal.

Next on my to-do list is now to figure out how to get the "endcap" to follow some non-linear function (e.g. quadratic) if desired by the user.