Python Script to Automate Prism PZFX XML Data

I am working on a mathematical modeling figure using Graphpad Prism. I got data from a collaborator. He works on the computational part. He sends me his model fitting and simulation results in a set of CSV files. The data contains:

  1. Experiment data: 2 genotypes x 5 cell species x 7 times points x 3 replicates
  2. Simulations: 4 simulations, each contains:
    • 2 genotypes x 5 cell species x 200 simulated times points
    • 2 genotypes x 10 ( fitted parameters + standard deviations)
    • 2 genotypes x 4 residual errors measuring fitting goodness x 100 runs.

As you can see, I need to put all these data into Prism to make good looking figures. Initially, I was copy-pasting by hand. Soon, as the collaboration progress, I found it is unsustainable. Every time we change something or have a new idea, my collaborator sends me a new set of simulated data. It may only take his computer minutes to run, or hours I am not sure (but it is his computer, not his hand.) It takes me a lot of time to redo the copy-and-paste. And I often am not sure if I have copy the wrong data or pasted to the right place or not, or whether I completely skipped anything, because the data looks so similar.

After a couple of iterations, I realize this has to be automated.

I found out that since version 5, Graphpad Prism stores its data in XML format in its pzfx files. It is indeed intended for automated data manipulation.

Unfortunately, there is no python module for this purpose yet. Here is what I did:

from bs4 import BeautifulSoup # read and write XML
import pandas as pd # get data from CSVs
from lxml import etree # generate XML

The pzfx to start with should already contains the tables and graphs you want. We will replace existing table with new data. I have not tested generating new table.

# read the pzfx file and parse it to bs4 xml data
with open('YL524.pzfx', 'r') as f:
    data =
Bs_data = BeautifulSoup(data, "xml")

You can open the same file with your favorite text editor (Sublime Text 3 for me) and Prism to check the table names and data structure. A simple representation is like this:

  • list of Table Names
  • Table
    • X column
    • Y column
      • Subcolumn
        • d
        • d
        • d

You can now check the element with BeautifulSoup. For example:

# Table34 - 5th YColumn - 1st Subcolumn
Bs_data.find('Table', {"ID": "Table34"}).find_all('YColumn')[4].find_all('Subcolumn')[0]

Now we have two ways to replace the old data with new data.

1. You can replace the individual d value with a new one in string format:

Bs_data.find('Table', {"ID": "Table{}".format(value + 3)}).find_all('YColumn')[
    ].find_all('Subcolumn')[0].find_all('d')[0].string.replace_with(str(wtProRates.iloc[i, 0]))

2. You can replace the entire Subcolumn with a new XML etree element:

x = etree.Element('Subcolumn')
for k, row in chi2[i].iteritems():
    item = etree.SubElement(x, 'd').text = str(row)
Bs_data.find('Table', {"ID": "Table45"}).find_all('YColumn')[
    BeautifulSoup(etree.tostring(x, pretty_print=True), 'xml').Subcolumn)

Lots of variable names in the code above are used for proper looping and pandas iterations. You need to adapt to your specific needs.

Becareful, check your data often to see the data goes to the place you want. If you replace a Subcolumn with a Nonetype object. You will get one subcolumn deleted and your loops and data table will be off.

After everying confirmed OK, you can output the new file:

with open('YL524_out.pzfx', 'w') as f:

Use str(Bs_data) rather than Bs_data.prettify(). The latter output will be unreadable by Prism.

Open the output file with Prism, you will see everything updated automatically with new data in there! Hooray!

Franklin: An American Life 读后感

The naive image of Franklin:

  1. industrial and frugal
  2. lightning and Kite

The complete image of Franklin:

  1. Family background: commoner emigrated to US
  2. successful publisher and writer
  3. influential local leader and politician
  4. key colony leader and founding father and diplomat
  5. popular among elite women, failed son and grandson
  6. practical scientist, engineer, inventor

My take:

  1. He is REALLY smart, polymath, mastered both science and people, affectionate to everyone
  2. Although flirt with women, he seems more platonic than erotic.
  3. As smart, successful and influential as Franklin is, his marriage was practical, his son and grandson failed. And his lineage ended there. On the other hand, his legacy will never die, become part of American spirit.
  4. The critic view of Franklin in subsequent times does not change who Franklin is, but rather reflect what kind of time it is. Conservatives attacked him not caring about the golden pavement of heaven. Romanticist attacked him only care about money nickel and dimes, not heroic. Now all seems naive.

Franklin is one of the two lines down passed in American cultural history: the pragmatic industrial frugal smart mundane democratic mid class. Not the elitist, religious, conservative.

  (1)Temperance: Eat not to dullness; drink not to elevation.
  (2)Silence: Speak not but what may benefit others or yourself; avoid trifling conversation.
  (3)Order: Let all your things have their places; let each part of your business have its time.
  (4)Resolution: Resolve to perform what you ought; perform without fail what you resolve.
  (5)Frugality: Make no expense but to do good to others or yourself; i.e., waste nothing.
  (6)Industry: Lose no time; be always employ’d in something useful; cut off all unnecessary actions.
  (7)Sincerity: Use no hurtful deceit; think innocently and justly, and, if you speak, speak accordingly.
  (8)Justice: Wrong none by doing injuries, or omitting the benefits that are your duty.  
  (9)Moderation: Avoid extreams; forbear resenting injuries so much as you think they deserve.
  (10)Cleanliness: Tolerate no uncleanliness in body, cloaths, or habitation.
  (11)Tranquility: Be not distuibed at trifles, or at accidents common or unavoidable.   
  (12)Chastity: Rarely use venery but for health or offspring, never to dulness, weakness, or the injury of your own or another’s peace or reputation.
  (13)Humility: Imitate Jesus and Socrates.


