diff --git a/docs/index.xml b/docs/index.xml
index 3ba2550..11d513b 100644
--- a/docs/index.xml
+++ b/docs/index.xml
@@ -10,7 +10,400 @@
Practice in Codequarto-1.3.450
-Mon, 08 Jan 2024 16:00:00 GMT
+Wed, 10 Jan 2024 16:00:00 GMT
+
+ py50 - Showing off Color Features
+ Tony E. Lin
+ https://tlint101.github.io/practice-in-code/posts/7-py50-additional-features.html
+ Last post I gave a quick rundown of py50. Here I would like to explain additional features, mainly color and highlighting options.
+
When it comes to figures, I think they are one of the more difficult aspects of writing a paper. A good figure must be many things. It must not only convey to the audience what was done, but also the outcome and our own interpretation said results. The figures are also a chance to add a bit of pizazz to the manuscript or presentation. There is nothing wrong with the classic black and white figures, but they can come across as stilted and boring, especially now in 2024 were many manuscripts are downloaded and read as PDFs. Adding additional flourishes to highlight our points with a dash of color will allow our personality, and by extension the research we are trying to convey, to shine.
+
py50 offers some of these functions that will, hopefully, allow the figures and results to pop. While py50 offers three different plotting styles, the colors and highlighting options stay the same across the functions. I will show a few examples across all three plot styles.
+
For those who want to get their hands dirty immediately, the functions are explained in more detail at the documentation page
+
+
Example with Single Plot
+
In addition to the typical configurations for a plot shown here - Plot Title and axis labels - the curve color can be adjusted. This takes the standard name of the color names (red, green, blue, etc) or hex codes. Further, users can highlight IC50 values on the curve using the ‘box=True’ argument. By default, the box will be gray. Again, the box color can be adjusted using the color names or hex codes. Importantly, the box does not need to correspond with the IC50. If you wanted to highlight a different area, say IC60, the box can be adjusted accordingly using the ‘box_intercept’ argument.
+
All information associated with the plots can be generated using the verbose=True argument. This will print out information related to the plot, consisting of what drug concentration py50 assumes the data is in, what concentration the X-axis will be in (default is in nM), and the concentration and response for the box.
Drug 1 concentration will be in nM!
+Concentration on X-axis will be in nM
+Box X intersection: 880.204 nM
+Box Y intersection: 60 %
+
+
+
+
+
+
For those who do not like the box but still want to highlight a particular value on the curve, there are ‘vline’ or ‘hline’ arguments. This will draw a dash line across the length of the plot. It is valid for both vertical and horizontal directions.
+
+
figure = data.single_curve_plot(drug_name='Drug 1',
+ concentration_col='Compound Conc',
+ response_col='% Inhibition Avg',
+ plot_title='Modified Single Curve in Hulk Colors',
+ xlabel='Concentration in nM',
+ ylabel='Response %',
+ line_color='green',
+ hline=50,
+ hline_color='purple')
+
+
+
+
+
+
+
Example with Multiple Curves
+
Depending on the situation, it may be more prudent to show multiple curves in a single plot. That can be done using the multi_curve_plot() function. Again, the options shown here are available in all three plots. By default, the multi_curve_plot() uses a colorblind color and marker palette, but custom colors and markers can be passed as a list.
Notice that some points above are below the 0% response. Depending on your dataset, these may be outliers. These can be shown by adjusting the Y axis using either the ymax or ymin arguments.
+
With multiple lines in the plot, it may be more prudent to highlight the response. The box can be drawn, but can only be drawn for a specific drug. In this case, the vline or hline arguments would serve better. Here a specific concentration is highlighted instead. The units for the vline must correspond to the plot units. In this case, the vline will be in nanomolar (nM) concentration. Colors can also be specified using the vline_color or hline_color, repsectively.
+
This example uses the vline at 880.2 nM, which roughly translates to the IC50 value for Drug 3.
Finally, multiple curves can be plotted and arrayed in a grid. Importantly, the grid_curve_plot() function contains an additional argument - column_num. This argument will format the curves accordingly. Note the number of curves must be even if you want to array the curves in a grid format. For now, the example will utilize four graphs.
+
By default, the grid curves are arrayed in a color-blind palette. They can be changed by inputting a color in a list format.
+
We can reposition how the plots are laid out using the “column_num=” argument. Note that if this argument is called, the figures will be “distroted”. The subplots can be adjusted by including the “figsize=” argument and adjusting the size accordingly.
+
By default, the grid_curve_plot() was figure size is adjusted for two cures. As a result, the figsize is adjusted manually in these examples.
Finally, A specific point on the curve can be highlighted using the box or the hline/vline arguments. The box will be plotted for each curve. The figures can be further modified to add a title, adjust the line colors similarly to the examples seen above.
These are some of the features with the plots generated from py50.
+
This is a great project for me personally and I learned a lot of making py50. I plan to maintain py50 for the foreseeable future. There are a couple of feature ideas swimming in my head that I would love to include in future releases.
+
Finally, for anyone who is not as well versed in code, there is a web application version of py50 (click here). The updates for the program takes a little more time, as I tend to tinker a bit more with UI stuff. But overall, it works fairly well and will get you the calculations and plots needed.
+
If you find any issues with py50, feel free to leave a comment on the GitHub repository.
In addition to the typical configurations for a plot shown here - Plot Title and axis labels - the curve color can be adjusted. This takes the standard name of the color names (red, green, blue, etc) or hex codes. Further, users can highlight IC50 values on the curve using the ‘box=True’ argument. By default, the box will be gray. Again, the box color can be adjusted using the color names or hex codes. Importantly, the box does not need to correspond with the IC50. If you wanted to highlight a different area, say IC60, the box can be adjusted accordingly using the ‘box_intercept’ argument.
All information associated with the plots can be generated using the verbose=True argument. This will print out information related to the plot, consisting of what drug concentration py50 assumes the data is in, what concentration the X-axis will be in (default is in nM), and the concentration and response for the box.
-
-
import pandas as pd
-from py50.plotcurve import PlotCurve
Drug 1 concentration will be in nM!
Concentration on X-axis will be in nM
@@ -239,63 +235,63 @@
Example with Sing
Box Y intersection: 60 %
-
+
For those who do not like the box but still want to highlight a particular value on the curve, there are ‘vline’ or ‘hline’ arguments. This will draw a dash line across the length of the plot. It is valid for both vertical and horizontal directions.
-
-
figure = data.single_curve_plot(drug_name='Drug 1',
- concentration_col='Compound Conc',
- response_col='% Inhibition Avg',
- plot_title='Modified Single Curve in Hulk Colors',
- xlabel='Concentration in nM',
- ylabel='Response %',
- line_color='green',
- hline=50,
- hline_color='purple')
+
+
figure = data.single_curve_plot(drug_name='Drug 1',
+ concentration_col='Compound Conc',
+ response_col='% Inhibition Avg',
+ plot_title='Modified Single Curve in Hulk Colors',
+ xlabel='Concentration in nM',
+ ylabel='Response %',
+ line_color='green',
+ hline=50,
+ hline_color='purple')
-
+
Example with Multiple Curves
Depending on the situation, it may be more prudent to show multiple curves in a single plot. That can be done using the multi_curve_plot() function. Again, the options shown here are available in all three plots. By default, the multi_curve_plot() uses a colorblind color and marker palette, but custom colors and markers can be passed as a list.
Notice that some points above are below the 0% response. Depending on your dataset, these may be outliers. These can be shown by adjusting the Y axis using either the ymax or ymin arguments.
With multiple lines in the plot, it may be more prudent to highlight the response. The box can be drawn, but can only be drawn for a specific drug. In this case, the vline or hline arguments would serve better. Here a specific concentration is highlighted instead. The units for the vline must correspond to the plot units. In this case, the vline will be in nanomolar (nM) concentration. Colors can also be specified using the vline_color or hline_color, repsectively.
This example uses the vline at 880.2 nM, which roughly translates to the IC50 value for Drug 3.
By default, the grid curves are arrayed in a color-blind palette. They can be changed by inputting a color in a list format.
We can reposition how the plots are laid out using the “column_num=” argument. Note that if this argument is called, the figures will be “distroted”. The subplots can be adjusted by including the “figsize=” argument and adjusting the size accordingly.
By default, the grid_curve_plot() was figure size is adjusted for two cures. As a result, the figsize is adjusted manually in these examples.
Finally, A specific point on the curve can be highlighted using the box or the hline/vline arguments. The box will be plotted for each curve. The figures can be further modified to add a title, adjust the line colors similarly to the examples seen above.
diff --git a/docs/posts/7-py50-additional-features_files/figure-html/cell-3-output-2.png b/docs/posts/7-py50-additional-features_files/figure-html/cell-2-output-2.png
similarity index 100%
rename from docs/posts/7-py50-additional-features_files/figure-html/cell-3-output-2.png
rename to docs/posts/7-py50-additional-features_files/figure-html/cell-2-output-2.png
diff --git a/docs/posts/7-py50-additional-features_files/figure-html/cell-3-output-1.png b/docs/posts/7-py50-additional-features_files/figure-html/cell-3-output-1.png
new file mode 100644
index 0000000..3bca991
Binary files /dev/null and b/docs/posts/7-py50-additional-features_files/figure-html/cell-3-output-1.png differ
diff --git a/docs/posts/7-py50-additional-features_files/figure-html/cell-4-output-1.png b/docs/posts/7-py50-additional-features_files/figure-html/cell-4-output-1.png
index 3bca991..8be5a0c 100644
Binary files a/docs/posts/7-py50-additional-features_files/figure-html/cell-4-output-1.png and b/docs/posts/7-py50-additional-features_files/figure-html/cell-4-output-1.png differ
diff --git a/docs/posts/7-py50-additional-features_files/figure-html/cell-5-output-1.png b/docs/posts/7-py50-additional-features_files/figure-html/cell-5-output-1.png
index 8be5a0c..47e56c0 100644
Binary files a/docs/posts/7-py50-additional-features_files/figure-html/cell-5-output-1.png and b/docs/posts/7-py50-additional-features_files/figure-html/cell-5-output-1.png differ
diff --git a/docs/posts/7-py50-additional-features_files/figure-html/cell-6-output-1.png b/docs/posts/7-py50-additional-features_files/figure-html/cell-6-output-1.png
index 47e56c0..98b418a 100644
Binary files a/docs/posts/7-py50-additional-features_files/figure-html/cell-6-output-1.png and b/docs/posts/7-py50-additional-features_files/figure-html/cell-6-output-1.png differ
diff --git a/docs/posts/7-py50-additional-features_files/figure-html/cell-7-output-1.png b/docs/posts/7-py50-additional-features_files/figure-html/cell-7-output-1.png
index 98b418a..b4534fc 100644
Binary files a/docs/posts/7-py50-additional-features_files/figure-html/cell-7-output-1.png and b/docs/posts/7-py50-additional-features_files/figure-html/cell-7-output-1.png differ
diff --git a/docs/posts/7-py50-additional-features_files/figure-html/cell-8-output-1.png b/docs/posts/7-py50-additional-features_files/figure-html/cell-8-output-1.png
deleted file mode 100644
index b4534fc..0000000
Binary files a/docs/posts/7-py50-additional-features_files/figure-html/cell-8-output-1.png and /dev/null differ
diff --git a/docs/posts/8-absolute-ic50_files/figure-html/cell-10-output-2.png b/docs/posts/8-absolute-ic50_files/figure-html/cell-10-output-2.png
new file mode 100644
index 0000000..b7492bb
Binary files /dev/null and b/docs/posts/8-absolute-ic50_files/figure-html/cell-10-output-2.png differ
diff --git a/docs/posts/8-absolute-ic50_files/figure-html/cell-13-output-2.png b/docs/posts/8-absolute-ic50_files/figure-html/cell-13-output-2.png
new file mode 100644
index 0000000..4c0c961
Binary files /dev/null and b/docs/posts/8-absolute-ic50_files/figure-html/cell-13-output-2.png differ
diff --git a/docs/posts/8-absolute-ic50_files/figure-html/cell-4-output-2.png b/docs/posts/8-absolute-ic50_files/figure-html/cell-4-output-2.png
new file mode 100644
index 0000000..1b0efe1
Binary files /dev/null and b/docs/posts/8-absolute-ic50_files/figure-html/cell-4-output-2.png differ
diff --git a/docs/posts/8-absolute-ic50_files/figure-html/cell-5-output-1.png b/docs/posts/8-absolute-ic50_files/figure-html/cell-5-output-1.png
deleted file mode 100644
index e652c3b..0000000
Binary files a/docs/posts/8-absolute-ic50_files/figure-html/cell-5-output-1.png and /dev/null differ
diff --git a/docs/posts/8-absolute-ic50_files/figure-html/cell-6-output-2.png b/docs/posts/8-absolute-ic50_files/figure-html/cell-6-output-2.png
new file mode 100644
index 0000000..c34ec5d
Binary files /dev/null and b/docs/posts/8-absolute-ic50_files/figure-html/cell-6-output-2.png differ
diff --git a/docs/posts/8-absolute-ic50_files/figure-html/cell-7-output-1.png b/docs/posts/8-absolute-ic50_files/figure-html/cell-7-output-1.png
deleted file mode 100644
index 946c5e0..0000000
Binary files a/docs/posts/8-absolute-ic50_files/figure-html/cell-7-output-1.png and /dev/null differ
diff --git a/docs/posts/8-absolute-ic50_files/figure-html/cell-9-output-2.png b/docs/posts/8-absolute-ic50_files/figure-html/cell-9-output-2.png
new file mode 100644
index 0000000..ad73989
Binary files /dev/null and b/docs/posts/8-absolute-ic50_files/figure-html/cell-9-output-2.png differ
diff --git a/docs/posts/9-IC50_or_pIC50.html b/docs/posts/9-IC50_or_pIC50.html
new file mode 100644
index 0000000..07f30d2
--- /dev/null
+++ b/docs/posts/9-IC50_or_pIC50.html
@@ -0,0 +1,664 @@
+
+
+
+
+
+
+
+
+
+
+
+Practice in Code - IC50 or pIC50?
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
IC50 or pIC50?
+
Where we look at scales
+
+
small-molecules
+
drug discovery
+
Informatics
+
+
+
+
+
+
+
+
+
Author
+
+
Tony E. Lin
+
+
+
+
+
Published
+
+
January 18, 2024
+
+
+
+
+
+
+
+
+
+
+
IC50 or pIC50?
+
One of the hardest things in the lab is not the experiments itself, but the representation of the results. There are multitudes of ways to represent information. One of the most difficult is IC50.
+
+
# Import packages
+import pandas as pd
+import matplotlib.pyplot as plt
+from py50.calculator import Calculator
+from py50.plotcurve import PlotCurve
+
+
+
+
+
\ No newline at end of file
diff --git a/docs/search.json b/docs/search.json
index 6d45fb6..b60afac 100644
--- a/docs/search.json
+++ b/docs/search.json
@@ -1,45 +1,10 @@
[
{
- "objectID": "posts/2-hello-world-goals.html",
- "href": "posts/2-hello-world-goals.html",
- "title": "Hello World - Now With Goals!",
- "section": "",
- "text": "Hello World - Now with Goals\nHello everyone. My name is Tony. I am currently in a Ph.D. program for drug discovery in Taiwan. Why Taiwan? Well, a series of life choices fresh from university led me there. I did not get a start into my field of study overnight. I am a late bloomer. And still learning. Or at least trying to!\nI specialize in cheminformatics - using computers to sort and categorize molecules. There’s a lot of good software out there that can help anyone interested into getting into the field. That includes both paid versions, such as Schrodiner’s Maestro, or open source software such as the wonderful suite available from the University of Hamburg. Those tools are great! But I quickly realized that relying on software, as good as they can be, can be very limiting. What if I have an idea that does not fit the available software? What if I want to make modifications to the figures I make? What if I want to try a new screening protocol? There is only one way to do these things - coding! And learning to code requires a lot of practice.\nI know that with experience. I have tried learning ot code multiple times in my life. Each time I have failed. There is a whole host of reasons. Maybe the language I chose was not for me. Java, is great, but at the time I can barely wrap my head around it. I tried making a small iOS app in the early days of the iPhone, which used UIKit. No dice. When Apple transitioned into Swift UI, I thought “Great! A new start!” Only to fail horribly.\nIt was not until I got into the Ph.D. program (and again, I started late!) that I finally tried and… well I did not succeed, but I got way further than before.\nWhat helped was having a project and actually sticking with it. Well, what really helped is that I found a lot of examples online tackling similar problems I had. People writing about their code, sharing new tools and packages, and how to solve them. All of this helped make things simple enough for me to at least get started.\nFor that, I am forever grateful.\nThat brings me to this blog. I will use it as a place to practice coding, my thinking and thought processes, what I am interested in, and hopefully, as a way to share with others.\nThis will be my way of paying it forward.\nAnd barring that, it will be a good place to showcase my failures to the world. I’m ok with that too."
- },
- {
- "objectID": "posts/5-egg-on-my-face.html",
- "href": "posts/5-egg-on-my-face.html",
- "title": "Egg On My Face",
- "section": "",
- "text": "Well I have egg on my face. Rotten eggs, so that they are unsalvageable to be used in scrambled eggs.\nHere is the story. In my earlier post I announced and in the last post I gave an example on how to use the program in python. Everything worked! The thing is, it worked for my datasets. When I shared this code/program with my co-workers/labmates, my program quickly crumbled like a dusty cracker. It is a good thing that I placed it as version 0.1.0. I am currently in the process of fixing the bugs and I hope to finish it sometime in the new year (Hey, a New Year’s resolution I might actually finish for once!).\nI will be sure to give updates and tutorials on the program once I finish.\nIf you would like to use the program now, I push out updates faster to the Streamlit version of py50 (see here). This web application is for my co-workers/labmates, but I hope others are able to find it and find it useful too.\nIn the meantime, I’ll be working on fixing these bugs and refactoring the code so that it will be a little bit easier to fix in the future (you’re welcome future me).\nThanks!"
- },
- {
- "objectID": "index.html",
- "href": "index.html",
- "title": "Practice in Code",
- "section": "",
- "text": "🫣 Welcome to a blog on coding, cheminformatics, or other thoughts swimming in my head.💭\n\n\n\n\n\n\n\n \n \n \n Order By\n Default\n \n Title\n \n \n Date - Oldest\n \n \n Date - Newest\n \n \n \n \n \n \n \n\n\n\n\n \n\n\n\n\npy50 - Now with Updates!\n\n\n\n\n\n\n\n\n\nJan 9, 2024\n\n\nTony E. Lin\n\n\n5 min\n\n\n\n\n\n\n \n\n\n\n\nEgg On My Face\n\n\nWhere I scramble to fix my program\n\n\n\n\n\n\nDec 20, 2023\n\n\nTony E. Lin\n\n\n2 min\n\n\n\n\n\n\n \n\n\n\n\npy50: Single Curve Plot\n\n\n\n\n\n\n\n\n\nDec 7, 2023\n\n\nTony E. Lin\n\n\n5 min\n\n\n\n\n\n\n \n\n\n\n\nAnnouncing py50!\n\n\n\n\n\n\n\n\n\nDec 5, 2023\n\n\nTony E. Lin\n\n\n3 min\n\n\n\n\n\n\n \n\n\n\n\nHello World - Now With Goals!\n\n\n\n\n\n\n\n\n\nDec 2, 2023\n\n\nTony E. Lin\n\n\n3 min\n\n\n\n\n\n\n \n\n\n\n\nHello World!\n\n\n\n\n\n\n\n\n\nNov 29, 2023\n\n\nTony E. Lin\n\n\n1 min\n\n\n\n\n\n\nNo matching items"
- },
- {
- "objectID": "about.html",
- "href": "about.html",
- "title": "About",
- "section": "",
- "text": "Github\n \n\n \nHi! 👋\nMy name is Tony and I write this blog. I am currently in a Ph.D. program for drug discovery in Taiwan. Why Taiwan? Well, a series of life choices fresh from university led me there, but I did not start the program until late. I am, what you would call, a late bloomer. And still learning!\nI will treat this as a place to practice code and share my thinking and thought processes.\nYou can find the repository for this site here.\nAny posts with code on this site will be packaged in a Jupyter Notebook and can be found here\nThanks for visiting!"
- },
- {
- "objectID": "posts/4-py50-single-plot.html",
- "href": "posts/4-py50-single-plot.html",
- "title": "py50: Single Curve Plot",
- "section": "",
- "text": "Generate Single Dose-Response Curve\nThe following will demo how to calculate the IC50 for a given drug response and generate single dose-response curve.\nThis tutorial will use dummy data found under the ‘../dataset’ folder. The calculation requires inputs from a DataFrame. As shown, only specific information is needed to run the calculations. Finally, the information will be plotted on a sigmoidal curve.\nFor those interested, this notebook can be found here\nAnd if you are not well versed in python code, good news! I have converted this python app into a web application. You can access it here\nNote - December 11 Edit: I shared my package with my classmates and coworkers. All seemed well until someone tried to make a fancy negative sigmoidal curve (from 100% to 0%). I tested my code on my own dataset which has a positive sigmoidal curve (from 0% to 100%). As such, I had to spend time fixing things. It has come out and the next post will address these issues.\n\nExample start\nFirst import the modules and the dataset.\n\nimport pandas as pd\nfrom py50.calculate import Calculate\nfrom py50.plotcurve import PlotCurve\n\n\ndf = pd.read_csv('datasets/py50/single_example.csv')\ndf.head()\n\n\n\n\n\n\n\n\nCompound Name\nCompound Conc\n% Inhibition 1\n% Inhibition 2\n% Inhibition Avg\n\n\n\n\n0\nDrug 1\n100000.0\n90\n94\n92\n\n\n1\nDrug 1\n33300.0\n97\n89\n93\n\n\n2\nDrug 1\n11100.0\n86\n89\n88\n\n\n3\nDrug 1\n3700.0\n81\n88\n84\n\n\n4\nDrug 1\n1240.0\n63\n70\n67\n\n\n\n\n\n\n\n\n\nCalculate IC50\nThe example dataframe will need to be converted into an instance of the Calculate class. Once converted, the table can also be printed for viewing and checking.\n\ndata = Calculate(df)\ndata.show().head()\n\n\n\n\n\n\n\n\nCompound Name\nCompound Conc\n% Inhibition 1\n% Inhibition 2\n% Inhibition Avg\n\n\n\n\n0\nDrug 1\n100000.0\n90\n94\n92\n\n\n1\nDrug 1\n33300.0\n97\n89\n93\n\n\n2\nDrug 1\n11100.0\n86\n89\n88\n\n\n3\nDrug 1\n3700.0\n81\n88\n84\n\n\n4\nDrug 1\n1240.0\n63\n70\n67\n\n\n\n\n\n\n\nCurrently, the py50 program requires the at least 3 columns as input. The rest of the columns will be ignored. py50 requires a column containing the following: - Drug Name - Concentration - Average Response\nNote that py50 requires the average response. Though if you would like to calculate IC50 for one trial of a drug, that is possible.\nThe names for the corresponding columns can be passed in the “calculate_ic50()” function as follows:\n\nic50 = data.calculate_ic50(name_col='Compound Name', concentration_col='Compound Conc', response_col='% Inhibition Avg')\nic50\n\n\n\n\n\n\n\n\ncompound_name\nmaximum\nminimum\nic50 (nM)\nhill_slope\n\n\n\n\n0\nDrug 1\n92.854428\n-7.640263\n439.823988\n1.040875\n\n\n\n\n\n\n\nWhere the maximum and minimum corresponds to the maximum and minimum response. The Hill slope is the hill coefficient. This table can be output as a separate .csv file. For this tutorial, we will output the final table as a markdown table.\nNOTE: The calculation in this table is the Relative IC50 value. A future post will tackle Relative vs Absolute IC50.\n\n\nPlotting\npy50 contains functions that will allow plotting. Let’s generate a sigmoidal curve from the dataset. This time the dataframe will need to be instantiated into the PlotCurve class. From there, the dataset will be calculated and the resulting information will be ploted on a graph.\n\nplot_data = PlotCurve(df)\n# The input dataset can be inspected as follows:\ndata.show().head()\n\n\n\n\n\n\n\n\nCompound Name\nCompound Conc\n% Inhibition 1\n% Inhibition 2\n% Inhibition Avg\n\n\n\n\n0\nDrug 1\n100000.0\n90\n94\n92\n\n\n1\nDrug 1\n33300.0\n97\n89\n93\n\n\n2\nDrug 1\n11100.0\n86\n89\n88\n\n\n3\nDrug 1\n3700.0\n81\n88\n84\n\n\n4\nDrug 1\n1240.0\n63\n70\n67\n\n\n\n\n\n\n\nFor this example, plotting the dose-response curve uses the single_curve_plot() function. By default, py50 will assume drug concentrations are in nanomolar (nM) concentration and will convert them into micromolar (µM) concentrations. This will also mean that the final scale on the x-axis will be in µM. As the dosages for a typical test vary greatly in concentrations, the scale of the concentration will be in log format by default. However, depending on user needs, these can be changed.\nAdditional parameters and their explanation can be found here.\nFirst. Here we will call the “single_curve_plot” method with the associated parameters:\n\nfigure = plot_data.single_curve_plot(concentration_col='Compound Conc',\n response_col='% Inhibition Avg',\n plot_title='Default Plot',\n drug_name='Drug 1',\n xlabel='Logarithmic Concentration (µM)',\n ylabel='Inhibition %',\n legend=True,\n output_filename=None)\n\nConcentration on X-axis converted to µM\n\n\n\n\n\n\n\nCustomize figure\nThe above figure looks great! But what if I do not like black for the line color? I would much prefer Teal (#008080). Good news! There are several ways to adjust the graph to highlight the information you want to convey. For colors, we will start with the “line_color=” parameter. The line color can be a specific color name (i.e. red, blue, green, etc) or a hex code. Here is an example of a colored line in “teal” (#008080)\n\nfigure = plot_data.single_curve_plot(concentration_col='Compound Conc',\n response_col='% Inhibition Avg',\n plot_title='Plot with Colored Lines',\n drug_name='Drug 1',\n xlabel='Logarithmic Concentration (µM)',\n ylabel='Inhibition %',\n line_color='#008080',\n legend=True,\n output_filename=None)\n\nConcentration on X-axis converted to µM\n\n\n\n\n\nThat doesn’t look half bad! But what if you want to highlight the IC50 value? That would give people a quick way to identify where the IC50 lies on the curve. That can be achieved using the “box=” parameter. The box argument is a boolean argument and by default it will draw a box at the 50% response with respect to the curve.\n\nfigure = plot_data.single_curve_plot(concentration_col='Compound Conc',\n response_col='% Inhibition Avg',\n plot_title='Plot with Colored Lines',\n drug_name='Drug 1',\n xlabel='Logarithmic Concentration (µM)',\n ylabel='Inhibition %',\n line_color='#008080',\n box=True,\n legend=True,\n output_filename=None)\n\nConcentration on X-axis converted to µM\n\n\n\n\n\nThe box highlight can be further modified for color and specific response position you may be interested in. For example, what if you want the box to be red and also highlight IC\\(_{60}\\) or IC\\(_{90}\\)? This can be achieved by using the “box_intercept=” and “box_color=” parameters\n\nfigure = plot_data.single_curve_plot(concentration_col='Compound Conc',\n response_col='% Inhibition Avg',\n plot_title='Plot with More Colors!',\n drug_name='Drug 1',\n xlabel='Logarithmic Concentration (µM)',\n ylabel='Inhibition %',\n line_color='#008080',\n box=True,\n box_intercept=60,\n box_color='red',\n legend=True,\n output_filename=None)\n\nConcentration on X-axis converted to µM\n\n\n\n\n\nFinally, the x-axis can be further adjusted.\nThe scale can be changed from log to linear using the “xscale=” argument, changing the shape of the curve from sigmoid to a normal curve. The units of the scale can be changed to nM using the “xscale_unit=” argument. Currently only µM and nM is used.\n\nfigure = plot_data.single_curve_plot(concentration_col='Compound Conc',\n response_col='% Inhibition Avg',\n plot_title='A Linear Plot',\n drug_name='Drug 1',\n xlabel='Logarithmic Concentration (nM)',\n ylabel='Inhibition %',\n line_color='#008080',\n box=False,\n legend=True,\n xscale='linear',\n xscale_unit='nM',\n xscale_ticks=(-2.5, 10),\n output_filename=None)\n\nConcentration on X-axis is in nM\nnM with ticks constraints!\n\n\n\n\n\nFor this dataset, the “xscale=‘linear’” does not look as good.\nAlso notice how on the linear plot the xscale_ticks was also adjusted to fit the concentration in nM scale. This was achieved using the “xscale_ticks=” argument. Note that the xscale_ticks will affect how the line curve is drawn and should be adjusted to fit the dataset on the plot. Notice how the plot below has the xscale_ticks ranging from 0 to 2 and how it would affect the resulting curve line.\n\nfigure = plot_data.single_curve_plot(concentration_col='Compound Conc',\n response_col='% Inhibition Avg',\n plot_title='X-Axis is Set to nM',\n drug_name='Drug 1',\n xlabel='Logarithmic Concentration (nM)',\n ylabel='Inhibition %',\n line_color='#008080',\n box=True,\n box_color='orange',\n legend=True,\n xscale='log',\n xscale_unit='nM',\n xscale_ticks=(0, 2),\n output_filename=None)\n\nConcentration on X-axis is in nM\nnM with ticks constraints!\n\n\n\n\n\n\n\nSaving the figure\nFinally, the figure can be saved using the “output_filename=” argument. Change “None” to file path of choice. Images should be saved in .png format.\n\nfigure = plot_data.single_curve_plot(concentration_col='Compound Conc',\n response_col='% Inhibition Avg',\n plot_title='X-Axis is Set to nM',\n drug_name='Drug 1',\n xlabel='Logarithmic Concentration (nM)',\n ylabel='Inhibition %',\n line_color='#008080',\n box=True,\n box_color='orange',\n legend=True,\n xscale='log',\n xscale_unit='µM',\n xscale_ticks=(-2.5, 2.5),\n output_filename=None)\n\nConcentration on X-axis converted to µM\nµM with ticks constraints!\n\n\n\n\n\nAdditionally, the figure can also be saved as follows:\n\nfigure.savefig('tutorial_figure_001.png')\n\nAnd that should be it!\nThis is my first “big” python project and I learned a lot from it. I know I should clean up the code in the future, but for now, I’m glad to have it up and running! I plan on maintaining this for the foreseeable future. I hope it helps others as much as it has helped me!"
- },
- {
- "objectID": "posts/1-hello-world.html",
- "href": "posts/1-hello-world.html",
- "title": "Hello World!",
+ "objectID": "posts/3-announcing-py50.html",
+ "href": "posts/3-announcing-py50.html",
+ "title": "Announcing py50!",
"section": "",
- "text": "Hello World!"
+ "text": "py50: Generate Dose-Response Curves\nI would like to announce a new project I have been working on: py50: Generate Dose-Response Curves. It is the first “big” python project that I have worked on. This package will calculate IC50 (py50, get it? … Anyone?) and will plot the dose-response curves. And for anyone who does not know how to code, I created a Streamlit web application(click here). I hope others will be able to find this useful for their own work.\n\nWhy did I make py50?\nWell, this was mostly for myself. I am lucky to be in a lab that has close collaborations with other labs, meaning that my work can quickly be shared with experts in other areas. They will generate the dose-response curves for me. But sometimes when I organize my figures, I realized that the curves do not fit my style. The color does not match my docking pose, or my protein, or the font could be bigger, etc. Now, I could ask them to change it, but I do not like to be a burden on people. They spent a lot of time doing this work, the least I could do is learn the program they used to generate plot, right?\nWell, the truth is I hate using their program (which I will not name here)!\nSo I went about creating my own. As a python module, it can be customizable to anyone’s workflow. The outcome is perfect for me. After I showed this to my advisor, he made the comment that it would be good for others to use. And I realized that I could easily convert the code for this purpose.\nFor py50, I have a KNIME workflow. That is available upon request. It is not as elegant, as they are not custom KNIME nodes, so I am a little more reserved in sharing that workflow. Another issue with KNIME is that it would require the user to have python installed on their machine. I realized that could be a hassle. So I also created a Streamlit web application. Using Streamlit has been on my list of things to try for a very long time, and I am glad that with my py50 project, I was able to do that.\nThe code is not perfect. There is a lot that I need to clean up on the backend. But for what I have, it works and I learned a lot. I am very surprised I got a decent package up and running. The plan is to maintain this for the foreseeable future. And, if the inspiration is right, I will add some extra features over the coming years.\nThe next few posts will dive into details about py50, the functions, and concepts of IC50 that I ran into."
},
{
"objectID": "posts/6-py50-QuickStart.html",
@@ -98,10 +63,80 @@
"text": "Conclusion\nThat is it!\nThis is my first very big (in my eyes) python project and I learned a lot. Hopefully the pacakge can help others too.\nAnd for anyone reading this who are not code savvy, I have converted py50 into a web application using streamlit. It can be found here. The update may be a little bit slower, as managing UI takes a bit more time, but hopefully this makes py50 more accessible to people.\nThanks for reading. 🙌"
},
{
- "objectID": "posts/3-announcing-py50.html",
- "href": "posts/3-announcing-py50.html",
- "title": "Announcing py50!",
+ "objectID": "posts/1-hello-world.html",
+ "href": "posts/1-hello-world.html",
+ "title": "Hello World!",
"section": "",
- "text": "py50: Generate Dose-Response Curves\nI would like to announce a new project I have been working on: py50: Generate Dose-Response Curves. It is the first “big” python project that I have worked on. This package will calculate IC50 (py50, get it? … Anyone?) and will plot the dose-response curves. And for anyone who does not know how to code, I created a Streamlit web application(click here). I hope others will be able to find this useful for their own work.\n\nWhy did I make py50?\nWell, this was mostly for myself. I am lucky to be in a lab that has close collaborations with other labs, meaning that my work can quickly be shared with experts in other areas. They will generate the dose-response curves for me. But sometimes when I organize my figures, I realized that the curves do not fit my style. The color does not match my docking pose, or my protein, or the font could be bigger, etc. Now, I could ask them to change it, but I do not like to be a burden on people. They spent a lot of time doing this work, the least I could do is learn the program they used to generate plot, right?\nWell, the truth is I hate using their program (which I will not name here)!\nSo I went about creating my own. As a python module, it can be customizable to anyone’s workflow. The outcome is perfect for me. After I showed this to my advisor, he made the comment that it would be good for others to use. And I realized that I could easily convert the code for this purpose.\nFor py50, I have a KNIME workflow. That is available upon request. It is not as elegant, as they are not custom KNIME nodes, so I am a little more reserved in sharing that workflow. Another issue with KNIME is that it would require the user to have python installed on their machine. I realized that could be a hassle. So I also created a Streamlit web application. Using Streamlit has been on my list of things to try for a very long time, and I am glad that with my py50 project, I was able to do that.\nThe code is not perfect. There is a lot that I need to clean up on the backend. But for what I have, it works and I learned a lot. I am very surprised I got a decent package up and running. The plan is to maintain this for the foreseeable future. And, if the inspiration is right, I will add some extra features over the coming years.\nThe next few posts will dive into details about py50, the functions, and concepts of IC50 that I ran into."
+ "text": "Hello World!"
+ },
+ {
+ "objectID": "posts/4-py50-single-plot.html",
+ "href": "posts/4-py50-single-plot.html",
+ "title": "py50: Single Curve Plot",
+ "section": "",
+ "text": "Generate Single Dose-Response Curve\nThe following will demo how to calculate the IC50 for a given drug response and generate single dose-response curve.\nThis tutorial will use dummy data found under the ‘../dataset’ folder. The calculation requires inputs from a DataFrame. As shown, only specific information is needed to run the calculations. Finally, the information will be plotted on a sigmoidal curve.\nFor those interested, this notebook can be found here\nAnd if you are not well versed in python code, good news! I have converted this python app into a web application. You can access it here\nNote - December 11 Edit: I shared my package with my classmates and coworkers. All seemed well until someone tried to make a fancy negative sigmoidal curve (from 100% to 0%). I tested my code on my own dataset which has a positive sigmoidal curve (from 0% to 100%). As such, I had to spend time fixing things. It has come out and the next post will address these issues.\n\nExample start\nFirst import the modules and the dataset.\n\nimport pandas as pd\nfrom py50.calculate import Calculate\nfrom py50.plotcurve import PlotCurve\n\n\ndf = pd.read_csv('datasets/py50/single_example.csv')\ndf.head()\n\n\n\n\n\n\n\n\nCompound Name\nCompound Conc\n% Inhibition 1\n% Inhibition 2\n% Inhibition Avg\n\n\n\n\n0\nDrug 1\n100000.0\n90\n94\n92\n\n\n1\nDrug 1\n33300.0\n97\n89\n93\n\n\n2\nDrug 1\n11100.0\n86\n89\n88\n\n\n3\nDrug 1\n3700.0\n81\n88\n84\n\n\n4\nDrug 1\n1240.0\n63\n70\n67\n\n\n\n\n\n\n\n\n\nCalculate IC50\nThe example dataframe will need to be converted into an instance of the Calculate class. Once converted, the table can also be printed for viewing and checking.\n\ndata = Calculate(df)\ndata.show().head()\n\n\n\n\n\n\n\n\nCompound Name\nCompound Conc\n% Inhibition 1\n% Inhibition 2\n% Inhibition Avg\n\n\n\n\n0\nDrug 1\n100000.0\n90\n94\n92\n\n\n1\nDrug 1\n33300.0\n97\n89\n93\n\n\n2\nDrug 1\n11100.0\n86\n89\n88\n\n\n3\nDrug 1\n3700.0\n81\n88\n84\n\n\n4\nDrug 1\n1240.0\n63\n70\n67\n\n\n\n\n\n\n\nCurrently, the py50 program requires the at least 3 columns as input. The rest of the columns will be ignored. py50 requires a column containing the following: - Drug Name - Concentration - Average Response\nNote that py50 requires the average response. Though if you would like to calculate IC50 for one trial of a drug, that is possible.\nThe names for the corresponding columns can be passed in the “calculate_ic50()” function as follows:\n\nic50 = data.calculate_ic50(name_col='Compound Name', concentration_col='Compound Conc', response_col='% Inhibition Avg')\nic50\n\n\n\n\n\n\n\n\ncompound_name\nmaximum\nminimum\nic50 (nM)\nhill_slope\n\n\n\n\n0\nDrug 1\n92.854428\n-7.640263\n439.823988\n1.040875\n\n\n\n\n\n\n\nWhere the maximum and minimum corresponds to the maximum and minimum response. The Hill slope is the hill coefficient. This table can be output as a separate .csv file. For this tutorial, we will output the final table as a markdown table.\nNOTE: The calculation in this table is the Relative IC50 value. A future post will tackle Relative vs Absolute IC50.\n\n\nPlotting\npy50 contains functions that will allow plotting. Let’s generate a sigmoidal curve from the dataset. This time the dataframe will need to be instantiated into the PlotCurve class. From there, the dataset will be calculated and the resulting information will be ploted on a graph.\n\nplot_data = PlotCurve(df)\n# The input dataset can be inspected as follows:\ndata.show().head()\n\n\n\n\n\n\n\n\nCompound Name\nCompound Conc\n% Inhibition 1\n% Inhibition 2\n% Inhibition Avg\n\n\n\n\n0\nDrug 1\n100000.0\n90\n94\n92\n\n\n1\nDrug 1\n33300.0\n97\n89\n93\n\n\n2\nDrug 1\n11100.0\n86\n89\n88\n\n\n3\nDrug 1\n3700.0\n81\n88\n84\n\n\n4\nDrug 1\n1240.0\n63\n70\n67\n\n\n\n\n\n\n\nFor this example, plotting the dose-response curve uses the single_curve_plot() function. By default, py50 will assume drug concentrations are in nanomolar (nM) concentration and will convert them into micromolar (µM) concentrations. This will also mean that the final scale on the x-axis will be in µM. As the dosages for a typical test vary greatly in concentrations, the scale of the concentration will be in log format by default. However, depending on user needs, these can be changed.\nAdditional parameters and their explanation can be found here.\nFirst. Here we will call the “single_curve_plot” method with the associated parameters:\n\nfigure = plot_data.single_curve_plot(concentration_col='Compound Conc',\n response_col='% Inhibition Avg',\n plot_title='Default Plot',\n drug_name='Drug 1',\n xlabel='Logarithmic Concentration (µM)',\n ylabel='Inhibition %',\n legend=True,\n output_filename=None)\n\nConcentration on X-axis converted to µM\n\n\n\n\n\n\n\nCustomize figure\nThe above figure looks great! But what if I do not like black for the line color? I would much prefer Teal (#008080). Good news! There are several ways to adjust the graph to highlight the information you want to convey. For colors, we will start with the “line_color=” parameter. The line color can be a specific color name (i.e. red, blue, green, etc) or a hex code. Here is an example of a colored line in “teal” (#008080)\n\nfigure = plot_data.single_curve_plot(concentration_col='Compound Conc',\n response_col='% Inhibition Avg',\n plot_title='Plot with Colored Lines',\n drug_name='Drug 1',\n xlabel='Logarithmic Concentration (µM)',\n ylabel='Inhibition %',\n line_color='#008080',\n legend=True,\n output_filename=None)\n\nConcentration on X-axis converted to µM\n\n\n\n\n\nThat doesn’t look half bad! But what if you want to highlight the IC50 value? That would give people a quick way to identify where the IC50 lies on the curve. That can be achieved using the “box=” parameter. The box argument is a boolean argument and by default it will draw a box at the 50% response with respect to the curve.\n\nfigure = plot_data.single_curve_plot(concentration_col='Compound Conc',\n response_col='% Inhibition Avg',\n plot_title='Plot with Colored Lines',\n drug_name='Drug 1',\n xlabel='Logarithmic Concentration (µM)',\n ylabel='Inhibition %',\n line_color='#008080',\n box=True,\n legend=True,\n output_filename=None)\n\nConcentration on X-axis converted to µM\n\n\n\n\n\nThe box highlight can be further modified for color and specific response position you may be interested in. For example, what if you want the box to be red and also highlight IC\\(_{60}\\) or IC\\(_{90}\\)? This can be achieved by using the “box_intercept=” and “box_color=” parameters\n\nfigure = plot_data.single_curve_plot(concentration_col='Compound Conc',\n response_col='% Inhibition Avg',\n plot_title='Plot with More Colors!',\n drug_name='Drug 1',\n xlabel='Logarithmic Concentration (µM)',\n ylabel='Inhibition %',\n line_color='#008080',\n box=True,\n box_intercept=60,\n box_color='red',\n legend=True,\n output_filename=None)\n\nConcentration on X-axis converted to µM\n\n\n\n\n\nFinally, the x-axis can be further adjusted.\nThe scale can be changed from log to linear using the “xscale=” argument, changing the shape of the curve from sigmoid to a normal curve. The units of the scale can be changed to nM using the “xscale_unit=” argument. Currently only µM and nM is used.\n\nfigure = plot_data.single_curve_plot(concentration_col='Compound Conc',\n response_col='% Inhibition Avg',\n plot_title='A Linear Plot',\n drug_name='Drug 1',\n xlabel='Logarithmic Concentration (nM)',\n ylabel='Inhibition %',\n line_color='#008080',\n box=False,\n legend=True,\n xscale='linear',\n xscale_unit='nM',\n xscale_ticks=(-2.5, 10),\n output_filename=None)\n\nConcentration on X-axis is in nM\nnM with ticks constraints!\n\n\n\n\n\nFor this dataset, the “xscale=‘linear’” does not look as good.\nAlso notice how on the linear plot the xscale_ticks was also adjusted to fit the concentration in nM scale. This was achieved using the “xscale_ticks=” argument. Note that the xscale_ticks will affect how the line curve is drawn and should be adjusted to fit the dataset on the plot. Notice how the plot below has the xscale_ticks ranging from 0 to 2 and how it would affect the resulting curve line.\n\nfigure = plot_data.single_curve_plot(concentration_col='Compound Conc',\n response_col='% Inhibition Avg',\n plot_title='X-Axis is Set to nM',\n drug_name='Drug 1',\n xlabel='Logarithmic Concentration (nM)',\n ylabel='Inhibition %',\n line_color='#008080',\n box=True,\n box_color='orange',\n legend=True,\n xscale='log',\n xscale_unit='nM',\n xscale_ticks=(0, 2),\n output_filename=None)\n\nConcentration on X-axis is in nM\nnM with ticks constraints!\n\n\n\n\n\n\n\nSaving the figure\nFinally, the figure can be saved using the “output_filename=” argument. Change “None” to file path of choice. Images should be saved in .png format.\n\nfigure = plot_data.single_curve_plot(concentration_col='Compound Conc',\n response_col='% Inhibition Avg',\n plot_title='X-Axis is Set to nM',\n drug_name='Drug 1',\n xlabel='Logarithmic Concentration (nM)',\n ylabel='Inhibition %',\n line_color='#008080',\n box=True,\n box_color='orange',\n legend=True,\n xscale='log',\n xscale_unit='µM',\n xscale_ticks=(-2.5, 2.5),\n output_filename=None)\n\nConcentration on X-axis converted to µM\nµM with ticks constraints!\n\n\n\n\n\nAdditionally, the figure can also be saved as follows:\n\nfigure.savefig('tutorial_figure_001.png')\n\nAnd that should be it!\nThis is my first “big” python project and I learned a lot from it. I know I should clean up the code in the future, but for now, I’m glad to have it up and running! I plan on maintaining this for the foreseeable future. I hope it helps others as much as it has helped me!"
+ },
+ {
+ "objectID": "about.html",
+ "href": "about.html",
+ "title": "About",
+ "section": "",
+ "text": "Github\n \n\n \nHi! 👋\nMy name is Tony and I write this blog. I am currently in a Ph.D. program for drug discovery in Taiwan. Why Taiwan? Well, a series of life choices fresh from university led me there, but I did not start the program until late. I am, what you would call, a late bloomer. And still learning!\nI will treat this as a place to practice code and share my thinking and thought processes.\nYou can find the repository for this site here.\nAny posts with code on this site will be packaged in a Jupyter Notebook and can be found here\nThanks for visiting!"
+ },
+ {
+ "objectID": "index.html",
+ "href": "index.html",
+ "title": "Practice in Code",
+ "section": "",
+ "text": "🫣 Welcome to a blog on coding, cheminformatics, or other thoughts swimming in my head.💭\n\n\n\n\n\n\n\n \n \n \n Order By\n Default\n \n Title\n \n \n Date - Oldest\n \n \n Date - Newest\n \n \n \n \n \n \n \n\n\n\n\n \n\n\n\n\npy50 - Showing off Color Features\n\n\nWhere I add personality to figures\n\n\n\n\n\n\nJan 11, 2024\n\n\nTony E. Lin\n\n\n5 min\n\n\n\n\n\n\n \n\n\n\n\npy50 - Now with Updates!\n\n\n\n\n\n\n\n\n\nJan 9, 2024\n\n\nTony E. Lin\n\n\n5 min\n\n\n\n\n\n\n \n\n\n\n\nEgg On My Face\n\n\nWhere I scramble to fix my program\n\n\n\n\n\n\nDec 20, 2023\n\n\nTony E. Lin\n\n\n2 min\n\n\n\n\n\n\n \n\n\n\n\npy50: Single Curve Plot\n\n\n\n\n\n\n\n\n\nDec 7, 2023\n\n\nTony E. Lin\n\n\n5 min\n\n\n\n\n\n\n \n\n\n\n\nAnnouncing py50!\n\n\n\n\n\n\n\n\n\nDec 5, 2023\n\n\nTony E. Lin\n\n\n3 min\n\n\n\n\n\n\n \n\n\n\n\nHello World - Now With Goals!\n\n\n\n\n\n\n\n\n\nDec 2, 2023\n\n\nTony E. Lin\n\n\n3 min\n\n\n\n\n\n\n \n\n\n\n\nHello World!\n\n\n\n\n\n\n\n\n\nNov 29, 2023\n\n\nTony E. Lin\n\n\n1 min\n\n\n\n\n\n\nNo matching items"
+ },
+ {
+ "objectID": "posts/7-py50-additional-features.html",
+ "href": "posts/7-py50-additional-features.html",
+ "title": "py50 - Showing off Color Features",
+ "section": "",
+ "text": "Last post I gave a quick rundown of py50. Here I would like to explain additional features, mainly color and highlighting options.\nWhen it comes to figures, I think they are one of the more difficult aspects of writing a paper. A good figure must be many things. It must not only convey to the audience what was done, but also the outcome and our own interpretation said results. The figures are also a chance to add a bit of pizazz to the manuscript or presentation. There is nothing wrong with the classic black and white figures, but they can come across as stilted and boring, especially now in 2024 were many manuscripts are downloaded and read as PDFs. Adding additional flourishes to highlight our points with a dash of color will allow our personality, and by extension the research we are trying to convey, to shine.\npy50 offers some of these functions that will, hopefully, allow the figures and results to pop. While py50 offers three different plotting styles, the colors and highlighting options stay the same across the functions. I will show a few examples across all three plot styles.\nFor those who want to get their hands dirty immediately, the functions are explained in more detail at the documentation page"
+ },
+ {
+ "objectID": "posts/7-py50-additional-features.html#example-with-single-plot",
+ "href": "posts/7-py50-additional-features.html#example-with-single-plot",
+ "title": "py50 - Showing off Color Features",
+ "section": "Example with Single Plot",
+ "text": "Example with Single Plot\nIn addition to the typical configurations for a plot shown here - Plot Title and axis labels - the curve color can be adjusted. This takes the standard name of the color names (red, green, blue, etc) or hex codes. Further, users can highlight IC50 values on the curve using the ‘box=True’ argument. By default, the box will be gray. Again, the box color can be adjusted using the color names or hex codes. Importantly, the box does not need to correspond with the IC50. If you wanted to highlight a different area, say IC60, the box can be adjusted accordingly using the ‘box_intercept’ argument.\nAll information associated with the plots can be generated using the verbose=True argument. This will print out information related to the plot, consisting of what drug concentration py50 assumes the data is in, what concentration the X-axis will be in (default is in nM), and the concentration and response for the box.\n\ndf = pd.read_csv('datasets/py50/single_example.csv')\ndata = PlotCurve(df)\n\nfigure = data.single_curve_plot(drug_name='Drug 1',\n concentration_col='Compound Conc',\n response_col='% Inhibition Avg',\n plot_title='Modified Single Curve',\n xlabel='Concentration in nM',\n ylabel='Response %',\n line_color='teal',\n box=True,\n box_color='#E0115F',\n box_intercept=60,\n verbose=True)\n\nDrug 1 concentration will be in nM!\nConcentration on X-axis will be in nM\nBox X intersection: 880.204 nM\nBox Y intersection: 60 %\n\n\n\n\n\nFor those who do not like the box but still want to highlight a particular value on the curve, there are ‘vline’ or ‘hline’ arguments. This will draw a dash line across the length of the plot. It is valid for both vertical and horizontal directions.\n\nfigure = data.single_curve_plot(drug_name='Drug 1',\n concentration_col='Compound Conc',\n response_col='% Inhibition Avg',\n plot_title='Modified Single Curve in Hulk Colors',\n xlabel='Concentration in nM',\n ylabel='Response %',\n line_color='green',\n hline=50,\n hline_color='purple')"
+ },
+ {
+ "objectID": "posts/7-py50-additional-features.html#example-with-multiple-curves",
+ "href": "posts/7-py50-additional-features.html#example-with-multiple-curves",
+ "title": "py50 - Showing off Color Features",
+ "section": "Example with Multiple Curves",
+ "text": "Example with Multiple Curves\nDepending on the situation, it may be more prudent to show multiple curves in a single plot. That can be done using the multi_curve_plot() function. Again, the options shown here are available in all three plots. By default, the multi_curve_plot() uses a colorblind color and marker palette, but custom colors and markers can be passed as a list.\n\ndf = pd.read_csv('datasets/py50/multiple_example.csv')\ndata = PlotCurve(df)\n\nrainbow = ['#ff0000', '#ffa500', '#008000', '#ee82ee']\n\nfigure = data.multi_curve_plot(name_col='Compound Name',\n concentration_col='Compound Conc',\n response_col='% Inhibition Avg',\n plot_title='Multi-Curves in Rainbow',\n xlabel='Concentration (nM)',\n ylabel='Response',\n legend=True,\n line_color=rainbow)\n\n\n\n\nNotice that some points above are below the 0% response. Depending on your dataset, these may be outliers. These can be shown by adjusting the Y axis using either the ymax or ymin arguments.\nWith multiple lines in the plot, it may be more prudent to highlight the response. The box can be drawn, but can only be drawn for a specific drug. In this case, the vline or hline arguments would serve better. Here a specific concentration is highlighted instead. The units for the vline must correspond to the plot units. In this case, the vline will be in nanomolar (nM) concentration. Colors can also be specified using the vline_color or hline_color, repsectively.\nThis example uses the vline at 880.2 nM, which roughly translates to the IC50 value for Drug 3.\n\nfigure = data.multi_curve_plot(name_col='Compound Name',\n concentration_col='Compound Conc',\n response_col='% Inhibition Avg',\n plot_title='Multi-Curves in Rainbow',\n xlabel='Concentration (nM)',\n ylabel='Response',\n legend=True,\n line_color=rainbow,\n ymin=-10,\n vline=880.2,\n vline_color='blue')"
+ },
+ {
+ "objectID": "posts/7-py50-additional-features.html#example-with-grid-plots",
+ "href": "posts/7-py50-additional-features.html#example-with-grid-plots",
+ "title": "py50 - Showing off Color Features",
+ "section": "Example with Grid Plots",
+ "text": "Example with Grid Plots\nFinally, multiple curves can be plotted and arrayed in a grid. Importantly, the grid_curve_plot() function contains an additional argument - column_num. This argument will format the curves accordingly. Note the number of curves must be even if you want to array the curves in a grid format. For now, the example will utilize four graphs.\nBy default, the grid curves are arrayed in a color-blind palette. They can be changed by inputting a color in a list format.\nWe can reposition how the plots are laid out using the “column_num=” argument. Note that if this argument is called, the figures will be “distroted”. The subplots can be adjusted by including the “figsize=” argument and adjusting the size accordingly.\nBy default, the grid_curve_plot() was figure size is adjusted for two cures. As a result, the figsize is adjusted manually in these examples.\n\nfigure = data.grid_curve_plot(name_col='Compound Name',\n concentration_col='Compound Conc',\n response_col='% Inhibition Avg',\n plot_title='1 Row Example',\n column_num=4,\n figsize=(15,4))\n\n\n\n\nFinally, A specific point on the curve can be highlighted using the box or the hline/vline arguments. The box will be plotted for each curve. The figures can be further modified to add a title, adjust the line colors similarly to the examples seen above.\n\nfigure = data.grid_curve_plot(name_col='Compound Name',\n concentration_col='Compound Conc',\n response_col='% Inhibition Avg',\n plot_title='Grid Example',\n line_color=rainbow,\n box=True,\n box_color='#E0115F',\n figsize=(8,7))"
+ },
+ {
+ "objectID": "posts/7-py50-additional-features.html#conclusion",
+ "href": "posts/7-py50-additional-features.html#conclusion",
+ "title": "py50 - Showing off Color Features",
+ "section": "Conclusion",
+ "text": "Conclusion\nThese are some of the features with the plots generated from py50.\nThis is a great project for me personally and I learned a lot of making py50. I plan to maintain py50 for the foreseeable future. There are a couple of feature ideas swimming in my head that I would love to include in future releases.\nFinally, for anyone who is not as well versed in code, there is a web application version of py50 (click here). The updates for the program takes a little more time, as I tend to tinker a bit more with UI stuff. But overall, it works fairly well and will get you the calculations and plots needed.\nIf you find any issues with py50, feel free to leave a comment on the GitHub repository."
+ },
+ {
+ "objectID": "posts/5-egg-on-my-face.html",
+ "href": "posts/5-egg-on-my-face.html",
+ "title": "Egg On My Face",
+ "section": "",
+ "text": "Well I have egg on my face. Rotten eggs, so that they are unsalvageable to be used in scrambled eggs.\nHere is the story. In my earlier post I announced and in the last post I gave an example on how to use the program in python. Everything worked! The thing is, it worked for my datasets. When I shared this code/program with my co-workers/labmates, my program quickly crumbled like a dusty cracker. It is a good thing that I placed it as version 0.1.0. I am currently in the process of fixing the bugs and I hope to finish it sometime in the new year (Hey, a New Year’s resolution I might actually finish for once!).\nI will be sure to give updates and tutorials on the program once I finish.\nIf you would like to use the program now, I push out updates faster to the Streamlit version of py50 (see here). This web application is for my co-workers/labmates, but I hope others are able to find it and find it useful too.\nIn the meantime, I’ll be working on fixing these bugs and refactoring the code so that it will be a little bit easier to fix in the future (you’re welcome future me).\nThanks!"
+ },
+ {
+ "objectID": "posts/2-hello-world-goals.html",
+ "href": "posts/2-hello-world-goals.html",
+ "title": "Hello World - Now With Goals!",
+ "section": "",
+ "text": "Hello World - Now with Goals\nHello everyone. My name is Tony. I am currently in a Ph.D. program for drug discovery in Taiwan. Why Taiwan? Well, a series of life choices fresh from university led me there. I did not get a start into my field of study overnight. I am a late bloomer. And still learning. Or at least trying to!\nI specialize in cheminformatics - using computers to sort and categorize molecules. There’s a lot of good software out there that can help anyone interested into getting into the field. That includes both paid versions, such as Schrodiner’s Maestro, or open source software such as the wonderful suite available from the University of Hamburg. Those tools are great! But I quickly realized that relying on software, as good as they can be, can be very limiting. What if I have an idea that does not fit the available software? What if I want to make modifications to the figures I make? What if I want to try a new screening protocol? There is only one way to do these things - coding! And learning to code requires a lot of practice.\nI know that with experience. I have tried learning ot code multiple times in my life. Each time I have failed. There is a whole host of reasons. Maybe the language I chose was not for me. Java, is great, but at the time I can barely wrap my head around it. I tried making a small iOS app in the early days of the iPhone, which used UIKit. No dice. When Apple transitioned into Swift UI, I thought “Great! A new start!” Only to fail horribly.\nIt was not until I got into the Ph.D. program (and again, I started late!) that I finally tried and… well I did not succeed, but I got way further than before.\nWhat helped was having a project and actually sticking with it. Well, what really helped is that I found a lot of examples online tackling similar problems I had. People writing about their code, sharing new tools and packages, and how to solve them. All of this helped make things simple enough for me to at least get started.\nFor that, I am forever grateful.\nThat brings me to this blog. I will use it as a place to practice coding, my thinking and thought processes, what I am interested in, and hopefully, as a way to share with others.\nThis will be my way of paying it forward.\nAnd barring that, it will be a good place to showcase my failures to the world. I’m ok with that too."
}
]
\ No newline at end of file
diff --git a/docs/sitemap.xml b/docs/sitemap.xml
index 8313ca1..487f1aa 100644
--- a/docs/sitemap.xml
+++ b/docs/sitemap.xml
@@ -1,35 +1,39 @@
- https://tlint101.github.io/practice-in-code/posts/2-hello-world-goals.html
- 2024-01-09T01:11:00.217Z
+ https://tlint101.github.io/practice-in-code/posts/3-announcing-py50.html
+ 2024-01-11T02:45:22.074Z
- https://tlint101.github.io/practice-in-code/posts/5-egg-on-my-face.html
- 2024-01-09T01:10:58.656Z
+ https://tlint101.github.io/practice-in-code/posts/6-py50-QuickStart.html
+ 2024-01-11T02:45:20.916Z
- https://tlint101.github.io/practice-in-code/index.html
- 2024-01-09T01:10:57.211Z
+ https://tlint101.github.io/practice-in-code/posts/1-hello-world.html
+ 2024-01-11T02:45:20.136Z
+
+
+ https://tlint101.github.io/practice-in-code/posts/4-py50-single-plot.html
+ 2024-01-11T02:45:19.498Zhttps://tlint101.github.io/practice-in-code/about.html
- 2024-01-09T01:10:56.703Z
+ 2024-01-11T02:45:18.370Z
- https://tlint101.github.io/practice-in-code/posts/4-py50-single-plot.html
- 2024-01-09T01:10:57.803Z
+ https://tlint101.github.io/practice-in-code/index.html
+ 2024-01-11T02:45:18.899Z
- https://tlint101.github.io/practice-in-code/posts/1-hello-world.html
- 2024-01-09T01:10:58.402Z
+ https://tlint101.github.io/practice-in-code/posts/7-py50-additional-features.html
+ 2024-01-11T02:45:19.895Z
- https://tlint101.github.io/practice-in-code/posts/6-py50-QuickStart.html
- 2024-01-09T01:10:59.110Z
+ https://tlint101.github.io/practice-in-code/posts/5-egg-on-my-face.html
+ 2024-01-11T02:45:20.405Z
- https://tlint101.github.io/practice-in-code/posts/3-announcing-py50.html
- 2024-01-09T01:10:59.914Z
+ https://tlint101.github.io/practice-in-code/posts/2-hello-world-goals.html
+ 2024-01-11T02:45:22.373Z
diff --git a/tests/7-py50-additional-features.ipynb b/posts/7-py50-additional-features.ipynb
similarity index 99%
rename from tests/7-py50-additional-features.ipynb
rename to posts/7-py50-additional-features.ipynb
index a014d99..930888c 100644
--- a/tests/7-py50-additional-features.ipynb
+++ b/posts/7-py50-additional-features.ipynb
@@ -46,23 +46,6 @@
},
"id": "38c52610c1bce39a"
},
- {
- "cell_type": "code",
- "execution_count": 1,
- "id": "initial_id",
- "metadata": {
- "collapsed": true,
- "ExecuteTime": {
- "end_time": "2024-01-08T06:47:19.140611Z",
- "start_time": "2024-01-08T06:47:19.137772Z"
- }
- },
- "outputs": [],
- "source": [
- "import pandas as pd\n",
- "from py50.plotcurve import PlotCurve"
- ]
- },
{
"cell_type": "code",
"execution_count": 2,
@@ -105,8 +88,8 @@
"metadata": {
"collapsed": false,
"ExecuteTime": {
- "end_time": "2024-01-08T06:47:19.408241Z",
- "start_time": "2024-01-08T06:47:19.141742Z"
+ "end_time": "2024-01-11T02:44:21.460465Z",
+ "start_time": "2024-01-11T02:44:21.168084Z"
}
},
"id": "378e2cb32f4a6c84"
@@ -147,8 +130,8 @@
"metadata": {
"collapsed": false,
"ExecuteTime": {
- "end_time": "2024-01-08T06:47:19.584633Z",
- "start_time": "2024-01-08T06:47:19.411139Z"
+ "end_time": "2024-01-11T02:44:21.645438Z",
+ "start_time": "2024-01-11T02:44:21.479110Z"
}
},
"id": "d7a5eab93c487b34",
@@ -197,8 +180,8 @@
"metadata": {
"collapsed": false,
"ExecuteTime": {
- "end_time": "2024-01-08T06:47:19.848656Z",
- "start_time": "2024-01-08T06:47:19.585007Z"
+ "end_time": "2024-01-11T02:44:21.923493Z",
+ "start_time": "2024-01-11T02:44:21.643766Z"
}
},
"id": "91f4a11f9337385"
@@ -245,8 +228,8 @@
"metadata": {
"collapsed": false,
"ExecuteTime": {
- "end_time": "2024-01-08T06:47:20.110037Z",
- "start_time": "2024-01-08T06:47:19.871494Z"
+ "end_time": "2024-01-11T02:44:22.204861Z",
+ "start_time": "2024-01-11T02:44:21.933694Z"
}
},
"id": "3c720514177b831a",
@@ -294,8 +277,8 @@
"metadata": {
"collapsed": false,
"ExecuteTime": {
- "end_time": "2024-01-08T06:47:20.805099Z",
- "start_time": "2024-01-08T06:47:20.113280Z"
+ "end_time": "2024-01-11T02:44:22.952921Z",
+ "start_time": "2024-01-11T02:44:22.226019Z"
}
},
"id": "1facd79c2f397e65"
@@ -336,8 +319,8 @@
"metadata": {
"collapsed": false,
"ExecuteTime": {
- "end_time": "2024-01-08T06:47:21.509166Z",
- "start_time": "2024-01-08T06:47:20.808829Z"
+ "end_time": "2024-01-11T02:44:23.708586Z",
+ "start_time": "2024-01-11T02:44:22.966001Z"
}
},
"id": "adfce1116d8b983f"