prompt: We are currently solving the following issue within our repository. Here is the issue text:
  --- BEGIN ISSUE ---
  Phi K correlation variable order
  For me all correlation plots show variables in the (domain-specific sensible) order of the columns in my data frame.
  
  Only Phi K shows them in some other order.
  
  Is this a bug or a feature?
  
  Is there a setting to get the "good" order?
  
  This is with pandas 1.3 and pandas-profiling 3.0.0
  
  <img width="879" alt="Screenshot 2021-09-05 at 21 43 55" src="https://user-images.githubusercontent.com/852409/132139566-ba92033b-98fb-4b3d-a869-6c096ed294a1.png">
  <img width="907" alt="Screenshot 2021-09-05 at 21 43 45" src="https://user-images.githubusercontent.com/852409/132139567-22e2d9ce-cdc8-4b95-93b2-7445a78ed397.png">
  
  
  --- END ISSUE ---
  
  Below are some code segments, each from a relevant file. One or more of these files may contain bugs.
  --- BEGIN FILES ---
  Path: `src/pandas_profiling/model/pandas/correlations_pandas.py`
  Content:
  ```
  1 """Correlations between variables."""
  2 import itertools
  3 import warnings
  4 from typing import Optional
  5 
  6 import numpy as np
  7 import pandas as pd
  8 from scipy import stats
  9 
  10 from pandas_profiling.config import Settings
  11 from pandas_profiling.model.correlations import (
  12     Cramers,
  13     Kendall,
  14     Pearson,
  15     PhiK,
  16     Spearman,
  17 )
  18 
  19 
  20 @Spearman.compute.register(Settings, pd.DataFrame, dict)
  21 def pandas_spearman_compute(
  22     config: Settings, df: pd.DataFrame, summary: dict
  23 ) -> Optional[pd.DataFrame]:
  24     return df.corr(method="spearman")
  25 
  26 
  27 @Pearson.compute.register(Settings, pd.DataFrame, dict)
  28 def pandas_pearson_compute(
  29     config: Settings, df: pd.DataFrame, summary: dict
  30 ) -> Optional[pd.DataFrame]:
  31     return df.corr(method="pearson")
  32 
  33 
  34 @Kendall.compute.register(Settings, pd.DataFrame, dict)
  35 def pandas_kendall_compute(
  36     config: Settings, df: pd.DataFrame, summary: dict
  37 ) -> Optional[pd.DataFrame]:
  38     return df.corr(method="kendall")
  39 
  40 
  41 def _cramers_corrected_stat(confusion_matrix: pd.DataFrame, correction: bool) -> float:
  42     """Calculate the Cramer's V corrected stat for two variables.
  43 
  44     Args:
  45         confusion_matrix: Crosstab between two variables.
  46         correction: Should the correction be applied?
  47 
  48     Returns:
  49         The Cramer's V corrected stat for the two variables.
  50     """
  51     chi2 = stats.chi2_contingency(confusion_matrix, correction=correction)[0]
  52     n = confusion_matrix.sum().sum()
  53     phi2 = chi2 / n
  54     r = confusion_matrix.shape[0]
  55     k = confusion_matrix.shape[1] if len(confusion_matrix.shape) > 1 else 1
  56 
  57     # Deal with NaNs later on
  58     with np.errstate(divide="ignore", invalid="ignore"):
  59         phi2corr = max(0.0, phi2 - ((k - 1.0) * (r - 1.0)) / (n - 1.0))
  60         rcorr = r - ((r - 1.0) ** 2.0) / (n - 1.0)
  61         kcorr = k - ((k - 1.0) ** 2.0) / (n - 1.0)
  62         rkcorr = min((kcorr - 1.0), (rcorr - 1.0))
  63         if rkcorr == 0.0:
  64             corr = 1.0
  65         else:
  66             corr = np.sqrt(phi2corr / rkcorr)
  67     return corr
  68 
  69 
  70 @Cramers.compute.register(Settings, pd.DataFrame, dict)
  71 def pandas_cramers_compute(
  72     config: Settings, df: pd.DataFrame, summary: dict
  73 ) -> Optional[pd.DataFrame]:
  74     threshold = config.categorical_maximum_correlation_distinct
  75 
  76     categoricals = {
  77         key
  78         for key, value in summary.items()
  79         if value["type"] in {"Categorical", "Boolean"}
  80         and value["n_distinct"] <= threshold
  81     }
  82 
  83     if len(categoricals) <= 1:
  84         return None
  85 
  86     matrix = np.zeros((len(categoricals), len(categoricals)))
  87     np.fill_diagonal(matrix, 1.0)
  88     correlation_matrix = pd.DataFrame(
  89         matrix,
  90         index=categoricals,
  91         columns=categoricals,
  92     )
  93 
  94     for name1, name2 in itertools.combinations(categoricals, 2):
  95         confusion_matrix = pd.crosstab(df[name1], df[name2])
  96         correlation_matrix.loc[name2, name1] = _cramers_corrected_stat(
  97             confusion_matrix, correction=True
  98         )
  99         correlation_matrix.loc[name1, name2] = correlation_matrix.loc[name2, name1]
  100     return correlation_matrix
  101 
  102 
  103 @PhiK.compute.register(Settings, pd.DataFrame, dict)
  104 def pandas_phik_compute(
  105     config: Settings, df: pd.DataFrame, summary: dict
  106 ) -> Optional[pd.DataFrame]:
  107     intcols = {
  108         key
  109         for key, value in summary.items()
  110         # DateTime currently excluded
  111         # In some use cases, it makes sense to convert it to interval
  112         # See https://github.com/KaveIO/PhiK/issues/7
  113         if value["type"] == "Numeric" and 1 < value["n_distinct"]
  114     }
  115 
  116     selcols = {
  117         key
  118         for key, value in summary.items()
  119         if value["type"] != "Unsupported"
  120         and 1 < value["n_distinct"] <= config.categorical_maximum_correlation_distinct
  121     }
  122     selcols = selcols.union(intcols)
  123 
  124     if len(selcols) <= 1:
  125         return None
  126 
  127     with warnings.catch_warnings():
  128         warnings.simplefilter("ignore")
  129         from phik import phik_matrix
  130 
  131         correlation = phik_matrix(df[selcols], interval_cols=list(intcols))
  132 
  133     return correlation
  134
  ```
  --- END FILES ---
  
  Please first localize the bug based on the issue statement, and then generate a patch according to the `git diff` format fenced by three backticks.
  
  Here is an example:
  
  ```diff
  diff --git a/examples/server_async.py b/examples/server_async.py
  --- a/examples/server_async.py
  +++ b/examples/server_async.py
  @@ -313,4 +313,4 @@
   
   
   if __name__ == "__main__":
  -    asyncio.run(run_async_server("."), debug=True)
  +    asyncio.run(run_async_server(), debug=True)
  diff --git a/examples/server_sync.py b/examples/server_sync.py
  --- a/examples/server_sync.py
  +++ b/examples/server_sync.py
  @@ -313,5 +313,5 @@
   
   
   if __name__ == "__main__":
  -    server = run_sync_server(".")
  +    server = run_sync_server()
       server.shutdown()
  
  ```
  
