This has nothing to do with the hovertool anymore:
You create a CDS via a dictionary:
median_source =ColumnDataSource(dict(x=cats,y=q2))
That CDS now has two columns, named x and y respectively because of the keys you’ve assigned in the dictionary. You could call it:
median_source =ColumnDataSource(dict(harry=cats,sally=q2))
and median_source would have two columns named harry and sally repectively.
When you create the rect renderer, you point to the names of the columns for the specific args the renderer needs. In the case of rect, it needs an x and a y arg… so :
p.rect(x='harry',y='sally',0.5,.01.... source_median_source)
Edit: I somewhat recently had some discussion about all the things you use to instantiate a renderer, and the fact that you can mix them ( which you are doing) here → Glyphs with nonexistent column names (non-continuous ranges!) - #4 by gmerritt123 , maybe it will help explain things a bit more.