Plots#

You can create your own plot from new or existing data.

import kappa_sdk as ka
from datetime import datetime

# Specify the connection configuration
ka_server_address = 'https://your-ka-instance.com'

plot_name = "Expenses by month"
connection = ka.Connection(ka_server_address, verify_ssl=False)
all_fields = connection.get_fields()

my_field = next(x for x in all_fields if x.name == "My Field")
my_well = next(x for x in my_field.wells if x.name == "My Well")
plot = my_well.create_plot(plot_name, stacked_bars=True)
months = [datetime(2024, 1, 1), datetime(2024, 2, 1), datetime(2024, 3, 1), datetime(2024, 4, 1)]
gas_channel = plot.add_embedded_data(ka.Vector(months, [30, 30, 30, 30]), channel_name="Gasoline", show_lines=False)
gas_channel.set_channel_aspect(ka.DrawingStyle.as_bar)
gas_channel.set_band_aspect(opacity=100, color="Blue")

food_channel = plot.add_embedded_data(ka.Vector(months, [170, 170, 370, 170]), channel_name="Food", show_lines=False)
food_channel.set_channel_aspect(ka.DrawingStyle.as_bar)
food_channel.set_band_aspect(opacity=100, color="Red")

rent_channel = plot.add_embedded_data(ka.Vector(months, [500, 500, 500, 500]), channel_name="Rent", show_lines=False)
rent_channel.set_channel_aspect(ka.DrawingStyle.as_bar)
rent_channel.set_band_aspect(opacity=100, color="#A2C9F1")

utilities_channel = plot.add_embedded_data(ka.Vector(months, [200, 200, 200, 200]), channel_name="Utilities", show_lines=False)
utilities_channel.set_channel_aspect(ka.DrawingStyle.as_bar)
utilities_channel.set_band_aspect(opacity=100, color="Green")
plot.update_plot()

The above script example will generate the following plot:

../_images/bar_plot.png

The previous example demonstrates working with new data through the kappa_sdk.Plot.add_embedded_data() method. However, if you need to incorporate existing data into your plot, you can leverage the kappa_sdk.Plot.add_existing_data() method instead. As this example shows, you can customise each channel as you like by changing the lines, symbols or bands appearance.

Another example:

from datetime import datetime, timedelta
import kappa_sdk as ka
import random
import numpy as np
from typing import List, Tuple


def compute_average_by_day(vector: ka.Vector) -> Tuple[List[datetime], List[float]]:
    days = np.array([date.strftime('%Y-%m-%d') for date in vector.dates])
    values = np.array(vector.values)

    unique_days_str = np.unique(days)
    unique_days = [datetime.strptime(day, '%Y-%m-%d') for day in unique_days_str]

    averages = [values[days == day].mean() for day in unique_days_str]
    return unique_days, averages


# Specify the connection configuration
ka_server_address = 'https://kubernetes-preprod.kappa.int/'

field_name = 'AB'
well_name = 'Well #1'
plot_name = "Plot "
vector_size = 10000
connection = ka.Connection(ka_server_address, verify_ssl=False)

field = next(x for x in connection.get_fields() if x.name == field_name)
well = next(x for x in field.wells if x.name == well_name)
plot = next((x for x in well.plots if x.name == plot_name), None)
if plot is not None:
    plot.delete()
plot = well.create_plot(plot_name)
days = [datetime(2024, 1, 1) + timedelta(minutes=5 * i) for i in range(vector_size)]
values = [random.uniform(0, 1) for _ in range(vector_size)]
vector = ka.Vector(days, values)
unique_days, average = compute_average_by_day(vector)

# CHANNEL EXAMPLE WITH EXISTING DATA FROM KA
# oil_rate = next(x for x in well.data if x.data_type == 'qo')
# oil_channel = plot.add_existing_data(oil_rate, channel_name="Oil Rate", show_lines=True)

# CHANNEL EXAMPLE WITH INLINE DATA
oil_channel = plot.add_embedded_data(ka.Vector(days, values), channel_name="Oil Rate", show_lines=True, y_measure=ka.MeasureEnum.liquid_rate)
oil_channel.set_symbols_aspect(color="Blue", symbol_type=ka.SymbolAspectEnum.circle)

oil_average_channel = plot.add_embedded_data(ka.Vector(unique_days, average), channel_name="Oil rates", show_symbols=False, hide_in_legend=False, y_measure=ka.MeasureEnum.liquid_rate)
oil_average_channel.set_lines_aspect(color="Orange")

missing_data_channel = plot.add_embedded_data(ka.Vector([days[100], days[200], days[500], days[800]], [0, 1, 0, 1]), channel_name="Missing Data")
missing_data_channel.set_band_aspect(color="Red", opacity=100)
missing_data_channel.set_channel_aspect(drawing_style=ka.DrawingStyle.as_vertical_line)

invalid_data_channel = plot.add_embedded_data(ka.Vector([days[1000], days[2000], days[3500], days[3800], days[4000], days[4200]], [0, 1, 0, 1, 0, 1]), channel_name="Invalid Data")
invalid_data_channel.set_band_aspect(color="Green", opacity=100)
invalid_data_channel.set_channel_aspect(drawing_style=ka.DrawingStyle.as_vertical_line)

allocation_error_channel = plot.add_embedded_data(ka.Vector([days[300], days[400], days[6000], days[8000], days[9000], days[9400]], [0, 1, 0, 1, 0, 1]), channel_name="Allocation error")
allocation_error_channel.set_band_aspect(color="Purple", opacity=100)
allocation_error_channel.set_channel_aspect(drawing_style=ka.DrawingStyle.as_vertical_line)

plot.update_plot()

This example will generate the following plot:

../_images/plot.png

Note

The last added channel will be the one visible in the foreground.