golden_diff: diff --git a/src/pandas_profiling/model/pandas/correlations_pandas.py b/src/pandas_profiling/model/pandas/correlations_pandas.py
  --- a/src/pandas_profiling/model/pandas/correlations_pandas.py
  +++ b/src/pandas_profiling/model/pandas/correlations_pandas.py
  @@ -104,6 +104,8 @@
   def pandas_phik_compute(
       config: Settings, df: pd.DataFrame, summary: dict
   ) -> Optional[pd.DataFrame]:
  +    df_cols_dict = {i: list(df.columns).index(i) for i in df.columns}
  +
       intcols = {
           key
           for key, value in summary.items()
  @@ -120,14 +122,15 @@
           and 1 < value["n_distinct"] <= config.categorical_maximum_correlation_distinct
       }
       selcols = selcols.union(intcols)
  +    selected_cols = sorted(selcols, key=lambda i: df_cols_dict[i])
   
  -    if len(selcols) <= 1:
  +    if len(selected_cols) <= 1:
           return None
   
       with warnings.catch_warnings():
           warnings.simplefilter("ignore")
           from phik import phik_matrix
   
  -        correlation = phik_matrix(df[selcols], interval_cols=list(intcols))
  +        correlation = phik_matrix(df[selected_cols], interval_cols=list(intcols))
   
       return correlation
  
