code: def _plot_two_pd_num_cat(
      exp: Explanation,
      feature: int,
      target_idx: int,
      pd_limits: Optional[Tuple[float, float]] = None,
      ax: Optional["plt.Axes"] = None,
      pd_num_cat_kw: Optional[dict] = None,
  ) -> Tuple["plt.Axes", Optional[Tuple[float, float]]]:
      """
      Plots two ways partial dependence curve for a numerical feature and a categorical feature.
  
      Parameters
      ----------
      exp, feature, pd_num_cat_kw
          See :py:meth:`alibi.explainers.partial_dependence.plot_pd` method.
      target_idx
          The target index for which to plot the partial dependence (PD) curves. An integer
          denoting target index in `exp.meta['params']['target_names'].`
      ax
          Pre-existing axes for the plot. Otherwise, call `matplotlib.pyplot.gca()` internally.
  
      Returns
      -------
      `matplotlib` axes and a tuple containing the minimum and maximum y-limits.
      """
      import matplotlib.pyplot as plt
      from matplotlib import transforms
  
      if exp.meta["params"]["kind"] not in [Kind.AVERAGE, Kind.BOTH]:
          raise ValueError(
              "Can only plot partial dependence for `kind` in `['average', 'both']`."
          )
  
      if ax is None:
          ax = plt.gca()
  
      def _is_categorical(feature):
          feature_idx = exp.meta["params"]["feature_names"].index(
              feature
          )
          return feature_idx in exp.meta["params"]["categorical_names"]
  
      # extract feature values and partial dependence values
      feature_values = exp.data["feature_values"][feature]
      feature_deciles = exp.data["feature_deciles"][feature]
      pd_values = exp.data["pd_values"][feature][target_idx]
  
      # find which feature is categorical and which one is numerical
      feature_names = exp.data["feature_names"][feature]
      if _is_categorical(feature_names[0]):
          feature_names = feature_names[::-1]
          feature_values = feature_values[::-1]
          feature_deciles = feature_deciles[::-1]
          pd_values = pd_values.T
  
      # define labels
      cat_feature_index = exp.meta["params"]["feature_names"].index(
          feature_names[1]
      )
      labels = [
          exp.meta["params"]["categorical_names"][cat_feature_index][i]
          for i in feature_values[1].astype(np.int32)
      ]
  
      # plot lines
      default_pd_num_cat_kw = {"markersize": 2, "marker": "o"}
      pd_num_cat_kw = (
          default_pd_num_cat_kw
          if pd_num_cat_kw is None
          else {**default_pd_num_cat_kw, **pd_num_cat_kw}
      )
      ax.plot([], [], " ", label=feature_names[1])
  
      for i in range(pd_values.shape[1]):
          x, y = feature_values[0], pd_values[:, i]
          pd_num_cat_kw.update({"label": labels[i]})
          ax.plot(x, y, **pd_num_cat_kw)
  
      # save `ylim` as they will be overwritten by `ax.vlines`
      ylim = ax.get_ylim() if pd_limits is None else pd_limits
  
      # add deciles markers to the bottom of the plot
      trans = transforms.blended_transform_factory(
          ax.transData, ax.transAxes
      )
      ax.vlines(feature_deciles[0][1:-1], 0, 0.05, transform=trans)
  
      ax.set_ylabel(exp.meta["params"]["target_names"][target_idx])
      ax.set_xlabel(feature_names[0])
      ax.legend()
      return ax, ylim
  
imports: import copy
  import logging
  import math
  import numbers
  import sys
  from abc import ABC, abstractmethod
  from enum import Enum
  from typing import Callable, Dict, Iterable, List, Optional, Tuple, Union, no_type_check
  import matplotlib.pyplot
  import numpy
  from scipy.stats.mstats import mquantiles
  from sklearn.base import BaseEstimator, is_classifier, is_regressor
  from sklearn.ensemble import RandomForestRegressor
  from sklearn.ensemble._gb import BaseGradientBoosting
  from sklearn.ensemble._hist_gradient_boosting.gradient_boosting import BaseHistGradientBoosting
  from sklearn.tree import DecisionTreeRegressor
  from sklearn.utils.extmath import cartesian
  from sklearn.utils.validation import check_is_fitted
  from tqdm import tqdm
  from alibi.api.defaults import DEFAULT_DATA_PD, DEFAULT_META_PD
  from alibi.api.interfaces import Explainer, Explanation
  from alibi.explainers.ale import get_quantiles
  from alibi.utils import _get_options_string
label_desc: Use image node_id 7 for calling a global function with example usage: _plot_two_pd_num_cat(exp, feature, target_idx, pd_limits, ax, pd_num_cat_kw) and returns: ax,  ylim, unknown