How to use hover with multi-line in bokeh? - python-2.7

I'm facing issues with multi-line figure in bokeh. i can't get the values when i show my graph. i'm using series data type.
Code:
df = pandas.read_csv("Data.csv", parse_dates=["time"])
result = df.groupby(['time','up','down'], as_index = False)['up', 'down'].sum()
p = Figure(width=500, height=250,logo =None,
sizing_mode='scale_width',
tools="pan, box_zoom, wheel_zoom, save, reset, box_select",
x_axis_type="datetime",
title="Graph:",
x_axis_label="Time Frame",
y_axis_label="Utilization (GB)",
toolbar_location="below",
toolbar_sticky=False)
up = result["up"]
time = result["time"]
down = result["down"]
p.multi_line(xs = [time, time], ys = [up, down], color=['#2828B0', '#BC0096'], line_width=1, legend='graph_1')
hover = HoverTool(tooltips = [('Time', '#time'),
('data', '#up')])
p.add_tools(hover)
p.show()

The # fields of hover tooltips refer to columns in Bokeh ColumnDataSource objects. Since you have not created a CDS explicitly with column names of your choice, Bokeh makes one for you with the standard column name xs and ys in this case. So:
HoverTool(tooltips = [
('Time', '#xs'),
('data', '#ys')]
)
That will put a hover that displays over all segments in the multi-line. There is no way to have a hover work for just one or the other. If you need that, you will have to use separate calls to line instead of multi_line.

Related

Revit Python Shell - Iterate over each Element, find View Name and group by Sheet Number