verification_info: {"golden_diff": "diff --git a/src/pandas_profiling/model/pandas/correlations_pandas.py b/src/pandas_profiling/model/pandas/correlations_pandas.py\n--- a/src/pandas_profiling/model/pandas/correlations_pandas.py\n+++ b/src/pandas_profiling/model/pandas/correlations_pandas.py\n@@ -104,6 +104,8 @@\n def pandas_phik_compute(\n     config: Settings, df: pd.DataFrame, summary: dict\n ) -> Optional[pd.DataFrame]:\n+    df_cols_dict = {i: list(df.columns).index(i) for i in df.columns}\n+\n     intcols = {\n         key\n         for key, value in summary.items()\n@@ -120,14 +122,15 @@\n         and 1 < value[\"n_distinct\"] <= config.categorical_maximum_correlation_distinct\n     }\n     selcols = selcols.union(intcols)\n+    selected_cols = sorted(selcols, key=lambda i: df_cols_dict[i])\n \n-    if len(selcols) <= 1:\n+    if len(selected_cols) <= 1:\n         return None\n \n     with warnings.catch_warnings():\n         warnings.simplefilter(\"ignore\")\n         from phik import phik_matrix\n \n-        correlation = phik_matrix(df[selcols], interval_cols=list(intcols))\n+        correlation = phik_matrix(df[selected_cols], interval_cols=list(intcols))\n \n     return correlation\n", "issue": "Phi K correlation variable order\nFor me all correlation plots show variables in the (domain-specific sensible) order of the columns in my data frame.\r\n\r\nOnly Phi K shows them in some other order.\r\n\r\nIs this a bug or a feature?\r\n\r\nIs there a setting to get the \"good\" order?\r\n\r\nThis is with pandas 1.3 and pandas-profiling 3.0.0\r\n\r\n<img width=\"879\" alt=\"Screenshot 2021-09-05 at 21 43 55\" src=\"https://user-images.githubusercontent.com/852409/132139566-ba92033b-98fb-4b3d-a869-6c096ed294a1.png\">\r\n<img width=\"907\" alt=\"Screenshot 2021-09-05 at 21 43 45\" src=\"https://user-images.githubusercontent.com/852409/132139567-22e2d9ce-cdc8-4b95-93b2-7445a78ed397.png\">\r\n\n", "before_files": [{"content": "\"\"\"Correlations between variables.\"\"\"\nimport itertools\nimport warnings\nfrom typing import Optional\n\nimport numpy as np\nimport pandas as pd\nfrom scipy import stats\n\nfrom pandas_profiling.config import Settings\nfrom pandas_profiling.model.correlations import (\n    Cramers,\n    Kendall,\n    Pearson,\n    PhiK,\n    Spearman,\n)\n\n\n@Spearman.compute.register(Settings, pd.DataFrame, dict)\ndef pandas_spearman_compute(\n    config: Settings, df: pd.DataFrame, summary: dict\n) -> Optional[pd.DataFrame]:\n    return df.corr(method=\"spearman\")\n\n\n@Pearson.compute.register(Settings, pd.DataFrame, dict)\ndef pandas_pearson_compute(\n    config: Settings, df: pd.DataFrame, summary: dict\n) -> Optional[pd.DataFrame]:\n    return df.corr(method=\"pearson\")\n\n\n@Kendall.compute.register(Settings, pd.DataFrame, dict)\ndef pandas_kendall_compute(\n    config: Settings, df: pd.DataFrame, summary: dict\n) -> Optional[pd.DataFrame]:\n    return df.corr(method=\"kendall\")\n\n\ndef _cramers_corrected_stat(confusion_matrix: pd.DataFrame, correction: bool) -> float:\n    \"\"\"Calculate the Cramer's V corrected stat for two variables.\n\n    Args:\n        confusion_matrix: Crosstab between two variables.\n        correction: Should the correction be applied?\n\n    Returns:\n        The Cramer's V corrected stat for the two variables.\n    \"\"\"\n    chi2 = stats.chi2_contingency(confusion_matrix, correction=correction)[0]\n    n = confusion_matrix.sum().sum()\n    phi2 = chi2 / n\n    r = confusion_matrix.shape[0]\n    k = confusion_matrix.shape[1] if len(confusion_matrix.shape) > 1 else 1\n\n    # Deal with NaNs later on\n    with np.errstate(divide=\"ignore\", invalid=\"ignore\"):\n        phi2corr = max(0.0, phi2 - ((k - 1.0) * (r - 1.0)) / (n - 1.0))\n        rcorr = r - ((r - 1.0) ** 2.0) / (n - 1.0)\n        kcorr = k - ((k - 1.0) ** 2.0) / (n - 1.0)\n        rkcorr = min((kcorr - 1.0), (rcorr - 1.0))\n        if rkcorr == 0.0:\n            corr = 1.0\n        else:\n            corr = np.sqrt(phi2corr / rkcorr)\n    return corr\n\n\n@Cramers.compute.register(Settings, pd.DataFrame, dict)\ndef pandas_cramers_compute(\n    config: Settings, df: pd.DataFrame, summary: dict\n) -> Optional[pd.DataFrame]:\n    threshold = config.categorical_maximum_correlation_distinct\n\n    categoricals = {\n        key\n        for key, value in summary.items()\n        if value[\"type\"] in {\"Categorical\", \"Boolean\"}\n        and value[\"n_distinct\"] <= threshold\n    }\n\n    if len(categoricals) <= 1:\n        return None\n\n    matrix = np.zeros((len(categoricals), len(categoricals)))\n    np.fill_diagonal(matrix, 1.0)\n    correlation_matrix = pd.DataFrame(\n        matrix,\n        index=categoricals,\n        columns=categoricals,\n    )\n\n    for name1, name2 in itertools.combinations(categoricals, 2):\n        confusion_matrix = pd.crosstab(df[name1], df[name2])\n        correlation_matrix.loc[name2, name1] = _cramers_corrected_stat(\n            confusion_matrix, correction=True\n        )\n        correlation_matrix.loc[name1, name2] = correlation_matrix.loc[name2, name1]\n    return correlation_matrix\n\n\n@PhiK.compute.register(Settings, pd.DataFrame, dict)\ndef pandas_phik_compute(\n    config: Settings, df: pd.DataFrame, summary: dict\n) -> Optional[pd.DataFrame]:\n    intcols = {\n        key\n        for key, value in summary.items()\n        # DateTime currently excluded\n        # In some use cases, it makes sense to convert it to interval\n        # See https://github.com/KaveIO/PhiK/issues/7\n        if value[\"type\"] == \"Numeric\" and 1 < value[\"n_distinct\"]\n    }\n\n    selcols = {\n        key\n        for key, value in summary.items()\n        if value[\"type\"] != \"Unsupported\"\n        and 1 < value[\"n_distinct\"] <= config.categorical_maximum_correlation_distinct\n    }\n    selcols = selcols.union(intcols)\n\n    if len(selcols) <= 1:\n        return None\n\n    with warnings.catch_warnings():\n        warnings.simplefilter(\"ignore\")\n        from phik import phik_matrix\n\n        correlation = phik_matrix(df[selcols], interval_cols=list(intcols))\n\n    return correlation\n", "path": "src/pandas_profiling/model/pandas/correlations_pandas.py"}], "after_files": [{"content": "\"\"\"Correlations between variables.\"\"\"\nimport itertools\nimport warnings\nfrom typing import Optional\n\nimport numpy as np\nimport pandas as pd\nfrom scipy import stats\n\nfrom pandas_profiling.config import Settings\nfrom pandas_profiling.model.correlations import (\n    Cramers,\n    Kendall,\n    Pearson,\n    PhiK,\n    Spearman,\n)\n\n\n@Spearman.compute.register(Settings, pd.DataFrame, dict)\ndef pandas_spearman_compute(\n    config: Settings, df: pd.DataFrame, summary: dict\n) -> Optional[pd.DataFrame]:\n    return df.corr(method=\"spearman\")\n\n\n@Pearson.compute.register(Settings, pd.DataFrame, dict)\ndef pandas_pearson_compute(\n    config: Settings, df: pd.DataFrame, summary: dict\n) -> Optional[pd.DataFrame]:\n    return df.corr(method=\"pearson\")\n\n\n@Kendall.compute.register(Settings, pd.DataFrame, dict)\ndef pandas_kendall_compute(\n    config: Settings, df: pd.DataFrame, summary: dict\n) -> Optional[pd.DataFrame]:\n    return df.corr(method=\"kendall\")\n\n\ndef _cramers_corrected_stat(confusion_matrix: pd.DataFrame, correction: bool) -> float:\n    \"\"\"Calculate the Cramer's V corrected stat for two variables.\n\n    Args:\n        confusion_matrix: Crosstab between two variables.\n        correction: Should the correction be applied?\n\n    Returns:\n        The Cramer's V corrected stat for the two variables.\n    \"\"\"\n    chi2 = stats.chi2_contingency(confusion_matrix, correction=correction)[0]\n    n = confusion_matrix.sum().sum()\n    phi2 = chi2 / n\n    r = confusion_matrix.shape[0]\n    k = confusion_matrix.shape[1] if len(confusion_matrix.shape) > 1 else 1\n\n    # Deal with NaNs later on\n    with np.errstate(divide=\"ignore\", invalid=\"ignore\"):\n        phi2corr = max(0.0, phi2 - ((k - 1.0) * (r - 1.0)) / (n - 1.0))\n        rcorr = r - ((r - 1.0) ** 2.0) / (n - 1.0)\n        kcorr = k - ((k - 1.0) ** 2.0) / (n - 1.0)\n        rkcorr = min((kcorr - 1.0), (rcorr - 1.0))\n        if rkcorr == 0.0:\n            corr = 1.0\n        else:\n            corr = np.sqrt(phi2corr / rkcorr)\n    return corr\n\n\n@Cramers.compute.register(Settings, pd.DataFrame, dict)\ndef pandas_cramers_compute(\n    config: Settings, df: pd.DataFrame, summary: dict\n) -> Optional[pd.DataFrame]:\n    threshold = config.categorical_maximum_correlation_distinct\n\n    categoricals = {\n        key\n        for key, value in summary.items()\n        if value[\"type\"] in {\"Categorical\", \"Boolean\"}\n        and value[\"n_distinct\"] <= threshold\n    }\n\n    if len(categoricals) <= 1:\n        return None\n\n    matrix = np.zeros((len(categoricals), len(categoricals)))\n    np.fill_diagonal(matrix, 1.0)\n    correlation_matrix = pd.DataFrame(\n        matrix,\n        index=categoricals,\n        columns=categoricals,\n    )\n\n    for name1, name2 in itertools.combinations(categoricals, 2):\n        confusion_matrix = pd.crosstab(df[name1], df[name2])\n        correlation_matrix.loc[name2, name1] = _cramers_corrected_stat(\n            confusion_matrix, correction=True\n        )\n        correlation_matrix.loc[name1, name2] = correlation_matrix.loc[name2, name1]\n    return correlation_matrix\n\n\n@PhiK.compute.register(Settings, pd.DataFrame, dict)\ndef pandas_phik_compute(\n    config: Settings, df: pd.DataFrame, summary: dict\n) -> Optional[pd.DataFrame]:\n    df_cols_dict = {i: list(df.columns).index(i) for i in df.columns}\n\n    intcols = {\n        key\n        for key, value in summary.items()\n        # DateTime currently excluded\n        # In some use cases, it makes sense to convert it to interval\n        # See https://github.com/KaveIO/PhiK/issues/7\n        if value[\"type\"] == \"Numeric\" and 1 < value[\"n_distinct\"]\n    }\n\n    selcols = {\n        key\n        for key, value in summary.items()\n        if value[\"type\"] != \"Unsupported\"\n        and 1 < value[\"n_distinct\"] <= config.categorical_maximum_correlation_distinct\n    }\n    selcols = selcols.union(intcols)\n    selected_cols = sorted(selcols, key=lambda i: df_cols_dict[i])\n\n    if len(selected_cols) <= 1:\n        return None\n\n    with warnings.catch_warnings():\n        warnings.simplefilter(\"ignore\")\n        from phik import phik_matrix\n\n        correlation = phik_matrix(df[selected_cols], interval_cols=list(intcols))\n\n    return correlation\n", "path": "src/pandas_profiling/model/pandas/correlations_pandas.py"}]}