Skip to content

Commit

Permalink
feat: added normal plot for time series (#550)
Browse files Browse the repository at this point in the history
Closes #549 

### Summary of Changes

Add more plot for time series:

* ```TimeSeries.plot_lineplot```
* ```TimeSeries.plot_scatterplot```

---------

Co-authored-by: megalinter-bot <129584137+megalinter-bot@users.noreply.github.com>
Co-authored-by: Lars Reimann <mail@larsreimann.com>
  • Loading branch information
3 people authored Mar 5, 2024
1 parent 3415045 commit dbdf11e
Show file tree
Hide file tree
Showing 13 changed files with 679 additions and 1 deletion.
150 changes: 149 additions & 1 deletion src/safeds/data/tabular/containers/_time_series.py
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@

import matplotlib.pyplot as plt
import pandas as pd
import seaborn as sns

from safeds.data.image.containers import Image
from safeds.data.tabular.containers import Column, Row, Table, TaggedTable
Expand Down Expand Up @@ -36,7 +37,7 @@ def _from_tagged_table(
Parameters
----------
table : TaggedTable
tagged_table: TaggedTable
The tagged table.
time_name: str
Name of the time column.
Expand Down Expand Up @@ -906,3 +907,150 @@ def plot_lagplot(self, lag: int) -> Image:
plt.close() # Prevents the figure from being displayed directly
buffer.seek(0)
return Image.from_bytes(buffer.read())

def plot_lineplot(self, x_column_name: str | None = None, y_column_name: str | None = None) -> Image:
"""
Plot the time series target or the given column(s) as line plot.
The function will take the time column as the default value for y_column_name and the target column as the
default value for x_column_name.
Parameters
----------
x_column_name:
The column name of the column to be plotted on the x-Axis, default is the time column.
y_column_name:
The column name of the column to be plotted on the y-Axis, default is the target column.
Returns
-------
plot:
The plot as an image.
Raises
------
NonNumericColumnError
If the time series given columns contain non-numerical values.
UnknownColumnNameError
If one of the given names does not exist in the table
Examples
--------
>>> from safeds.data.tabular.containers import TimeSeries
>>> table = TimeSeries({"time":[1, 2], "target": [3, 4], "feature":[2,2]}, target_name= "target", time_name="time", feature_names=["feature"], )
>>> image = table.plot_lineplot()
"""
self._data.index.name = "index"
if x_column_name is not None and not self.get_column(x_column_name).type.is_numeric():
raise NonNumericColumnError("The time series plotted column contains non-numerical columns.")

if y_column_name is None:
y_column_name = self.target.name

elif y_column_name not in self._data.columns:
raise UnknownColumnNameError([y_column_name])

if x_column_name is None:
x_column_name = self.time.name

if not self.get_column(y_column_name).type.is_numeric():
raise NonNumericColumnError("The time series plotted column contains non-numerical columns.")

fig = plt.figure()
ax = sns.lineplot(
data=self._data,
x=x_column_name,
y=y_column_name,
)
ax.set(xlabel=x_column_name, ylabel=y_column_name)
ax.set_xticks(ax.get_xticks())
ax.set_xticklabels(
ax.get_xticklabels(),
rotation=45,
horizontalalignment="right",
) # rotate the labels of the x Axis to prevent the chance of overlapping of the labels
plt.tight_layout()

buffer = io.BytesIO()
fig.savefig(buffer, format="png")
plt.close() # Prevents the figure from being displayed directly
buffer.seek(0)
self._data = self._data.reset_index()
return Image.from_bytes(buffer.read())

def plot_scatterplot(
self,
x_column_name: str | None = None,
y_column_name: str | None = None,
) -> Image:
"""
Plot the time series target or the given column(s) as scatter plot.
The function will take the time column as the default value for x_column_name and the target column as the
default value for y_column_name.
Parameters
----------
x_column_name:
The column name of the column to be plotted on the x-Axis.
y_column_name:
The column name of the column to be plotted on the y-Axis.
Returns
-------
plot:
The plot as an image.
Raises
------
NonNumericColumnError
If the time series given columns contain non-numerical values.
UnknownColumnNameError
If one of the given names does not exist in the table
Examples
--------
>>> from safeds.data.tabular.containers import TimeSeries
>>> table = TimeSeries({"time":[1, 2], "target": [3, 4], "feature":[2,2]}, target_name= "target", time_name="time", feature_names=["feature"], )
>>> image = table.plot_scatterplot()
"""
self._data.index.name = "index"
if x_column_name is not None and not self.get_column(x_column_name).type.is_numeric():
raise NonNumericColumnError("The time series plotted column contains non-numerical columns.")

if y_column_name is None:
y_column_name = self.target.name
elif y_column_name not in self._data.columns:
raise UnknownColumnNameError([y_column_name])
if x_column_name is None:
x_column_name = self.time.name

if not self.get_column(y_column_name).type.is_numeric():
raise NonNumericColumnError("The time series plotted column contains non-numerical columns.")

fig = plt.figure()
ax = sns.scatterplot(
data=self._data,
x=x_column_name,
y=y_column_name,
)
ax.set(xlabel=x_column_name, ylabel=y_column_name)
ax.set_xticks(ax.get_xticks())
ax.set_xticklabels(
ax.get_xticklabels(),
rotation=45,
horizontalalignment="right",
) # rotate the labels of the x Axis to prevent the chance of overlapping of the labels
plt.tight_layout()

buffer = io.BytesIO()
fig.savefig(buffer, format="png")
plt.close() # Prevents the figure from being displayed directly
buffer.seek(0)
self._data = self._data.reset_index()
return Image.from_bytes(buffer.read())
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading

0 comments on commit dbdf11e

Please sign in to comment.