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()

```

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

{"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"}]}