{"metadata":{"kernelspec":{"language":"python","display_name":"Python 3","name":"python3"},"language_info":{"pygments_lexer":"ipython3","nbconvert_exporter":"python","version":"3.6.4","file_extension":".py","codemirror_mode":{"name":"ipython","version":3},"name":"python","mimetype":"text/x-python"}},"nbformat_minor":4,"nbformat":4,"cells":[{"cell_type":"code","source":"# This Python 3 environment comes with many helpful analytics libraries installed\n# It is defined by the kaggle/python Docker image: https://github.com/kaggle/docker-python\n# For example, here's several helpful packages to load\n\nimport numpy as np # linear algebra\nimport pandas as pd # data processing, CSV file I/O (e.g. pd.read_csv)\n\n# Input data files are available in the read-only \"../input/\" directory\n# For example, running this (by clicking run or pressing Shift+Enter) will list all files under the input directory\n\nimport os\n# for dirname, _, filenames in os.walk('/kaggle/input'):\n#     for filename in filenames:\n#         print(os.path.join(dirname, filename))\n\n# You can write up to 20GB to the current directory (/kaggle/working/) that gets preserved as output when you create a version using \"Save & Run All\" \n# You can also write temporary files to /kaggle/temp/, but they won't be saved outside of the current session","metadata":{"_uuid":"8f2839f25d086af736a60e9eeb907d3b93b6e0e5","_cell_guid":"b1076dfc-b9ad-4769-8c92-a6c4dae69d19","execution":{"iopub.status.busy":"2023-06-26T08:58:19.565600Z","iopub.execute_input":"2023-06-26T08:58:19.566002Z","iopub.status.idle":"2023-06-26T08:58:19.571073Z","shell.execute_reply.started":"2023-06-26T08:58:19.565969Z","shell.execute_reply":"2023-06-26T08:58:19.570235Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"### Links\n- https://stackoverflow.com/questions/24458645/label-encoding-across-multiple-columns-in-scikit-learn\n- https://numpy.org/doc/stable/reference/generated/numpy.polyfit.html\n- https://www.tensorflow.org/api_docs/python/tf/keras/preprocessing/image/ImageDataGenerator\n- https://stackoverflow.com/questions/70080062/how-to-correctly-use-imagedatagenerator-in-keras","metadata":{"jupyter":{"source_hidden":true}}},{"cell_type":"markdown","source":"### Goal\n - Locate microvasculature structures (blood vessels) within human kidney histology slides.\n\n### Data Description \n-  tiles extracted from five Whole Slide Images (WSI) split into two datasets. Tiles from Dataset 1 have annotations that have been expert reviewed. Dataset 2 comprises the remaining tiles from these same WSIs and contain sparse annotations that have not been expert reviewed.\n\n- All of the test set tiles are from Dataset 1.\n- Two of the WSIs make up the training set, two WSIs make up the public test set, and one WSI makes up the private test set.\n- The training data includes Dataset 2 tiles from the public test WSI, but not from the private test WSI.","metadata":{}},{"cell_type":"code","source":"from PIL import Image\nimport matplotlib.pyplot as plt\nimport os\nimport keras\nfrom sklearn.model_selection import train_test_split\nimport tensorflow as tf\nimport cv2\nfrom keras import applications\nfrom keras.layers import Conv2D, MaxPooling2D, Flatten, Dense, Dropout, Input\nfrom keras.models import Model\nfrom keras.optimizers import Adam","metadata":{"execution":{"iopub.status.busy":"2023-06-26T08:58:22.665392Z","iopub.execute_input":"2023-06-26T08:58:22.665821Z","iopub.status.idle":"2023-06-26T08:58:22.672474Z","shell.execute_reply.started":"2023-06-26T08:58:22.665792Z","shell.execute_reply":"2023-06-26T08:58:22.671180Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"import csv\nimport tifffile\n\ndef merge_csv_tiff(csv_file, tiff_file, output_file):\n\n  with open(csv_file, \"r\") as csv_file:\n    reader = csv.reader(csv_file)\n    data = list(reader)\n\n  with tifffile.TiffFile(tiff_file, mode=\"r\") as tiff_file:\n    images = tiff_file.asarray()\n\n  # Merge the data and images.\n  merged_data = []\n  for i in range(len(data)):\n    merged_data.append(data[i] + [images[i]])\n\n  # Write the merged data to the output file.\n  with open(output_file, \"w\") as output_file:\n    writer = csv.writer(output_file)\n    writer.writerows(data)\n\nif __name__ == \"__main__\":\n  csv_file = \"/kaggle/input/hubmap-hacking-the-human-vasculature/wsi_meta.csv\"\n  tiff_file = \"/kaggle/input/hubmap-hacking-the-human-vasculature/train/00176a88fdb0.tif\"\n  output_file = \"wsi_meta.csv\"\n  merge_csv_tiff(csv_file, tiff_file, output_file)\n","metadata":{"execution":{"iopub.status.busy":"2023-06-26T08:58:24.494649Z","iopub.execute_input":"2023-06-26T08:58:24.495065Z","iopub.status.idle":"2023-06-26T08:58:24.519284Z","shell.execute_reply.started":"2023-06-26T08:58:24.495024Z","shell.execute_reply":"2023-06-26T08:58:24.518026Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"merge_csv_tiff(csv_file, tiff_file, output_file)","metadata":{"execution":{"iopub.status.busy":"2023-06-26T08:58:26.939064Z","iopub.execute_input":"2023-06-26T08:58:26.939463Z","iopub.status.idle":"2023-06-26T08:58:26.959317Z","shell.execute_reply.started":"2023-06-26T08:58:26.939420Z","shell.execute_reply":"2023-06-26T08:58:26.958316Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"def read_csv(csv_file):\n\n  with open(csv_file, \"r\") as csv_file:\n    reader = csv.reader(csv_file)\n    data = list(reader)\n\n  return data\n\nif __name__ == \"__main__\":\n  csv_file = \"/kaggle/working/wsi_meta.csv\"\n\n  wsi_meta = read_csv(csv_file)\n\n  for row in wsi_meta:\n    print(row)","metadata":{"execution":{"iopub.status.busy":"2023-06-26T08:58:28.428888Z","iopub.execute_input":"2023-06-26T08:58:28.429746Z","iopub.status.idle":"2023-06-26T08:58:28.436503Z","shell.execute_reply.started":"2023-06-26T08:58:28.429706Z","shell.execute_reply":"2023-06-26T08:58:28.435250Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"wsi_meta = pd.DataFrame(wsi_meta)\nwsi_meta.head()","metadata":{"execution":{"iopub.status.busy":"2023-06-26T08:58:30.772068Z","iopub.execute_input":"2023-06-26T08:58:30.772452Z","iopub.status.idle":"2023-06-26T08:58:30.787614Z","shell.execute_reply.started":"2023-06-26T08:58:30.772411Z","shell.execute_reply":"2023-06-26T08:58:30.786471Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"# Radar Chart\nimport pandas as pd\nimport matplotlib.pyplot as plt\n\n# df = pd.read_csv('data.csv')\n\n# Get the names of the columns\ncolumns = wsi_meta.columns\n\n# Create a radar chart\nplt.figure()\nax = plt.subplot(111, projection='polar')\n\n# Plot the data\nfor column in columns:\n    values = wsi_meta[column]\n    ax.plot(values, label=column)\n\n# Add labels to the axes\nplt.xticks(np.arange(len(columns)), columns, color='grey', size=12)\nax.tick_params(pad=10)\n\n# Fill the area of the polygon with blue and some transparency\nax.fill(values, color='blue', alpha=0.1)\n\n# Add a legend\nplt.legend()\n\n# Add a title\nplt.title('Chart')\n\n# Show the chart\nplt.show()","metadata":{"execution":{"iopub.status.busy":"2023-06-26T08:58:33.635160Z","iopub.execute_input":"2023-06-26T08:58:33.635555Z","iopub.status.idle":"2023-06-26T08:58:34.495802Z","shell.execute_reply.started":"2023-06-26T08:58:33.635526Z","shell.execute_reply":"2023-06-26T08:58:34.494581Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"wsi_meta.head()","metadata":{"execution":{"iopub.status.busy":"2023-06-26T08:58:38.044579Z","iopub.execute_input":"2023-06-26T08:58:38.044973Z","iopub.status.idle":"2023-06-26T08:58:38.059481Z","shell.execute_reply.started":"2023-06-26T08:58:38.044942Z","shell.execute_reply":"2023-06-26T08:58:38.058505Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"# import plotly.express as px\n\n# # Create a treemap\n# fig = px.treemap(wsi_meta, path=[\"1\"])\n\n# # Display the treemap\n# fig.show()","metadata":{"execution":{"iopub.status.busy":"2023-06-26T08:58:41.454014Z","iopub.execute_input":"2023-06-26T08:58:41.454428Z","iopub.status.idle":"2023-06-26T08:58:41.459605Z","shell.execute_reply.started":"2023-06-26T08:58:41.454396Z","shell.execute_reply":"2023-06-26T08:58:41.458504Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"data = pd.read_csv(\"/kaggle/input/hubmap-hacking-the-human-vasculature/wsi_meta.csv\")\ndata.head()","metadata":{"execution":{"iopub.status.busy":"2023-06-26T08:58:43.622137Z","iopub.execute_input":"2023-06-26T08:58:43.622514Z","iopub.status.idle":"2023-06-26T08:58:43.639877Z","shell.execute_reply.started":"2023-06-26T08:58:43.622486Z","shell.execute_reply":"2023-06-26T08:58:43.638737Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"from sklearn.preprocessing import LabelEncoder\nfrom sklearn.pipeline import Pipeline\nclass MultiColumnLabelEncoder:\n    def __init__(self,columns = None):\n        self.columns = columns # array of column names to encode\n\n    def fit(self,X,y=None):\n        return self # not relevant here\n\n    def transform(self,X):\n        '''\n        Transforms columns of X specified in self.columns using\n        LabelEncoder(). If no columns specified, transforms all\n        columns in X.\n        '''\n        output = X.copy()\n        if self.columns is not None:\n            for col in self.columns:\n                output[col] = LabelEncoder().fit_transform(output[col])\n        else:\n            for colname,col in output.iteritems():\n                output[colname] = LabelEncoder().fit_transform(col)\n        return output\n\n    def fit_transform(self,X,y=None):\n        return self.fit(X,y).transform(X)","metadata":{"execution":{"iopub.status.busy":"2023-06-26T08:58:49.635564Z","iopub.execute_input":"2023-06-26T08:58:49.635939Z","iopub.status.idle":"2023-06-26T08:58:49.643312Z","shell.execute_reply.started":"2023-06-26T08:58:49.635903Z","shell.execute_reply":"2023-06-26T08:58:49.642374Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"data = MultiColumnLabelEncoder(columns = ['sex','race','weight']).fit_transform(data)","metadata":{"execution":{"iopub.status.busy":"2023-06-26T08:58:52.343558Z","iopub.execute_input":"2023-06-26T08:58:52.343928Z","iopub.status.idle":"2023-06-26T08:58:52.354958Z","shell.execute_reply.started":"2023-06-26T08:58:52.343902Z","shell.execute_reply":"2023-06-26T08:58:52.353654Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"data.head()","metadata":{"execution":{"iopub.status.busy":"2023-06-26T08:58:53.893178Z","iopub.execute_input":"2023-06-26T08:58:53.893593Z","iopub.status.idle":"2023-06-26T08:58:53.906868Z","shell.execute_reply.started":"2023-06-26T08:58:53.893562Z","shell.execute_reply":"2023-06-26T08:58:53.905721Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"import numpy as np\nimport pandas as pd\nfrom sklearn.model_selection import train_test_split\nfrom sklearn.linear_model import LogisticRegression\nfrom sklearn.metrics import accuracy_score\n\n# Split the dataset into training and testing sets\nX_train, X_test, y_train, y_test = train_test_split(data, data[\"weight\"], test_size=0.25)\n\n# Create a logistic regression model\nmodel = LogisticRegression()\n\n# Train the model\nmodel.fit(X_train, y_train)\n\n# Evaluate the model\naccuracy = accuracy_score(y_test, model.predict(X_test))\n\n# Print the accuracy\nprint(\"Accuracy:\", accuracy)","metadata":{"execution":{"iopub.status.busy":"2023-06-26T08:58:59.669123Z","iopub.execute_input":"2023-06-26T08:58:59.669529Z","iopub.status.idle":"2023-06-26T08:58:59.698705Z","shell.execute_reply.started":"2023-06-26T08:58:59.669495Z","shell.execute_reply":"2023-06-26T08:58:59.697590Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"# !pip install scikit-learn==0.22.2.post1\n# !pip install yellowbrick==0.9.1","metadata":{"_kg_hide-output":true,"execution":{"iopub.status.busy":"2023-06-25T01:31:07.870560Z","iopub.execute_input":"2023-06-25T01:31:07.871295Z","iopub.status.idle":"2023-06-25T01:31:07.875931Z","shell.execute_reply.started":"2023-06-25T01:31:07.871259Z","shell.execute_reply":"2023-06-25T01:31:07.874391Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"import matplotlib.pyplot as plt\nfrom sklearn.datasets import load_digits\nfrom sklearn.linear_model import LogisticRegression\nfrom sklearn.metrics import confusion_matrix\n\n# Load the dataset of healthy human kidney tissue images\ndigits = load_digits()\n\nX_train, X_test, y_train, y_test = train_test_split(digits.data, digits.target, test_size=0.25)\n\nmodel = LogisticRegression()\n\nmodel.fit(X_train, y_train)\n\nscore = model.score(X_test, y_test)\n\n# Print the model accuracy\nprint(\"Model accuracy:\", score)\n\n# # Plot the confusion matrix\n# plt.matshow(model.confusion_matrix(X_test, y_test))\n# plt.title(\"Confusion matrix\")\n# plt.show()","metadata":{"execution":{"iopub.status.busy":"2023-06-26T08:59:13.382540Z","iopub.execute_input":"2023-06-26T08:59:13.383748Z","iopub.status.idle":"2023-06-26T08:59:13.642934Z","shell.execute_reply.started":"2023-06-26T08:59:13.383694Z","shell.execute_reply":"2023-06-26T08:59:13.641892Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"wsi_meta = pd.read_csv(\"/kaggle/input/hubmap-hacking-the-human-vasculature/wsi_meta.csv\")\nwsi_meta.head()","metadata":{"execution":{"iopub.status.busy":"2023-06-26T08:59:33.907294Z","iopub.execute_input":"2023-06-26T08:59:33.907732Z","iopub.status.idle":"2023-06-26T08:59:33.924158Z","shell.execute_reply.started":"2023-06-26T08:59:33.907703Z","shell.execute_reply":"2023-06-26T08:59:33.923216Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"tile_meta = pd.read_csv(\"/kaggle/input/hubmap-hacking-the-human-vasculature/tile_meta.csv\")\ntile_meta.head()","metadata":{"execution":{"iopub.status.busy":"2023-06-26T08:59:35.838832Z","iopub.execute_input":"2023-06-26T08:59:35.839231Z","iopub.status.idle":"2023-06-26T08:59:35.862803Z","shell.execute_reply.started":"2023-06-26T08:59:35.839200Z","shell.execute_reply":"2023-06-26T08:59:35.861882Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"# Merge the two dataframes on the 'Name' column\ndf = wsi_meta.merge(tile_meta, on='source_wsi')\n\nprint(df)","metadata":{"execution":{"iopub.status.busy":"2023-06-26T08:59:38.051858Z","iopub.execute_input":"2023-06-26T08:59:38.052267Z","iopub.status.idle":"2023-06-26T08:59:38.078276Z","shell.execute_reply.started":"2023-06-26T08:59:38.052234Z","shell.execute_reply":"2023-06-26T08:59:38.076972Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"df.plot()","metadata":{"execution":{"iopub.status.busy":"2023-06-26T08:59:40.928245Z","iopub.execute_input":"2023-06-26T08:59:40.928669Z","iopub.status.idle":"2023-06-26T08:59:41.516869Z","shell.execute_reply.started":"2023-06-26T08:59:40.928635Z","shell.execute_reply":"2023-06-26T08:59:41.515694Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"import os\n\nfolder_path = '../input/hubmap-hacking-the-human-vasculature/train/'\nfor dirname, _, filenames in os.walk(folder_path):\n    print(dirname)","metadata":{"execution":{"iopub.status.busy":"2023-06-26T08:59:44.064687Z","iopub.execute_input":"2023-06-26T08:59:44.065113Z","iopub.status.idle":"2023-06-26T08:59:46.062564Z","shell.execute_reply.started":"2023-06-26T08:59:44.065083Z","shell.execute_reply":"2023-06-26T08:59:46.061660Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"import PIL\nimport gc\nimport random\nimport tifffile\nimport cv2\nimport json\nimport seaborn as sns\nimport matplotlib.pyplot as plt\nimport numpy as np\nimport pandas as pd\nfrom PIL import Image\n\nimport warnings\nwarnings.filterwarnings(\"ignore\")\n\nPATH = \"../input/hubmap-hacking-the-human-vasculature\"\nPATH_TRAIN = PATH + \"train/\"\nPATH_TEST = PATH + \"test/\"","metadata":{"execution":{"iopub.status.busy":"2023-06-26T08:59:47.774775Z","iopub.execute_input":"2023-06-26T08:59:47.775426Z","iopub.status.idle":"2023-06-26T08:59:48.119432Z","shell.execute_reply.started":"2023-06-26T08:59:47.775387Z","shell.execute_reply":"2023-06-26T08:59:48.118356Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"# import os\n# for dirname, _, filenames in os.walk('/kaggle/input'):\n#     for filename in filenames:\n#         print(os.path.join(dirname, filename))","metadata":{"execution":{"iopub.status.busy":"2023-06-24T04:12:57.961672Z","iopub.execute_input":"2023-06-24T04:12:57.962035Z","iopub.status.idle":"2023-06-24T04:12:57.966809Z","shell.execute_reply.started":"2023-06-24T04:12:57.962005Z","shell.execute_reply":"2023-06-24T04:12:57.965783Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"import pandas as pd\nimport plotly.express as px\n\nfig = px.bar(df, x=\"weight\", y=\"bmi\", color=\"age\")\nfig.update_layout(\n    title=\"Bar Chart\",\n    xaxis_title=\"weight\",\n    yaxis_title=\"bmi\",\n    clickmode=None\n)\n\n# Display the plot\nfig.show()","metadata":{"execution":{"iopub.status.busy":"2023-06-26T08:59:52.141568Z","iopub.execute_input":"2023-06-26T08:59:52.142802Z","iopub.status.idle":"2023-06-26T08:59:54.316715Z","shell.execute_reply.started":"2023-06-26T08:59:52.142750Z","shell.execute_reply":"2023-06-26T08:59:54.315521Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"fig = px.pie(df, values=\"bmi\", names=\"sex\", color=\"race\")\nfig.update_layout(\n    title=\"Pie Chart\",\n    clickmode=None\n)\n\n# Display the plot\nfig.show()","metadata":{"execution":{"iopub.status.busy":"2023-06-25T01:36:50.912130Z","iopub.execute_input":"2023-06-25T01:36:50.912559Z","iopub.status.idle":"2023-06-25T01:36:51.049101Z","shell.execute_reply.started":"2023-06-25T01:36:50.912528Z","shell.execute_reply":"2023-06-25T01:36:51.047995Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"fig = px.histogram(df, x=\"bmi\", color=\"sex\")\nfig.update_layout(\n    title=\"Statistical Chart\",\n    xaxis_title=\"bmi\",\n    yaxis_title=\"Count\",\n    clickmode=None\n)\n\n# Display the plot\nfig.show()","metadata":{"execution":{"iopub.status.busy":"2023-06-26T09:00:00.708230Z","iopub.execute_input":"2023-06-26T09:00:00.708661Z","iopub.status.idle":"2023-06-26T09:00:00.837454Z","shell.execute_reply.started":"2023-06-26T09:00:00.708629Z","shell.execute_reply":"2023-06-26T09:00:00.836139Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"import pandas as pd\nimport matplotlib.pyplot as plt\n\n# Create a DataFrame\n# Calculate the correlation matrix\ncorr = df.corr()\n\n# Create a heatmap of the correlation matrix\nplt.matshow(corr)\nplt.title(\"Correlation Matrix\")\nplt.xticks(range(len(corr)), corr.columns, rotation=90)\nplt.yticks(range(len(corr)), corr.columns)\nplt.show()","metadata":{"execution":{"iopub.status.busy":"2023-06-26T09:00:03.446869Z","iopub.execute_input":"2023-06-26T09:00:03.447270Z","iopub.status.idle":"2023-06-26T09:00:03.713478Z","shell.execute_reply.started":"2023-06-26T09:00:03.447238Z","shell.execute_reply":"2023-06-26T09:00:03.712383Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"def charts_PerformanceSummary(returns):\n    '''\n    Implements the charts.PerformanceSummary function from R,\n    assuming geometrically compounded returns.\n    \n    Plots the cumulative return of all series, period returns of the leftmost return series,\n    and the drawdown charts of all series.\n\n    '''\n    if type(returns) == pd.Series:\n        returns = pd.DataFrame(returns)\n    \n    period = infer_trading_periods(returns)\n    \n    cumulative_wealth_index = compound_returns(returns)-1\n    drawdowns = Drawdowns(returns)\n        \n    # Creating a figure and subplots with shared x-axis\n    fig, axs = plt.subplots(3, 1, sharex=True, figsize=(8, 10))\n    \n    # Adjusting spacing between subplots\n    #fig.subplots_adjust(hspace=0.2)\n    \n    # Plotting cumulative wealth index\n    axs[0].plot(cumulative_wealth_index.index, cumulative_wealth_index.values, \n                label = returns.columns)\n    axs[0].grid(True)\n    axs[0].set_title('Cumulative Return', loc='left', fontweight='bold')\n    \n    # Plotting daily returns\n    if(type(returns)==pd.Series):\n        axs[1].plot(returns.index, returns.values)\n    else:\n        axs[1].plot(returns.index, returns.values[:,0])\n    axs[1].grid(True)\n    if(period==252):\n        axs[1].set_title('Daily Return', loc='left', fontweight='bold')\n    elif(period==52):\n        axs[1].set_title('Weekly Return', loc='left', fontweight='bold')\n    elif(period==12):\n        axs[1].set_title('Monthly Return', loc='left', fontweight='bold')\n    elif(period==4):\n        axs[1].set_title('Quarterly Return', loc='left', fontweight='bold')\n    elif(period==1):\n        axs[1].set_title('Yearly Return', loc='left', fontweight='bold')\n\n    # Plotting drawdowns\n    axs[2].plot(drawdowns.index, drawdowns.values)\n    axs[2].grid(True)\n    axs[2].set_title('Drawdown', loc='left', fontweight='bold')\n    \n    # Setting x-axis limit\n    last_data_point = len(cumulative_wealth_index) - 1\n    plt.xlim(cumulative_wealth_index.index[0], cumulative_wealth_index.index[last_data_point])\n    \n    # Adding a title to the figure\n    fig.suptitle('Performance Summary', fontsize=14, fontweight='bold')\n    \n    # Adding first and last timestamps string\n    first_timestamp = cumulative_wealth_index.index[0].strftime('%Y-%m-%d')\n    last_timestamp = cumulative_wealth_index.index[last_data_point].strftime('%Y-%m-%d')\n    time_string = f'{first_timestamp} / {last_timestamp}'\n    axs[0].text(1, 1.1, time_string, transform=axs[0].transAxes,\n                fontsize=12, fontweight='bold', color='black',\n                va='top', ha='right')\n    \n    if type(returns)==pd.DataFrame:\n    # Adding legend to the first plot\n        handles, labels = axs[0].get_legend_handles_labels()\n        labels = returns.columns\n        axs[0].legend(handles, labels, loc='upper left', frameon=True)\n    \n    # Displaying the plots\n    plt.show()","metadata":{"execution":{"iopub.status.busy":"2023-06-26T09:00:07.420931Z","iopub.execute_input":"2023-06-26T09:00:07.421323Z","iopub.status.idle":"2023-06-26T09:00:07.436059Z","shell.execute_reply.started":"2023-06-26T09:00:07.421292Z","shell.execute_reply":"2023-06-26T09:00:07.434804Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"","metadata":{},"execution_count":null,"outputs":[]}]}