Source code for pycafee.normalitycheck.dotplot

"""
desc
"""

##########################################
################ Summmary ################
##########################################



#########################################
################ Imports ################
#########################################

###### Standard ######



###### Third part ######
import matplotlib.pyplot as plt
import numpy as np



###### Home made ######
from pycafee.database_management import management
from pycafee.utils.helpers import PlotsManagement, LanguageManagement
from pycafee.utils import checkers
from pycafee.utils import general
from pycafee.utils import helpers
###########################################
################ Functions ################
###########################################


[docs]class DotPlot(PlotsManagement, LanguageManagement): def __init__(self, language=None, **kwargs): super().__init__(language=language,**kwargs) # with tests, with text, with docstring, with database
[docs] def draw(self, x_exp, ax=None, legend_label=None, x_label=None, width='auto', height='auto', export=None, file_name=None, extension=None, dpi=None, tight=None, transparent=None, n_ticks=None, legend=None, decimal_separator=None): """This function draws a dot plot with a predefined design Parameters ---------- x_exp : 1D :doc:`numpy array <numpy:reference/generated/numpy.array>` A ``1`` dimension numpy array with the dataset ax : ``None`` or ``matplotlib.axes.SubplotBase`` * If ``ax`` is ``None``, a figure is created with a preset design. The other parameters can be used to edit and export the graph. * If ``ax`` is a ``matplotlib.axes.SubplotBase``, the function returns a ``matplotlib.axes.SubplotBase`` with the dotplot axis. In this case, parameters relatd to wht ``fig`` will not affect the graph. legend : ``bool``, optional Whether the legend should be add into the chart (``True``) or not (``False``). The default value is ``None``, which implies ``False``. legend_label : ``str``, optional The label to be displayed on the legend. Default is ``None``, which results in ``"data"``. Only valid if ``legend = True``. x_label : ``str``, optional The label to be displayed on x label. Default is ``None``, which results in a blank label. width : ``"auto"``, ``"default"``, ``int`` or ``float`` (positive), optional The ``width`` of the figure. * If it is ``"auto"``, it tries to figure out a nice ``width`` for the plot using the data range. * If it is ``"default"``, it uses a pre-defined value. * If it is a number, it defines the ``width`` of the chart (in inches). height : ``"auto"``, ``"default"``, ``int`` or ``float`` (positive), optional The ``height`` of the figure. * If it is ``"auto"``, it tries to figure out a nice height for the plot using the data range. * If it is ``"default"``, it uses a pre-defined value. * If it is a number, it defines the height of the chart (in inches). export : ``bool``, optional Whether the graph should be exported (``True``) or not (``False``). The default value is ``None``, which implies ``False``. file_name : ``str``, optional The file name. Default is ``None`` which results in a file named ``"dot_plot"``. extension : ``str``, optional The file extension without a dot. Default is ``None`` which results in a ``".png"`` file. dpi : ``int`` or ``float`` (positive), optional The figure pixel density. The default is ``None``, which results in a ``100 dpis`` picture. This parameter must be a positive number. n_ticks : ``int`` (positive), optional The number of evenly spaced ticks to be drawn on the x-axis. The default is ``None``, which uses matplotlib default parameter. tight : ``bool``, optional Whether the graph should be tight (``True``) or not (``False``). The default value is ``None``, which implies ``True``. transparent : ``bool``, optional Whether the background of the graph should be transparent (``True``) or not (``False``). The default value is ``None``, which implies ``False`` (e.g, white background). decimal_separator : ``str``, optional The decimal separator symbol used in the chart. It can be the dot (``None`` or ``"."``) or the comma (``","``). Returns ------- x : :doc:`numpy array <numpy:reference/generated/numpy.array>` The ``x`` values used to plot the graph. y : :doc:`numpy array <numpy:reference/generated/numpy.array>` The ``y`` values used to plot the graph. axes : ``matplotlib.axes._subplots.AxesSubplot`` The axis of the graph. See Also -------- pycafee.normalitycheck.densityplot.DensityPlot.draw References ---------- .. [1] Inspired by FITZGERALD, P. How to create a “dot plot” in Matplotlib? (not a scatter plot). Available at: `stackoverflow.com <https://stackoverflow.com/questions/49703938/how-to-create-a-dot-plot-in-matplotlib-not-a-scatter-plot/64943404#64943404>`_. Access on: 10 May. 2022. Examples -------- **Drawing a dot plot with default parameters** >>> from pycafee.normalitycheck.dotplot import DotPlot >>> import numpy as np >>> x = np.array([ 5.1, 4.9, 4.7, 4.6, 5.0, 5.4, 4.6, 5.0, 4.4, 4.9, 5.4, 4.8, 4.8, 4.3, 5.8, 5.7, 5.4, 5.1, 5.7, 5.1, 5.4, 5.1,4.6, 5.1, 4.8, 5.0, 5.0, 5.2, 5.2, 4.7, 4.8, 5.4, 5.2, 5.5, 4.9, 5.0, 5.5, 4.9, 4.4, 5.1, 5.0, 4.5, 4.4, 5.0, 5.1,4.8, 5.1, 4.6, 5.3, 5.0 ]) >>> dotplot = DotPlot() >>> x, y, axes = dotplot.draw(x, ax=None, export=True) The 'dot_plot.png' file was exported! .. image:: img/dot_plot.png :alt: Graph showing the dot plot :align: center | **Drawing a dot plot** >>> from pycafee.normalitycheck.dotplot import DotPlot >>> import numpy as np >>> x = np.array([ 5.1, 4.9, 4.7, 4.6, 5.0, 5.4, 4.6, 5.0, 4.4, 4.9, 5.4, 4.8, 4.8, 4.3, 5.8, 5.7, 5.4, 5.1, 5.7, 5.1, 5.4, 5.1,4.6, 5.1, 4.8, 5.0, 5.0, 5.2, 5.2, 4.7, 4.8, 5.4, 5.2, 5.5, 4.9, 5.0, 5.5, 4.9, 4.4, 5.1, 5.0, 4.5, 4.4, 5.0, 5.1,4.8, 5.1, 4.6, 5.3, 5.0 ]) >>> dotplot = DotPlot() >>> x, y, axes = dotplot.draw(x, ax=None, export=True, file_name="my_data", decimal_separator=",", n_ticks=6, x_label='comprimento das sépalas ($cm$)') The 'my_data.png' file was exported! .. image:: img/my_data.png :alt: Graph showing the dot plot :align: center | **Drawing a dot plot using a previously created figure** >>> from pycafee.normalitycheck.dotplot import DotPlot >>> import numpy as np >>> import matplotlib.pyplot as plt >>> x = np.array([ 5.1, 4.9, 4.7, 4.6, 5.0, 5.4, 4.6, 5.0, 4.4, 4.9, 5.4, 4.8, 4.8, 4.3, 5.8, 5.7, 5.4, 5.1, 5.7, 5.1, 5.4, 5.1,4.6, 5.1, 4.8, 5.0, 5.0, 5.2, 5.2, 4.7, 4.8, 5.4, 5.2, 5.5, 4.9, 5.0, 5.5, 4.9, 4.4, 5.1, 5.0, 4.5, 4.4, 5.0, 5.1,4.8, 5.1, 4.6, 5.3, 5.0 ]) >>> dotplot = DotPlot() >>> fig, ax = plt.subplots(figsize=(8,4)) >>> x, y, ax = dotplot.draw(x, ax=ax) >>> plt.savefig("new_plot.png") >>> plt.show() .. image:: img/new_plot.png :alt: Graph showing the dot plot :align: center """ ### Checking the input parameters ### ## x_exp ## checkers._check_is_numpy_1_D(x_exp, "x_exp", self.language) ## legend_label ## legend_label = self._get_default_legend_label(legend_label) ## width ## if width == 'auto': width = None else: width = self._get_default_width(width) ## height ## if height == 'auto': height = None else: height = self._get_default_height(height) ## export ## export = self._get_default_export(export) ## file name ## if file_name is None: file_name = "dot_plot" else: checkers._check_is_str(file_name, "file_name", self.language) helpers._check_forbidden_character(file_name, "file_name", self.language) ## extension ## extension = self._get_default_extension(extension) ## dpi ## dpi = self._get_default_dpi(dpi) ## n_ticks ## if n_ticks is not None: checkers._check_is_integer(n_ticks, "n_ticks", self.language) ## tight ## tight = self._get_default_tight(tight) ## transparent ## transparent = self._get_default_transparent(transparent) ## Legend ## if legend is None: legend = False else: legend = self._get_default_legend(legend) ## decimal_separator ## decimal_separator = self._get_default_decimal_separator(decimal_separator) checkers._check_is_str(decimal_separator, "decimal_separator", self.language) helpers._check_decimal_separator(decimal_separator, self.language) ## This was removed due to local issue on colab ## ## local ## # local = self._get_default_local(local) ### drawing the graph ### ## counting the number of unique values within x_exp ## values, counts = np.unique(x_exp, return_counts=True) ## formatting the chart according to the data ## data_range = max(values) - min(values) # width # if width is None: if data_range < 10: width = 4 elif data_range < 30: width = data_range/2 else: width = 8 else: pass # height # if height is None: if data_range < 50: height = max(counts)/4 else: height = max(counts)/2 else: pass if width is not None or height is not None: if data_range < 50: marker_size = 40 else: marker_size = np.ceil(200 / (data_range//10)) else: marker_size = None ## This was removed due to local issue on colab ## # cheking the decimal_separator # # default_locale = helpers._change_locale(self.language, decimal_separator, local) # lists to export the data # axis_x = [] axis_y = [] # making the data # for value, count in zip(values, counts): axis_x.append([value]*count) axis_y.append(list(range(count))) # flating the data into one dimension array # x = np.array(helpers._flat_list_of_lists(axis_x, "axis_x", self.language)) y = np.array(helpers._flat_list_of_lists(axis_y, "axis_y", self.language)) ## Createing the dot plot with format ## if ax is None: fig, axes = plt.subplots(figsize=(width, height)) else: checkers._check_is_subplots(ax, "ax", self.language) axes = ax # ploting the data # axes.scatter(x, y, marker='o', c="None", edgecolors="k", s=marker_size, label=legend_label) # removing spines # for spine in ['top', 'right', 'left']: axes.spines[spine].set_visible(False) # improving y axis # axes.yaxis.set_visible(False) axes.set_ylim(-1, max(counts)) # formatting the axes # if n_ticks is None: pass else: ticks = np.linspace(min(values), max(values), n_ticks)#, dtype=int) axes.set_xticks(ticks) axes.tick_params(axis='x', length=5, pad=5) # legend # if legend: axes.legend() # decimal separator if ax is None: axes = helpers._change_decimal_separator_x_axis(fig, axes, decimal_separator) # x label # if x_label is not None: axes.set_xlabel(x_label) if ax is None: # making the graph "tight" # if tight: tight = 'tight' fig.tight_layout() else: tight = None # exporting the plot # if export: ### Baptism of Fire ### exits, file_name = helpers._check_conflicting_filename(file_name, extension, self.language) plt.savefig(file_name, dpi=dpi, transparent=transparent, bbox_inches=tight) ### quering ### if exits == False: func_name = "draw_density_function" # reaproveitando database fk_id_function = management._query_func_id(func_name) messages = management._get_messages(fk_id_function, self.language, func_name) general._display_one_line_success(f"{messages[1][0][0]} '{file_name}' {messages[1][2][0]}") # showing the plot # plt.show() ## This was removed due to local issue on colab ## # helpers._change_locale_back_to_default(default_locale) return x, y, axes
#