Repository: ludwig-ai/ludwig

Issue:
Incorrect formatting of visualization api calls in Ludwig documentation
**Describe the bug**
Most visualization api parameters documentation are not correctly formatted.

**To Reproduce**
Example of incorrect formatting of documentation: https://uber.github.io/ludwig/api/visualization/#learning_curves
<img width="962" alt="api_doc_incorrect_format" src="https://user-images.githubusercontent.com/1425269/67630148-3c5cc000-f859-11e9-9d2e-8d4e2893dd0b.png">


**Expected behavior**
Correct formatting of the parameter list

**Screenshots**
If applicable, add screenshots to help explain your problem.

**Environment (please complete the following information):**
 - OS: MacOs 10:15
 - Version 10.15
- Python version N/A
- Ludwig version: 0.2.1

**Additional context**
I've researched and modified the module `code_doc_autogen.py` to correctly format the visualization api parameters.  In addition, minor updates were made to the docstring for functions in `visualize.py`.  Here is an example generated by the revised `code_doc_autogen.py`:
<img width="856" alt="api_doc_correct_format" src="https://user-images.githubusercontent.com/1425269/67630218-e426bd80-f85a-11e9-836f-acb3440c0e6d.png">

If this looks reasonable, I'm willing to finish up the work to correctly format the visualization api calls and submit a PR.    Any guidance will be appreciated.



Discussion:

Resolving patch:
diff --git a/ludwig/visualize.py b/ludwig/visualize.py
--- a/ludwig/visualize.py
+++ b/ludwig/visualize.py
@@ -682,17 +682,22 @@ def learning_curves(
 ):
     """Show how model measures change over training and validation data epochs.
 
-     For each model and for each output feature and measure of the model,
-     it produces a line plot showing how that measure changed over the course
-     of the epochs of training on the training and validation sets.
-    :param train_stats_per_model: List containing train statistics per model
-    :param output_feature_name: Name of the output feature that is predicted 
+    For each model and for each output feature and measure of the model,
+    it produces a line plot showing how that measure changed over the course
+    of the epochs of training on the training and validation sets.
+
+    # Inputs
+
+    :param train_stats_per_model: (list) List containing train statistics per model
+    :param output_feature_name: (string) Name of the output feature that is predicted
            and for which is provided ground truth
-    :param model_names: List of the names of the models to use as labels.
-    :param output_directory: Directory where to save plots.
+    :param model_names: (list, default: None) List of the names of the models to use as labels.
+    :param output_directory: (string, default: None) Directory where to save plots.
              If not specified, plots will be displayed in a window
-    :param file_format: File format of output plots - pdf or png
-    :return None:
+    :param file_format: (string, default: 'pdf') File format of output plots - pdf or png
+
+    # Return
+    :return: (None)
     """
     filename_template = 'learning_curves_{}_{}.' + file_format
     filename_template_path = generate_filename_template_path(
@@ -754,13 +759,19 @@ def compare_performance(
     For each model (in the aligned lists of test_statistics and model_names)
     it produces bars in a bar plot, one for each overall metric available
     in the test_statistics file for the specified output_feature_name.
-    :param test_stats_per_model: List containing train statistics per model
-    :param output_feature_name: Name of the output feature that is predicted and for which is provided ground truth
-    :param model_names: List of the names of the models to use as labels.
-    :param output_directory: Directory where to save plots.
+
+    # Inputs
+
+    :param test_stats_per_model: (list) List containing train statistics per model
+    :param output_feature_name: (string) Name of the output feature that is predicted and for which is provided ground truth
+    :param model_names: (list, default: None) List of the names of the models to use as labels.
+    :param output_directory: (string, default: None) Directory where to save plots.
              If not specified, plots will be displayed in a window
-    :param file_format: File format of output plots - pdf or png
-    :return None:
+    :param file_format: (string, default: 'pdf') File format of output plots - pdf or png
+
+    # Return
+
+    :return: (None)
     """
     filename_template = 'compare_performance_{}.' + file_format
     filename_template_path = generate_filename_template_path(
@@ -833,16 +844,22 @@ def compare_classifiers_performance_from_prob(
     For each model it produces bars in a bar plot, one for each overall metric
     computed on the fly from the probabilities of predictions for the specified
     output_feature_name.
-    :param probabilities_per_model: List of model probabilities
-    :param ground_truth: NumPy Array containing ground truth data
-    :param top_n_classes: List containing the number of classes to plot
-    :param labels_limit: Maximum numbers of labels.
+
+    # Inputs
+
+    :param probabilities_per_model: (list) List of model probabilities
+    :param ground_truth: (ndarray) NumPy Array containing ground truth data
+    :param top_n_classes: (list) List containing the number of classes to plot
+    :param labels_limit: (int) Maximum numbers of labels.
              If labels in dataset are higher than this number, "rare" label
-    :param model_names: List of the names of the models to use as labels.
-    :param output_directory: Directory where to save plots.
+    :param model_names: (list, default: None) List of the names of the models to use as labels.
+    :param output_directory: (string, default: None) Directory where to save plots.
              If not specified, plots will be displayed in a window
-    :param file_format: File format of output plots - pdf or png
-    :return None:
+    :param file_format: (string, default: 'pdf') File format of output plots - pdf or png
+
+    # Return
+
+    :return: (None)
     """
     top_n_classes_list = convert_to_list(top_n_classes)
     k = top_n_classes_list[0]
@@ -912,10 +929,13 @@ def compare_classifiers_performance_from_pred(
 
     For each model it produces bars in a bar plot, one for each overall metric
     computed on the fly from the predictions for the specified output_feature_name.
-    :param predictions_per_model: List containing the model predictions
+
+    # Inputs
+
+    :param predictions_per_model: (list) List containing the model predictions
            for the specified output_feature_name
-    :param ground_truth: NumPy Array containing ground truth data
-    :param metadata: Model's input metadata
+    :param ground_truth: (ndarray) NumPy Array containing ground truth data
+    :param metadata: (dict) Model's input metadata
     :param output_feature_name: output_feature_name containing ground truth
     :param labels_limit: Maximum numbers of labels.
              If labels in dataset are higher than this number, "rare" label
@@ -923,7 +943,10 @@ def compare_classifiers_performance_from_pred(
     :param output_directory: Directory where to save plots.
              If not specified, plots will be displayed in a window
     :param file_format: File format of output plots - pdf or png
-    :return None:
+
+    # Return
+
+    :return: (None)
     """
     if labels_limit > 0:
         ground_truth[ground_truth > labels_limit] = labels_limit
@@ -996,16 +1019,22 @@ def compare_classifiers_performance_subset(
      specified output_feature_name, considering only a subset of the full training set.
      The way the subset is obtained is using the top_n_classes and
      subset parameters.
-    :param probabilities_per_model: List of model probabilities
-    :param ground_truth: NumPy Array containing ground truth data
-    :param top_n_classes: List containing the number of classes to plot
-    :param labels_limit: Maximum numbers of labels.
-    :param subset: Type of the subset filtering
-    :param model_names: List of the names of the models to use as labels.
-    :param output_directory: Directory where to save plots.
+
+     # Inputs
+
+    :param probabilities_per_model: (list) List of model probabilities
+    :param ground_truth: (ndarray) NumPy Array containing ground truth data
+    :param top_n_classes: (list) List containing the number of classes to plot
+    :param labels_limit: (int) Maximum numbers of labels.
+    :param subset: () Type of the subset filtering
+    :param model_names: (list, default: None) List of the names of the models to use as labels.
+    :param output_directory: (string, default: None) Directory where to save plots.
              If not specified, plots will be displayed in a window
-    :param file_format: File format of output plots - pdf or png
-    :return None:
+    :param file_format: (string, default: 'pdf') File format of output plots - pdf or png
+
+    # Return
+
+    :return: (None)
     """
     top_n_classes_list = convert_to_list(top_n_classes)
     k = top_n_classes_list[0]
@@ -1105,16 +1134,22 @@ def compare_classifiers_performance_changing_k(
     For each model it produces a line plot that shows the Hits@K measure
     (that counts a prediction as correct if the model produces it among the
     first k) while changing k from 1 to top_k for the specified output_feature_name.
-    :param probabilities_per_model: List of model probabilities
-    :param ground_truth: NumPy Array containing ground truth data
-    :param top_k: Number of elements in the ranklist to consider
-    :param labels_limit: Maximum numbers of labels.
+
+    # Inputs
+
+    :param probabilities_per_model: (list) List of model probabilities
+    :param ground_truth: (ndarray) NumPy Array containing ground truth data
+    :param top_k: (int) Number of elements in the ranklist to consider
+    :param labels_limit: (int) Maximum numbers of labels.
              If labels in dataset are higher than this number, "rare" label
-    :param model_names: List of the names of the models to use as labels.
-    :param output_directory: Directory where to save plots.
+    :param model_names: (list, default: None) List of the names of the models to use as labels.
+    :param output_directory: (string, default: None) Directory where to save plots.
              If not specified, plots will be displayed in a window
-    :param file_format: File format of output plots - pdf or png
-    :return None:
+    :param file_format: (string, default: 'pdf') File format of output plots - pdf or png
+
+    # Return
+
+    :return: (None)
     """
     k = top_k
     if labels_limit > 0:
@@ -1169,16 +1204,20 @@ def compare_classifiers_multiclass_multimetric(
 
     For each model it produces four plots that show the precision,
     recall and F1 of the model on several classes for the specified output_feature_name.
-    :param test_stats_per_model: List containing train statistics per model
-    :param metadata: Model's input metadata
-    :param output_feature_name: Name of the output feature that is predicted and for which is provided ground truth
-    :param top_n_classes: List containing the number of classes to plot
-    :param model_names: List of the names of the models to use as labels.
-    :param output_directory: Directory where to save plots.
+
+    # Inputs
+
+    :param test_stats_per_model: (list) List containing train statistics per model
+    :param metadata: (dict) Model's input metadata
+    :param output_feature_name: (string) Name of the output feature that is predicted and for which is provided ground truth
+    :param top_n_classes: (list) List containing the number of classes to plot
+    :param model_names: (list, default: None) List of the names of the models to use as labels.
+    :param output_directory: (string, default: None) Directory where to save plots.
              If not specified, plots will be displayed in a window
-    :param file_format: File format of output plots - pdf or png
-    :return None:
-    :return:
+    :param file_format: (string, default: 'pdf') File format of output plots - pdf or png
+
+    # Return
+    :return: (None)
     """
     filename_template = 'compare_classifiers_multiclass_multimetric_{}_{}_{}.' \
                         + file_format
@@ -1338,15 +1377,20 @@ def compare_classifiers_predictions(
 ):
     """Show two models comparision of their output_feature_name predictions.
 
-    :param predictions_per_model: List containing the model predictions
-    :param ground_truth: NumPy Array containing ground truth data
-    :param labels_limit: Maximum numbers of labels.
+    # Inputs
+
+    :param predictions_per_model: (list) List containing the model predictions
+    :param ground_truth: (ndarray) NumPy Array containing ground truth data
+    :param labels_limit: (int) Maximum numbers of labels.
              If labels in dataset are higher than this number, "rare" label
-    :param model_names: List of the names of the models to use as labels.
-    :param output_directory: Directory where to save plots.
+    :param model_names: (list, default: None) List of the names of the models to use as labels.
+    :param output_directory: (string, default: None) Directory where to save plots.
              If not specified, plots will be displayed in a window
-    :param file_format: File format of output plots - pdf or png
-    :return None:
+    :param file_format: (string, default: 'pdf') File format of output plots - pdf or png
+
+    # Return
+
+    :return: (None)
     """
     model_names_list = convert_to_list(model_names)
     name_c1 = (
@@ -1469,15 +1513,21 @@ def compare_classifiers_predictions_distribution(
 
     This visualization produces a radar plot comparing the distributions of
     predictions of the models for the first 10 classes of the specified output_feature_name.
-    :param predictions_per_model: List containing the model predictions
-    :param ground_truth: NumPy Array containing ground truth data
-    :param labels_limit: Maximum numbers of labels.
+
+    # Inputs
+
+    :param predictions_per_model: (list) List containing the model predictions
+    :param ground_truth: (ndarray) NumPy Array containing ground truth data
+    :param labels_limit: (int) Maximum numbers of labels.
              If labels in dataset are higher than this number, "rare" label
-    :param model_names: List of the names of the models to use as labels.
-    :param output_directory: Directory where to save plots.
+    :param model_names: (list, default: None) List of the names of the models to use as labels.
+    :param output_directory: (string, default: None) Directory where to save plots.
              If not specified, plots will be displayed in a window
-    :param file_format: File format of output plots - pdf or png
-    :return None:
+    :param file_format: (string, default: 'pdf') File format of output plots - pdf or png
+
+    # Return
+
+    :return: (None)
     """
     model_names_list = convert_to_list(model_names)
     if labels_limit > 0:
@@ -1530,15 +1580,21 @@ def confidence_thresholding(
     For each model it produces a pair of lines indicating the accuracy of
     the model and the data coverage while increasing a threshold (x axis) on
     the probabilities of predictions for the specified output_feature_name.
-    :param probabilities_per_model: List of model probabilities
-    :param ground_truth: NumPy Array containing ground truth data
-    :param labels_limit: Maximum numbers of labels.
+
+    # Inputs
+
+    :param probabilities_per_model: (list) List of model probabilities
+    :param ground_truth: (ndarray) NumPy Array containing ground truth data
+    :param labels_limit: (int) Maximum numbers of labels.
              If labels in dataset are higher than this number, "rare" label
-    :param model_names: List of the names of the models to use as labels.
-    :param output_directory: Directory where to save plots.
+    :param model_names: (list, default: None) List of the names of the models to use as labels.
+    :param output_directory: (sting) Directory where to save plots.
              If not specified, plots will be displayed in a window
-    :param file_format: File format of output plots - pdf or png
-    :return None:
+    :param file_format: (string, default: 'pdf') File format of output plots - pdf or png
+
+    # Return
+
+    :return: (None)
     """
     if labels_limit > 0:
         ground_truth[ground_truth > labels_limit] = labels_limit
@@ -1613,15 +1669,20 @@ def confidence_thresholding_data_vs_acc(
     confidence_thresholding is that it uses two axes instead of three,
     not visualizing the threshold and having coverage as x axis instead of
     the threshold.
-    :param probabilities_per_model: List of model probabilities
-    :param ground_truth: NumPy Array containing ground truth data
-    :param labels_limit: Maximum numbers of labels.
+
+    # Inputs
+
+    :param probabilities_per_model: (list) List of model probabilities
+    :param ground_truth: (ndarray) NumPy Array containing ground truth data
+    :param labels_limit:(int) Maximum numbers of labels.
              If labels in dataset are higher than this number, "rare" label
-    :param model_names: List of the names of the models to use as labels.
-    :param output_directory: Directory where to save plots.
+    :param model_names: (list, default: None) List of the names of the models to use as labels.
+    :param output_directory: (string, default: None) Directory where to save plots.
              If not specified, plots will be displayed in a window
-    :param file_format: File format of output plots - pdf or png
-    :return None:
+    :param file_format: (string, default: 'pdf') File format of output plots - pdf or png
+
+    # Return
+    :return: (None)
     """
     if labels_limit > 0:
         ground_truth[ground_truth > labels_limit] = labels_limit
@@ -1707,16 +1768,22 @@ def confidence_thresholding_data_vs_acc_subset(
      that is within the top n most frequent ones will be considered as test set,
      and the percentage of datapoints that have been kept from the original set
      will be displayed for each model.
-    :param probabilities_per_model: List of model probabilities
-    :param ground_truth: NumPy Array containing ground truth data
-    :param top_n_classes: List containing the number of classes to plot
-    :param labels_limit: Maximum numbers of labels.
-    :param subset: Type of the subset filtering
-    :param model_names: List of the names of the models to use as labels.
-    :param output_directory: Directory where to save plots.
+
+    # Inputs
+
+    :param probabilities_per_model: (list) List of model probabilities
+    :param ground_truth: (ndarray) NumPy Array containing ground truth data
+    :param top_n_classes: (list) List containing the number of classes to plot
+    :param labels_limit: (int) Maximum numbers of labels.
+    :param subset: (string) Type of the subset filtering
+    :param model_names: (list, default: None) List of the names of the models to use as labels.
+    :param output_directory: (string, default: None) Directory where to save plots.
              If not specified, plots will be displayed in a window
-    :param file_format: File format of output plots - pdf or png
-    :return None:
+    :param file_format: (string, default: 'pdf') File format of output plots - pdf or png
+
+    # Return
+
+    :return: (None)
     """
     top_n_classes_list = convert_to_list(top_n_classes)
     k = top_n_classes_list[0]
@@ -1832,17 +1899,22 @@ def confidence_thresholding_data_vs_acc_subset_per_class(
 
     The difference with confidence_thresholding_data_vs_acc_subset is that it
     produces one plot per class within the top_n_classes.
-    :param probabilities_per_model: List of model probabilities
-    :param ground_truth: NumPy Array containing ground truth data
-    :param metadata: Model's input metadata
-    :param top_n_classes: List containing the number of classes to plot
-    :param labels_limit: Maximum numbers of labels.
-    :param subset: Type of the subset filtering
-    :param model_names: List of the names of the models to use as labels.
-    :param output_directory: Directory where to save plots.
+
+    # Inputs
+
+    :param probabilities_per_model: (list) List of model probabilities
+    :param ground_truth: (ndarray) NumPy Array containing ground truth data
+    :param metadata: (dict) Model's input metadata
+    :param top_n_classes: (list) List containing the number of classes to plot
+    :param labels_limit: (int) Maximum numbers of labels.
+    :param subset: (string) Type of the subset filtering
+    :param model_names: (list, default: None) List of the names of the models to use as labels.
+    :param output_directory: (string, default: None) Directory where to save plots.
              If not specified, plots will be displayed in a window
-    :param file_format: File format of output plots - pdf or png
-    :return None:
+    :param file_format: (string, default: 'pdf') File format of output plots - pdf or png
+
+    # Return
+    :return: (None)
     """
     filename_template = \
         'confidence_thresholding_data_vs_acc_subset_per_class_{}.' + file_format
@@ -1947,16 +2019,22 @@ def confidence_thresholding_2thresholds_2d(
     threshold_output_feature_names  as x and y axes and either the data coverage percentage or
     the accuracy as z axis. Each line represents a slice of the data
     coverage  surface projected onto the accuracy surface.
-    :param probabilities_per_model: List of model probabilities
-    :param ground_truths: List of NumPy Arrays containing ground truth data
-    :param threshold_output_feature_names: List of output_feature_names for 2d threshold
-    :param labels_limit: Maximum numbers of labels.
+
+    # Inputs
+
+    :param probabilities_per_model: (list) List of model probabilities
+    :param ground_truths: (list) List of NumPy Arrays containing ground truth data
+    :param threshold_output_feature_names: (list) List of output_feature_names for 2d threshold
+    :param labels_limit: (int) Maximum numbers of labels.
              If labels in dataset are higher than this number, "rare" label
-    :param model_names: Name of the model to use as label.
-    :param output_directory: Directory where to save plots.
+    :param model_names: (string) Name of the model to use as label.
+    :param output_directory: (string, default: None) Directory where to save plots.
              If not specified, plots will be displayed in a window
-    :param file_format: File format of output plots - pdf or png
-    :return None:
+    :param file_format: (string, default: 'pdf') File format of output plots - pdf or png
+
+    # Return
+
+    :return: (None)
     """
     try:
         validate_conf_treshholds_and_probabilities_2d_3d(
@@ -2133,15 +2211,21 @@ def confidence_thresholding_2thresholds_3d(
     confidence_thresholding_2thresholds_3d that have thresholds on the
     confidence of the predictions of the two threshold_output_feature_names as x and y axes
     and either the data coverage percentage or the accuracy as z axis.
-    :param probabilities_per_model: List of model probabilities
-    :param ground_truths: List of NumPy Arrays containing ground truth data
-    :param threshold_output_feature_names: List of output_feature_names for 2d threshold
-    :param labels_limit: Maximum numbers of labels.
+
+    # Inputs
+
+    :param probabilities_per_model: (list) List of model probabilities
+    :param ground_truths: (list) List of NumPy Arrays containing ground truth data
+    :param threshold_output_feature_names: (list) List of output_feature_names for 2d threshold
+    :param labels_limit: (int) Maximum numbers of labels.
              If labels in dataset are higher than this number, "rare" label
-    :param output_directory: Directory where to save plots.
+    :param output_directory: (string, default: None) Directory where to save plots.
              If not specified, plots will be displayed in a window
-    :param file_format: File format of output plots - pdf or png
-    :return None:
+    :param file_format: (string, default: 'pdf') File format of output plots - pdf or png
+
+    # Return
+
+    :return: (None)
     """
     try:
         validate_conf_treshholds_and_probabilities_2d_3d(
@@ -2249,16 +2333,22 @@ def binary_threshold_vs_metric(
     considered negative. It needs to be an integer, to figure out the
     association between classes and integers check the ground_truth_metadata
     JSON file.
-    :param probabilities_per_model: List of model probabilities
-    :param ground_truth: List of NumPy Arrays containing ground truth data
+
+    # Inputs
+
+    :param probabilities_per_model: (list) List of model probabilities
+    :param ground_truth: (list) List of NumPy Arrays containing ground truth data
     :param metrics: metrics to dispay (f1, precision, recall,
                     accuracy)
-    :param positive_label: Label of the positive class
-    :param model_names: List of the names of the models to use as labels.
-    :param output_directory: Directory where to save plots.
+    :param positive_label: (string) Label of the positive class
+    :param model_names: (list, default: None) List of the names of the models to use as labels.
+    :param output_directory: (string, default: None) Directory where to save plots.
              If not specified, plots will be displayed in a window
-    :param file_format: File format of output plots - pdf or png
-    :return None:
+    :param file_format: (string, default: 'pdf') File format of output plots - pdf or png
+
+    # Return
+
+    :return: (None)
     """
     probs = probabilities_per_model
     model_names_list = convert_to_list(model_names)
@@ -2359,14 +2449,20 @@ def roc_curves(
     be considered negative. It needs to be an integer, to figure out the
     association between classes and integers check the ground_truth_metadata
     JSON file.
-    :param probabilities_per_model: List of model probabilities
-    :param ground_truth: List of NumPy Arrays containing ground truth data
-    :param positive_label: Label of the positive class
-    :param model_names: List of the names of the models to use as labels.
-    :param output_directory: Directory where to save plots.
+
+    # Inputs
+
+    :param probabilities_per_model: (list) List of model probabilities
+    :param ground_truth: (list) List of NumPy Arrays containing ground truth data
+    :param positive_label: (string) Label of the positive class
+    :param model_names: (list, default: None) List of the names of the models to use as labels.
+    :param output_directory: (string, default: None) Directory where to save plots.
              If not specified, plots will be displayed in a window
-    :param file_format: File format of output plots - pdf or png
-    :return None:
+    :param file_format: (string, default: 'pdf') File format of output plots - pdf or png
+
+    # Return
+
+    :return: (None)
     """
     probs = probabilities_per_model
     model_names_list = convert_to_list(model_names)
@@ -2410,13 +2506,19 @@ def roc_curves_from_test_statistics(
     This visualization uses the output_feature_name, test_statistics and model_names
     parameters. output_feature_name needs to be binary feature. This visualization produces a
     line chart plotting the roc curves for the specified output_feature_name.
-    :param test_stats_per_model: List containing train statistics per model
-    :param output_feature_name: Name of the output feature that is predicted and for which is provided ground truth
-    :param model_names: List of the names of the models to use as labels.
-    :param output_directory: Directory where to save plots.
+
+    # Inputs
+
+    :param test_stats_per_model: (list) List containing train statistics per model
+    :param output_feature_name: (string) Name of the output feature that is predicted and for which is provided ground truth
+    :param model_names: (list, default: None) List of the names of the models to use as labels.
+    :param output_directory: (string, default: None) Directory where to save plots.
              If not specified, plots will be displayed in a window
-    :param file_format: File format of output plots - pdf or png
-    :return None:
+    :param file_format: (string, default: 'pdf') File format of output plots - pdf or png
+
+    # Return
+
+    :return: (None)
     """
     model_names_list = convert_to_list(model_names)
     filename_template = 'roc_curves_from_prediction_statistics.' + file_format
@@ -2465,16 +2567,22 @@ def calibration_1_vs_all(
     the  current class to be the true one and all others to be a false one,
     drawing the distribution for each model (in the aligned lists of
     probabilities and model_names).
-    :param probabilities_per_model: List of model probabilities
-    :param ground_truth: NumPy Array containing ground truth data
-    :param top_n_classes: List containing the number of classes to plot
-    :param labels_limit: Maximum numbers of labels.
+
+    # Inputs
+
+    :param probabilities_per_model: (list) List of model probabilities
+    :param ground_truth: (ndarray) NumPy Array containing ground truth data
+    :param top_n_classes: (list) List containing the number of classes to plot
+    :param labels_limit: (int) Maximum numbers of labels.
              If labels in dataset are higher than this number, "rare" label
-    :param model_names: List of the names of the models to use as labels.
-    :param output_directory: Directory where to save plots.
+    :param model_names: (list, default: None) List of the names of the models to use as labels.
+    :param output_directory: (string, default: None) Directory where to save plots.
              If not specified, plots will be displayed in a window
-    :param file_format: File format of output plots - pdf or png
-    :return None:
+    :param file_format: (string, default: 'pdf') File format of output plots - pdf or png
+
+    # String
+
+    :return: (None)
     """
     probs = probabilities_per_model
     model_names_list = convert_to_list(model_names)
@@ -2583,15 +2691,20 @@ def calibration_multiclass(
     """Show models probability of predictions for each class of the the
     specified output_feature_name.
 
-    :param probabilities_per_model: List of model probabilities
-    :param ground_truth: NumPy Array containing ground truth data
-    :param labels_limit: Maximum numbers of labels.
+    # Inputs
+
+    :param probabilities_per_model: (list) List of model probabilities
+    :param ground_truth: (ndarray) NumPy Array containing ground truth data
+    :param labels_limit: (int) Maximum numbers of labels.
              If labels in dataset are higher than this number, "rare" label
-    :param model_names: List of the names of the models to use as labels.
-    :param output_directory: Directory where to save plots.
+    :param model_names: (list, default: None) List of the names of the models to use as labels.
+    :param output_directory: (string, default: None) Directory where to save plots.
              If not specified, plots will be displayed in a window
-    :param file_format: File format of output plots - pdf or png
-    :return None:
+    :param file_format: (string, default: 'pdf') File format of output plots - pdf or png
+
+    # Return
+
+    :return: (None)
     """
     probs = probabilities_per_model
     model_names_list = convert_to_list(model_names)
@@ -2689,17 +2802,22 @@ def confusion_matrix(
     it  produces a heatmap of the confusion matrix in the predictions for
     each  output_feature_name that has a confusion matrix in test_statistics. The value of
     top_n_classes limits the heatmap to the n most frequent classes.
-    :param test_stats_per_model: List containing train statistics per model
-    :param metadata: Model's input metadata
-    :param output_feature_name: Name of the output feature that is predicted and for which is provided ground truth
-    :param top_n_classes: List containing the number of classes to plot
-    :param normalize: Flag to normalize rows in confusion matrix
-    :param model_names: List of the names of the models to use as labels.
-    :param output_directory: Directory where to save plots.
+
+    # Inputs
+
+    :param test_stats_per_model: (string) List containing train statistics per model
+    :param metadata: (dict) Model's input metadata
+    :param output_feature_name: (string) Name of the output feature that is predicted and for which is provided ground truth
+    :param top_n_classes: (list) List containing the number of classes to plot
+    :param normalize: (bool) Flag to normalize rows in confusion matrix
+    :param model_names: (list, default: None) List of the names of the models to use as labels.
+    :param output_directory: (string, default: None) Directory where to save plots.
              If not specified, plots will be displayed in a window
-    :param file_format: File format of output plots - pdf or png
-    :return None:
-    :return:
+    :param file_format: (string, default: 'pdf') File format of output plots - pdf or png
+
+    # Return
+
+    :return: (None)
     """
     test_stats_per_model_list = test_stats_per_model
     model_names_list = convert_to_list(model_names)
@@ -2717,7 +2835,7 @@ def confusion_matrix(
             test_stats_per_model_list):
         for output_feature_name in output_feature_names:
             if 'confusion_matrix' in test_statistics[output_feature_name]:
-                confusion_matrix = np.array(
+                _confusion_matrix = np.array(
                     test_statistics[output_feature_name]['confusion_matrix']
                 )
                 model_name_name = model_names_list[i] if (
@@ -2729,12 +2847,12 @@ def confusion_matrix(
                         metadata[output_feature_name]:
                     labels = metadata[output_feature_name]['idx2str']
                 else:
-                    labels = list(range(len(confusion_matrix)))
+                    labels = list(range(len(_confusion_matrix)))
 
                 for k in top_n_classes:
-                    k = (min(k, confusion_matrix.shape[0])
-                         if k > 0 else confusion_matrix.shape[0])
-                    cm = confusion_matrix[:k, :k]
+                    k = (min(k, _confusion_matrix.shape[0])
+                         if k > 0 else _confusion_matrix.shape[0])
+                    cm = _confusion_matrix[:k, :k]
                     if normalize:
                         with np.errstate(divide='ignore', invalid='ignore'):
                             cm_norm = np.true_divide(cm,
@@ -2811,16 +2929,21 @@ def frequency_vs_f1(
     The second plot has the same structure of the first one,
      but the axes are flipped and the classes on the x axis are sorted by
      frequency.
-    :param test_stats_per_model: List containing train statistics per model
-    :param metadata: Model's input metadata
-    :param output_feature_name: Name of the output feature that is predicted and for which is provided ground truth
-    :param top_n_classes: List containing the number of classes to plot
-    :param model_names: List of the names of the models to use as labels.
-    :param output_directory: Directory where to save plots.
+
+    # Inputs
+
+    :param test_stats_per_model: (list) List containing train statistics per model
+    :param metadata: (dict) Model's input metadata
+    :param output_feature_name: (string) Name of the output feature that is predicted and for which is provided ground truth
+    :param top_n_classes: (list) List containing the number of classes to plot
+    :param model_names: (list, default: None) List of the names of the models to use as labels.
+    :param output_directory: (string, default: None) Directory where to save plots.
              If not specified, plots will be displayed in a window
-    :param file_format: File format of output plots - pdf or png
-    :return None:
-    :return:
+    :param file_format: (string, default: 'pdf') File format of output plots - pdf or png
+
+    # Return
+
+    :return: (None)
     """
     test_stats_per_model_list = test_stats_per_model
     model_names_list = convert_to_list(model_names)
diff --git a/mkdocs/code_doc_autogen.py b/mkdocs/code_doc_autogen.py
--- a/mkdocs/code_doc_autogen.py
+++ b/mkdocs/code_doc_autogen.py
@@ -132,24 +132,24 @@
 OUTPUT_DIR = 'docs'
 
 
-def get_function_signature(function, method=True):
-    wrapped = getattr(function, '_original_function', None)
+def get_function_signature(_function, _method=True):
+    wrapped = getattr(_function, '_original_function', None)
     if wrapped is None:
-        signature = inspect.getargspec(function)
+        _signature = inspect.getfullargspec(_function)
     else:
-        signature = inspect.getargspec(wrapped)
-    defaults = signature.defaults
-    if method and len(signature.args) > 0 and signature.args[0] == 'self':
-        args = signature.args[1:]
+        _signature = inspect.getfullargspec(wrapped)
+    defaults = _signature.defaults
+    if _method and _signature.args and _signature.args[0] == 'self':
+        args = _signature.args[1:]
     else:
-        args = signature.args
+        args = _signature.args
     if defaults:
         kwargs = zip(args[-len(defaults):], defaults)
         args = args[:-len(defaults)]
     else:
         kwargs = []
     st = '%s.%s(\n' % (
-        clean_module_name(function.__module__), function.__name__)
+        clean_module_name(_function.__module__), _function.__name__)
 
     for a in args:
         st += '  {},\n'.format(str(a))
@@ -158,32 +158,32 @@ def get_function_signature(function, method=True):
             v = '\'' + v + '\''
         st += '  {}={},\n'.format(str(a), str(v))
     if kwargs or args:
-        signature = st[:-2] + '\n)'
+        _signature = st[:-2] + '\n)'
     else:
-        signature = st + ')'
-    return post_process_signature(signature)
+        _signature = st + ')'
+    return post_process_signature(_signature)
 
 
-def get_class_signature(cls):
+def get_class_signature(_cls):
     try:
-        class_signature = get_function_signature(cls.__init__)
-        class_signature = class_signature.replace('__init__', cls.__name__)
+        class_signature = get_function_signature(_cls.__init__)
+        class_signature = class_signature.replace('__init__', _cls.__name__)
     except (TypeError, AttributeError):
         # in case the class inherits from object and does not
         # define __init__
         class_signature = "{clean_module_name}.{cls_name}()".format(
-            clean_module_name=clean_module_name(cls.__module__),
-            cls_name=cls.__name__
+            clean_module_name=clean_module_name(_cls.__module__),
+            cls_name=_cls.__name__
         )
     return post_process_signature(class_signature)
 
 
-def post_process_signature(signature):
-    parts = re.split(r'\.(?!\d)', signature)
+def post_process_signature(_signature):
+    parts = re.split(r'\.(?!\d)', _signature)
     if len(parts) >= 4:
         if parts[1] == 'api':
-            signature = 'ludwig.' + '.'.join(parts[2:])
-    return signature
+            _signature = 'ludwig.' + '.'.join(parts[2:])
+    return _signature
 
 
 def clean_module_name(name):
@@ -192,20 +192,20 @@ def clean_module_name(name):
     return name
 
 
-def class_to_docs_link(cls):
-    module_name = clean_module_name(cls.__module__)
+def class_to_docs_link(_cls):
+    module_name = clean_module_name(_cls.__module__)
     module_name = module_name[6:]
-    link = ROOT + module_name.replace('.', '/') + '#' + cls.__name__.lower()
+    link = ROOT + module_name.replace('.', '/') + '#' + _cls.__name__.lower()
     return link
 
 
-def class_to_source_link(cls):
-    module_name = clean_module_name(cls.__module__)
-    path = module_name.replace('.', '/')
-    path += '.py'
-    line = inspect.getsourcelines(cls)[-1]
+def class_to_source_link(_cls):
+    module_name = clean_module_name(_cls.__module__)
+    _path = module_name.replace('.', '/')
+    _path += '.py'
+    line = inspect.getsourcelines(_cls)[-1]
     link = ('https://github.com/uber/'
-            'ludwig/blob/master/' + path + '#L' + str(line))
+            'ludwig/blob/master/' + _path + '#L' + str(line))
     return '[[source]](' + link + ')'
 
 
@@ -224,18 +224,18 @@ def count_leading_spaces(s):
         return 0
 
 
-def process_list_block(docstring, starting_point, section_end,
+def process_list_block(_docstring, starting_point, section_end,
                        leading_spaces, marker):
-    ending_point = docstring.find('\n\n', starting_point)
-    block = docstring[starting_point:(None if ending_point == -1 else
+    ending_point = _docstring.find('\n\n', starting_point)
+    block = _docstring[starting_point:(None if ending_point == -1 else
                                       ending_point - 1)]
     # Place marker for later reinjection.
-    docstring_slice = docstring[
+    docstring_slice = _docstring[
                       starting_point:None if section_end == -1 else section_end].replace(
         block, marker)
-    docstring = (docstring[:starting_point]
+    _docstring = (_docstring[:starting_point]
                  + docstring_slice
-                 + docstring[section_end:])
+                 + _docstring[section_end:])
     lines = block.split('\n')
     # Remove the computed number of leading white spaces from each line.
     lines = [re.sub('^' + ' ' * leading_spaces, '', line) for line in lines]
@@ -294,20 +294,20 @@ def process_list_block(docstring, starting_point, section_end,
             lines[i] = '- __return__{}:{}'.format(inside_brackets, line)
 
     block = '\n'.join(lines)
-    return docstring, block
+    return _docstring, block
 
 
-def process_docstring(docstring):
+def process_docstring(_docstring):
     # First, extract code blocks and process them.
     code_blocks = []
-    if '```' in docstring:
-        tmp = docstring[:]
+    if '```' in _docstring:
+        tmp = _docstring[:]
         while '```' in tmp:
             tmp = tmp[tmp.find('```'):]
             index = tmp[3:].find('```') + 6
             snippet = tmp[:index]
             # Place marker in docstring for later reinjection.
-            docstring = docstring.replace(
+            _docstring = _docstring.replace(
                 snippet, '$CODE_BLOCK_%d' % len(code_blocks))
             snippet_lines = snippet.split('\n')
             # Remove leading spaces.
@@ -338,83 +338,88 @@ def process_docstring(docstring):
 
     # Format docstring lists.
     section_regex = r'\n( +)# (.*)\n'
-    section_idx = re.search(section_regex, docstring)
+    section_idx = re.search(section_regex, _docstring)
     shift = 0
     sections = {}
     while section_idx and section_idx.group(2):
         anchor = section_idx.group(2)
         leading_spaces = len(section_idx.group(1))
         shift += section_idx.end()
-        next_section_idx = re.search(section_regex, docstring[shift:])
+        next_section_idx = re.search(section_regex, _docstring[shift:])
         if next_section_idx is None:
             section_end = -1
         else:
             section_end = shift + next_section_idx.start()
         marker = '$' + anchor.replace(' ', '_') + '$'
-        docstring, content = process_list_block(docstring,
-                                                shift,
-                                                section_end,
-                                                leading_spaces,
-                                                marker)
+        _docstring, content = process_list_block(_docstring,
+                                                 shift,
+                                                 section_end,
+                                                 leading_spaces,
+                                                 marker)
         sections[marker] = content
         # `docstring` has changed, so we can't use `next_section_idx` anymore
         # we have to recompute it
-        section_idx = re.search(section_regex, docstring[shift:])
+        section_idx = re.search(section_regex, _docstring[shift:])
 
     # Format docstring section titles.
-    docstring = re.sub(r'\n(\s+)# (.*)\n',
+    _docstring = re.sub(r'\n(\s+)# (.*)\n',
                        r'\n\1__\2__\n\n',
-                       docstring)
+                        _docstring)
 
     # Strip all remaining leading spaces.
-    lines = docstring.split('\n')
-    docstring = '\n'.join([line.lstrip(' ') for line in lines])
+    # generator function to resolve deepsource.io major issue
+    def strip_leading_spaces(these_lines):
+        for l in these_lines:
+            yield l.lstrip(' ')
+
+    lines = _docstring.split('\n')
+    _docstring = '\n'.join(strip_leading_spaces(lines))
 
     # Reinject list blocks.
     for marker, content in sections.items():
-        docstring = docstring.replace(marker, content)
+        _docstring = _docstring.replace(marker, content)
 
     # Reinject code blocks.
     for i, code_block in enumerate(code_blocks):
-        docstring = docstring.replace(
+        _docstring = _docstring.replace(
             '$CODE_BLOCK_%d' % i, code_block)
-    return docstring
+    return _docstring
 
 
-def read_file(path):
-    with open(path) as f:
-        return f.read()
+def read_file(_path):
+    with open(_path) as _f:
+        return _f.read()
 
 
-def collect_class_methods(cls, methods):
-    if isinstance(methods, (list, tuple)):
-        return [getattr(cls, m) if isinstance(m, str) else m for m in methods]
-    methods = []
-    for _, method in inspect.getmembers(cls, predicate=inspect.isroutine):
-        if method.__name__[0] == '_' or method.__name__ in EXCLUDE:
+def collect_class_methods(_cls, _methods):
+    if isinstance(_methods, (list, tuple)):
+        return [getattr(_cls, m) if isinstance(m, str) else m for m in _methods]
+    _methods = []
+    for _, _method in inspect.getmembers(_cls, predicate=inspect.isroutine):
+        if _method.__name__[0] == '_' or _method.__name__ in EXCLUDE:
             continue
-        methods.append(method)
-    return methods
+        _methods.append(_method)
+    return _methods
 
 
-def render_function(function, method=True):
-    subblocks = []
-    signature = get_function_signature(function, method=method)
-    if method:
-        signature = signature.replace(
-            clean_module_name(function.__module__) + '.', '')
-    subblocks.append('## ' + function.__name__ + '\n')
-    subblocks.append(code_snippet(signature))
-    docstring = function.__doc__
-    if docstring:
-        subblocks.append(process_docstring(docstring))
-    return '\n\n'.join(subblocks)
+def render_function(_function, _method=True):
+    _subblocks = []
+    _signature = get_function_signature(_function, _method=_method)
+    if _method:
+        _signature = _signature.replace(
+            clean_module_name(_function.__module__) + '.', '')
+    _subblocks.append('## ' + _function.__name__ + '\n')
+    _subblocks.append(code_snippet(_signature))
+    _docstring = _function.__doc__
+    if _docstring:
+        _subblocks.append(process_docstring(_docstring))
+    return '\n\n'.join(_subblocks)
 
 
-def read_page_data(page_data, type):
+def read_page_data(_page_data, type):
     assert type in ['classes', 'functions', 'methods']
-    data = page_data.get(type, [])
-    for module in page_data.get('all_module_{}'.format(type), []):
+    data = _page_data.get(type, [])
+    for module in _page_data.get('all_module_{}'.format(type), []):
         module_data = []
         for name in dir(module):
             if name[0] == '_' or name in EXCLUDE:
@@ -459,7 +464,15 @@ def read_page_data(page_data, type):
 
     print('Generating docs for Ludwig %s.' % ludwig.__version__)
     for page_data in PAGES:
-        classes = read_page_data(page_data, 'classes')
+        classes = []
+        functions = []
+        methods = []
+        if 'classes' in page_data.keys():
+            classes = read_page_data(page_data, 'classes')
+        elif 'functions' in page_data.keys():
+            functions = read_page_data(page_data, 'functions')
+        else:
+            raise TypeError('Invalid type specified in page_data')
 
         blocks = []
         for element in classes:
@@ -482,20 +495,24 @@ def read_page_data(page_data, type):
             if methods:
                 subblocks.append('\n---')
                 subblocks.append('# ' + cls.__name__ + ' methods\n')
-                subblocks.append('\n---\n'.join(
-                    [render_function(method, method=True) for method in
-                     methods]))
+
+                # generator function to resolve deepsource.io major issue
+                def generate_render_functions(_methods):
+                    for m in _methods:
+                        yield render_function(m, _method=True)
+
+                subblocks.append('\n---\n'.join(generate_render_functions(methods)))
             blocks.append('\n'.join(subblocks))
 
         methods = read_page_data(page_data, 'methods')
 
         for method in methods:
-            blocks.append(render_function(method, method=True))
+            blocks.append(render_function(method, _method=True))
 
         functions = read_page_data(page_data, 'functions')
 
         for function in functions:
-            blocks.append(render_function(function, method=False))
+            blocks.append(render_function(function, _method=False))
 
         if not blocks:
             raise RuntimeError('Found no content for page ' +


Test patch: