# Copyright 2021 IRT Saint Exupéry, https://www.irt-saintexupery.com
#
# This work is licensed under a BSD 0-Clause License.
#
# Permission to use, copy, modify, and/or distribute this software
# for any purpose with or without fee is hereby granted.
#
# THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL
# WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED
# WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL
# THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT,
# OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING
# FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT,
# NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION
# WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
"""
Customize with matplotlib
=========================

In this example,
we will see how to modify the matplotlib figures generated by a :class:`.DatasetPlot`.
This can be useful to finely tune a graph for a presentation or a paper.
"""

from __future__ import annotations

from matplotlib import pyplot as plt

from gemseo.datasets.dataset import Dataset
from gemseo.post.dataset.yvsx import YvsX

# %%
# First,
# we build a simple :class:`.Dataset`
# containing a cloud of points ``((1, 1), (2, 0), (3, 1))`` of the tuple ``("a", "b")``.
dataset = Dataset()
dataset.add_variable("a", [[1], [2], [3]])
dataset.add_variable("b", [[1], [0], [1]])

# %%
# Then,
# we define a :class:`YvsX` chart, which is a particular :class:`.DatasetPlot`:
yvsx = YvsX(dataset, "a", "b")

# %%
# and draw the figure.
figures = yvsx.execute(save=False)

# %%
# By default,
# the horizontal and vertical labels are the names of the variables,
# namely ``"a"`` and ``"b"`` in this example.
# As these labels are not so relevant,
# we are going to modify this figure directly with matplotlib
# instead of saving it.
# For that,
# we get the matplotlib ``Axes`` of the matplotlib ``Figure``:
figure = figures[0]
ax = figure.axes[0]

# %%
# and change the labels:
ax.set_xlabel("A relevant x-label")
ax.set_ylabel("A relevant y-label")

# %%
# We can also add a grid:
ax.grid()

# %%
# Lastly,
# we can save the figure with matplotlib
plt.savefig("foo.png")

# %%
# and display it:
plt.show()

# %%
# Note that in this pedagogical example,
# we modified basic properties of the chart
# which could have been modified with the attributes of ``DatasetPlot``,
# e.g. ``yvsx.xlabel = "A relevant x-label"``.
# But it is impossible to add attributes or methods for all the features of matplotlib.
# It is therefore advisable to check if an attribute of :class:`.DatasetPlot` can help
# and if not, access and modify the matplotlib ``Figure`` as shown here.