越是争议越卖座 — 流浪地球观后感 (无剧透)


突然觉得好幸福,从中学时代每期追科幻世界,在某期上读到 带上她的眼睛 这样的极早期作品,拿了当年的银河奖,到每期科幻世界先翻目录找刘慈欣的名字,他银河奖拿到手软,到大学科幻世界出中篇小说单行本为 球状闪电 里的量子玫瑰唏嘘,到三体横空出世被深深震撼,大刘也拿到了雨果奖!磁铁们最大的心愿就是能看到作品成功搬上荧幕。

所以在经历了三体拍电影和流产的兴奋和失望之后,今天等到流浪地球呈现在眼前的时候,心中都是满足和幸福。就像当年读到 带上她的眼睛 短短的几页,相信这只是一个美好时代的开始,期待 地火 全频道 山 球状闪电 甚至刘慈欣以外的一些中国优秀科幻作品都能搬上荧幕。

流浪地球最近争议很多,越是争议越是卖座,希望中国科幻电影走向成熟和成功,科幻作家的生存和科幻文学的市场也越来越好,越来越普及。I choose hope. 前进三!





来了 爱了 临走送她一颗星



* 句子多有借鉴 请多包涵

FireFox for Mac中文字体粗细大小不一的解决办法(默认英文)

我的Firefox for Mac 一直有这个问题,某些中文网站字体显示粗细大小不一。如图:


答案中的用户把中文zh放在了en之前,结果访问很多国外网站比如Airbnb, Kayak时,它们默认我来自中国(因为zh-cn排第一嘛)。把界面,货币等都默认为中国,对于在海外学习生活的我们不是很方便。



设置Firefox / Preferences / Content / Languages


Seasons of Los Angeles 洛城四季

最后的叶子落下的时候 When last leaf falls
你和冬天一起来到我身边 Along with Winter you come to me
海都不动了 Ocean remains still
我把蓝天给了你 I give you sky
把蓝色留给自己 Leaving myself the blue

第一朵蓝花楹绽开的时候 When first Jacaranda blooms
你和春天一起拂过窗前 Along with Spring you pass my window
星都不闪了 Stars no longer glow
我把雪山给了你 I give you snow peaks
把冰川留给自己 Leaving myself the ice

排排棕榈摇曳的时候 When palm trees waver
你和夏天一起漫过沙滩 Along with Summer you rush to shore
鸥都唱累了 Seagulls tired of singing
我把浪花给了你 I give you breakers
把涛声留给自己 Leaving myself the tides

满树桔子红了的时候 When oranges turn yellow
你和秋天一起掠过山林 Along with Autumn you glide across ridges
大地都燃烧了 Land is burning
我把晚霞给了你 I give you sunset
把暮光留给自己 Leaving myself the twilight

最初的雪花融化的时候 When first snowflake melts
你走过四季回到我身边 Through four seasons you back to me
心稳稳在跳 Heart goes on beating
我把生命给了你 I give you my life
把意义留给自己 Leaving myself the meaning

后面四段扩写 作于 2018.2.10 洛杉矶

Template rendered html email for Web2py email verification and password reset

For discussion about this old problem, read Google group thread here.

I ended up modifying gluon/ It is probably not a good practice. But it is the easiest solution.

I edit register() and email_reset_password()

modifying something like (depends on which one)

message=self.messages.verify_email % d


message=('',response.render('email/template.html', d))

Be careful with the ending parentheses, the two functions need different number of them due to context codes.

It is important to use a 2-tuple or 2-list to pass the second item to html in the email, the empty '' will go to text. Otherwise, it will likely be sent as plain text, especially if you have <!DOCTYPE as start in your template.

for email_reset_password(), you also need:

response = current.response

Then you need to delete tools.pyc and restart web2py to take effect.

Make sure you modify and delete tools.pyc every time you update web2py.

Hope this save some other people’s time.

Force SSL/HTTPS and non-www in web2py

Update 02.08.2018: Code is updated to use just one line to force https:



I read this!topic/web2py/RzJ4pYtAWF4


then I realized “cronjob” problem described in these answers are no longer relevant since `scheduler` has long since replaced `cron`

I created a new model and add:

########## FORCED SSL non-www ##########
if not request.is_https:
    redirect(URL(scheme='https', args=request.args, vars=request.vars))
if request.env.http_host.startswith("www."):

I skipped the cron part since scheduler has long since replaced cron in web2py.

I created separated model so I can specify only to have it on my server, not on my local macbook, using .gitignore (see #2 below)

2. I need only to use https at server, not local development environment (, so I put models/ into my .gitignore

Hope this helps!