I want to create a list of all Viewports by associated sheet number, View Name and Location Center. Like so:
vPorts = [('A0.01, View Name 01',[Center of ViewPort location]),('A0.02, View Name 01',[Centre of ViewPort location]),('A0.02, View Name 02',[Center of ViewPort location]),('A0.04, View Name 01',[Centre of ViewPort location]), etc.]
This so a user can align Multiple Viewports to each other in a listbox (not shown here) in WPF. I have the below:
import clr
clr.AddReferenceByPartialName('PresentationCore')
clr.AddReferenceByPartialName("PresentationFramework")
clr.AddReferenceByPartialName('System')
clr.AddReferenceByPartialName('System.Windows.Forms')
from Autodesk.Revit.DB import *
from Autodesk.Revit.DB.Architecture import *
from Autodesk.Revit.DB.Analysis import *
from Autodesk.Revit.UI import *
doc = __revit__.ActiveUIDocument.Document
#List of ViewPort Elements
vPorts = []
#List for ViewPorts by sheet number, view name and location
vPortsloc = []
col_sheets = FilteredElementCollector(doc).OfCategory(BuiltInCategory.OST_Sheets).WhereElementIsNotElementType().ToElements()
for sheet in col_sheets:
vPorts.append(sheet.GetAllViewports())
for vp in vPorts:
print(vp)
Which gets me all the Viewports on all Sheets as List objects.
But I now want to format this list as stated above. I tried the following:
for vp in vPorts:
v = doc.GetElement(vp.ViewId)
vPortsloc.append(v.SheetNumber + v.Name + (v.GetBoxCenter().ToPoint()))
I believe I am not iterating over the whole List of lists. Not to mention I am new to python.. Any help would be really appreciated. Thanks!
Thanks Callum that helped alot! I just had to fix one or two typos, use append () instead of add, and get the View Name as well instead of the Sheet Name. As below
viewPorts = list(FilteredElementCollector(doc).OfClass(Viewport))
viewPortTriples = []
for vp in viewPorts:
sheet = doc.GetElement(vp.SheetId)
view = doc.GetElement(vp.ViewId)
viewPortTriples.append([sheet.SheetNumber, view.ViewName, vp.GetBoxCenter()])
print(viewPortTriples)
It could help to visualise multiple-dimensioned Lists like this:
vPortTriples = [
[Sheet Number, Sheet Name, ViewPort Center],
[Sheet Number, Sheet Name, ViewPort Center],
[Sheet Number, Sheet Name, ViewPort Center]
]
It looks like youre appending three separate items to a List. Should they be added as a new List, like this?
vPortTriples.append([v.SheetNumber, v.Name, v.GetBoxCenter().ToPoint()])
If you really are looking to catch every Viewport in a project, you can fetch all the ViewPorts by Class, so in your code it would look like:
# I find it easiest to convert FilteredElementCollector to a list
viewPorts = list(FilteredElementCollector(doc).OfClass(Viewport))
viewPortTriples = []
for vp in viewPorts:
# need to fetch the ViewPorts Sheet
sheet = doc.GetElement(vp.SheetId)
# add a new List to the 'viewPortTriples' List
viewPorts.Add([sheet.SheetNumber, sheet.Name, vp.GetBoxCenter()]
This is a pretty expensive way to do it though, better to fetch them only for the relevant sheet - say, by a specific Sheet Number (which may have been what you were trying to do in your example anyway!):
def getViewPorts (document, sheetNumber): # returns [[viewPort, bboxCenter], ... ]
sheets = list(FilteredElementCollector(document).OfClass(ViewSheet))
try:
targetSheet = [i for i in sheets if i.Sheetnumber == sheetNumber][0]
except:
print 'failed to find sheet',sheetNumber
return []
viewPortLocations = [] # a list of [[viewPort, bboxCenter], ... ]
for vpId in targetSheet.GetAllViewports():
vp = document.GetElement(vpId)
viewPortLocations.Add([vp, vp.GetBoxCenter()])
return viewPortLocations

Listbox Python Columns

I am trying to develop a script that allows me to keep my formatting within my listbox.
from Tkinter import *
from tabulate import tabulate
master = Tk()
listbox = Listbox(master)
listbox.pack()
table = [["spam",42],["eggs",451],["bacon",0]]
headers = ["item", "qty"]
tb = tabulate(table, headers, tablefmt="plain")
listbox.insert(END,tb)
mainloop()
End Result the listbox populated with the tb formatting:
QUESTION: HOW DO I GET MY LISTBOX TO APPEAR LIKE THE PICTURE ABOVE THAT I USED TABULATE TO FORMAT?
I've noticed treeview seems to have some limitations with the horizontal box and expanding the columns without adjusting the entire GUI so I'd decided this might be a more shake-shift way that will suit my needs just fine.
One option may be to use str.format() to align each insert into the listbox:
from Tkinter import *
import tkFont
master = Tk()
master.resizable(width=False, height=False)
master.geometry('{width}x{height}'.format(width=300, height=100))
my_font = tkFont.Font(family="Monaco", size=12) # use a fixed width font so columns align
listbox = Listbox(master, width=400, height=400, font=my_font)
listbox.pack()
table = [["spam", 42, "test", ""],["eggs", 451, "", "we"],["bacon", "True", "", ""]]
headers = ["item", "qty", "sd", "again"]
row_format ="{:<8}{sp}{:>8}{sp}{:<8}{sp}{:8}" # left or right align, with an arbitrary '8' column width
listbox.insert(0, row_format.format(*headers, sp=" "*2))
for items in table:
listbox.insert(END, row_format.format(*items, sp=" "*2))
mainloop()
Which appears to match the output you got using tabulate:
Another option could be use a Grid layout.

Set background color for column

Is it possible to set background color of a column in a django-tables2? My rows consists of 2 different object data so I have to make user to simple distinguish between them.
For example by changing a css class of the column.
class AdminPairTable(tables.Table):
reservation_1_destination_from = tables.TemplateColumn("""{{ record.0.destination_from }}""")
reservation_1_destination_to = tables.TemplateColumn("""{{ record.0.destination_to }}""")
reservation_1_date_departure = tables.TemplateColumn("""{{record.0.date_departure}}""")
reservation_1_time_departure = tables.TemplateColumn("""{{record.0.time_departure}}""")
reservation_1_specification = tables.TemplateColumn("""{{record.0.specification}}""")
reservation_2_destination_from = tables.TemplateColumn("""{{ record.1.destination_from }}""")
reservation_2_destination_to = tables.TemplateColumn("""{{ record.1.destination_to }}""")
reservation_2_date_arrival = tables.TemplateColumn("""{{record.1.date_arrival}}""")
reservation_2_time_arrival = tables.TemplateColumn("""{{record.1.time_arrival}}""")
reservation_2_specification = tables.TemplateColumn("""{{record.1.specification}}""")
confirm_pair = tables.TemplateColumn("""<button class="btn btn-success">Zaradiť pár</button>""")
The only way which comes to my mind is to simply use JQuery but it's not a best way.
You can set column attributes while creating columns.
Not sure why you use the TemplateColumn to just render a value, just Column would work here too (except for confirm_pair of course).

Bokeh: dashboard not updating axis range based on widget value

I am trying to implement an interactive dashboard in Bokeh with a "play" function that loops through all value pairs for two indicators selected by widgets.
Screen cap of dashboard
While the loop works, the dashboard resets the axis values for each step of the loop. So what I need is to set axis values based on the widget.value selected. To this end, I have built a data frame "ranges" that has the name of the indicator as index and the min/max value for each indicator as columns.
The updates for controls work thusly (x_axis,etc. are the names of the widgets):
controls = [x_axis, y_axis, start_yr, end_yr, years]
for control in controls:
control.on_change('value', lambda attr, old, new: update())
The update function is supposed to update the ranges upon change in the controls like this:
def update():
p.x_range = Range1d(start = ranges.loc[x_axis.value,"Min"],
end = ranges.loc[x_axis.value,"Max"])
p.y_range = Range1d(start = ranges.loc[y_axis.value,"Min"],
end = ranges.loc[y_axis.value,"Max"])
What should happen: Whenever I change the value of the widget, the ranges should update, but other than that, they should remain constant
What does happen: The ranges are set based on the value of the widget initially set and don't change on update.
I've tried to find examples trying to achieve something similar but no luck.
This is a working example:
import numpy as np
from bokeh.plotting import figure
from bokeh.models import Range1d
from bokeh.io import curdoc
x = np.linspace(0, 100, 1000)
y = np.sin(x)
p = figure(x_range=(0, 100))
p.circle(x, y)
def cb():
# this works:
p.x_range.start += 1
p.x_range.end += 1
# this also works:
#p.x_range = Range1d(p.x_range.start+1, p.x_range.end+1)
curdoc().add_periodic_callback(cb, 200)
curdoc().add_root(p)

CAD to Feature Class

import arcpy
fc = r'H:\H-ONUS UTILITY DATA GIS\As_Builts\2014\RandolphPoint_Phase2\789-AS-BUILT 8-7-13.dwg\Polyline'
out_gdb = r'H:\H-ONUS UTILITY DATA GIS\As_Builts\2014\RandolphPoint_Phase2\RandolphPoint.gdb.gdb'
field = 'Layer'
values = [row[0] for row in arcpy.da.SearchCursor(fc, (field))]
uniqueValues = set(Values)
for value in uniqueValues:
sql = """Layer" = '{0}'""".format(Value)
name = arcpy.ValidateTableName(value,out_gdb)
arcpy.FeatureClassToFeatureClass_conversion(fc, out_gdb, name, sql)
I am trying to convert CAD(dwg) to ArcGIS 10.2.2 Feature Classes using a file geodatase as the workspace. I was just taught this code at an ESRI conference and of course it worked beautifully for the insturtor.
My error I am getting is "NameError:name'Values' is not defined" however I did define it as values = [row[0] for row in arcpy.da.SearchCursor(fc, (field))] I have been working hours on this, it would help out my job considerably.
Python variables are case-sensitive.
You've declared values with a lower-case v, but you're referring to it on the next line with an upper-case V.
(Same with value/Value further down.
import arcpy
fc = r'H:\H-ONUS UTILITY DATA GIS\As_Builts\2014\RandolphPoint_Phase2\789ASBUILT.dwg\Polyline'
out_gdb = r'H:\H-ONUS UTILITY DATA GIS\As_Builts\2014\RandolphPoint_Phase2\RandolphPoint.gdb'
field = 'Layer'
value = [row[0] for row in arcpy.da.SearchCursor(fc, (field))]
uniquevalues = set(value)
for value in uniquevalues:
sql = """"Layer" = '{0}'""".format(value)
name = arcpy.ValidateTableName(value,out_gdb)
arcpy.FeatureClassToFeatureClass_conversion(fc, out_gdb, name, sql)
Here is the solution, I had an extra .gdb in the geodatabase path
my word value was values so had to take the s off
and also in my sql statement I was missing a " before the word Layer
If anyone is reading this just change the individual parameters and it works beautifully!
thanks Juffy for responding and trying to help me out
Cartogal