How to add a second dataset to a plotly annotated heatmap? - plotly-python

I'm trying to create an annotated heatmap with a dropdown menu to switch between two different sets of data. The datasets have the same format and I have added a working dropdown menu. But I can only add one dataset at a time. I am using
fig = ff.create_annotated_heatmap(data, annotation_text=numbers, showscale=True, colorscale=colorscale, text=hover, hoverinfo='text')
to create the annotated heatmap. Is there a way to add a second dataset to switch between with the dropdown menu?

Resolved. Had to add the second data set to the args of the dropdown menu object
along with any other changes needed (such as hover text)

I just realized how easy it is to switch between two plots with a menu. You can just get the data from each figure to create a list of traces to swithc between
from plotly.offline import init_notebook_mode, iplot
import plotly.figure_factory as ff
init_notebook_mode(connected=True)
fig_1 = ff.create_annotated_heatmap(...)
fig_2 = ff.create_annotated_heatmap(...)
menu_items = ["Heatmap 1", "Heatmap 2"]
trace1 = fig_1.to_dict()["data"][0]
trace2 = fig_2.to_dict()["data"][0]
buttons = []
for i, menu_item in enumerate(menu_items):
visibility = [i==j for j in range(len(menu_items))]
button = dict(
label = menu_item,
method = 'update',
args = [{'visible': visibility},
{ 'title' : menu_item }])
buttons.append(button)
updatemenus = list([
dict(buttons = buttons)
])
layout = dict(updatemenus = updatemenus, title=menu_items[0])
fig = dict(data=[trace1, trace2], layout=layout)
iplot(fig)

Related

How do I delay the execution of a function within tkinter button command

I am trying to simulate a computer player "clicking" a button after a human user clicks a button In a grid of buttons. If I use the .after method the 'state' of the button change is delayed but it executes my check_state() method which doesn't detect the change. When I try time.sleep() method it prolongs the human click but still immediately invokes the 'auto' click regardless of where I put it in my code. I want a delay between the human click and 'auto' click.
I have tried widget.after(1000) which gives the desired delay of 'auto' click, but doesn't allow my the change to be seen by my check_state() function. I have tried time.sleep() which delays the execution of the human button click but the 'auto' click is still immediately invokes regardless of which order I place the sleep() function in relation to the call to auto_click(). I know there are better practices for this code implementation like using class based structure which I plan on using once my logic and functionality issues are resolved. My code is as follows:
import tkinter as tk
import random
def app():
def auto_click():
grid_state = get_grid_state()
possible_clicks = []
for i in range(0, len(grid_state)):
if grid_state[i] == " ":
possible_clicks.append(i)
#debug.config(text=possible_moves)
click = random.choice(possible_clicks)
buttons[click].after(1000, lambda: buttons[click].config(text = "auto", state=tk.DISABLED))
#time.sleep(1)
check_grid_state()
check_grid_full()
debug.config(text="test")
def onclick(*arg):
global is_full
buttons[arg[0]].config(text = "clicked", state=tk.DISABLED)
check_grid_state()
check_grid_full()
if not is_full:
auto_click()
def check_grid_full():
global is_full
result=[]
for i in range(len(buttons)):
result.append(buttons[i].cget('state'))
r = [*set(result)]
if r == ['disabled']:
is_full = True
grid_status.config(text=is_full)
else:
is_full = False
Retrieve the current state of the grid
def get_grid_state():
grid_state =[]
for i in range(len(buttons)):
grid_state.append(buttons[i].cget('text'))
return grid_state
Check grid state
def check_grid_state():
grid_states.config(text=get_grid_state())
Global Variables
is_full = False
buttons = []
c=0
Window
root = tk.Tk()
root.title("Title")
Heading
label = tk.Label(root, text="grid state", font = ("Ariel black",22, "bold"))
label.pack()
Grid Frame
frame = tk.Frame(root)
frame.pack()
for row in range(3):
for column in range(3):
buttons.append(tk.Button(frame, text=f" ", font=("arial", "22"), state=tk.ACTIVE, height=2, width=2, command=lambda c=c: onclick(c)))
buttons[c].grid(row=row, column=column)
c += 1
Status bar
grid_states = tk.Label(root, text=f"")
grid_states.pack()
grid_status = tk.Label(root, text=f"")
grid_status.pack()
#btn_is = tk.Label(root, text=f"")
#btn_is.pack()
Debugging output label
debug = tk.Label(root, text="debug")
debug.pack()
Event loop
root.mainloop()
if name == "main":
app()

Dynamically changing trait

Is it possible to have two classes
class SimulationDigitizer(HasTraits):
width = Int(1920)
height = Int(1080)
name = 'Simulation'
class FileDigitizer(HasTraits):
Filename = File
name = 'File'
and another class 'Digitizer' having an attribute (or trait) UserDigitizer whose edition dialog will propose a drop-down list with 'Simulation' and 'File' and, depending on the choice, the instance edition of either FileDigitizer or SimulationDigitizer and get the result in UserDigitizer ?
Thanks
Thanks Jonathan, you are right, the problem is to select the appropriate subcomponent among many possible.
I ended with the following code, I guess it can be improved in many ways. I am new both to Python and Traits.
# -*- coding: utf-8 -*-
from traits.api import HasTraits, Int, File, Enum, Instance
from traitsui.api import View, Item, Handler, HGroup, InstanceEditor
class UserComponent ( HasTraits ):
""" An empty class from which all user component classes are
derived.
"""
pass
class SimulationDigitizer(UserComponent):
width = Int(1920)
height = Int(1080)
nature = 'Simulation'
class FileDigitizer(UserComponent):
filename = File
nature = 'Reading a file'
UserDigitizers = [FileDigitizer, SimulationDigitizer]
class UserComponentHandler(Handler):
def __init__(self,_user_components_dict):
Handler.__init__(self)
self._user_components_dict = _user_components_dict
def object_user_component_nature_changed ( self, info ):
# Find new UserComponent class from string in user_component_nature
new_user_component = self._user_components_dict[info.object.user_component_nature]
# If different, change user_component value
if info.object.user_component is not new_user_component:
info.object.user_component = new_user_component
class Digitizer(HasTraits):
user_component_nature = Enum([x().nature for x in UserDigitizers])
_user_file_digitizer = FileDigitizer()
_user_simulation_digitizer = SimulationDigitizer()
# Dictionary with keys = nature and values = user digitizers
_user_digitizers_dict = {x.nature: x for x in [_user_file_digitizer,_user_simulation_digitizer]}
user_component = Enum(_user_file_digitizer,_user_simulation_digitizer)
view = View(HGroup(Item('user_component_nature',
label = 'Nature'),
Item('user_component',
show_label = False,
editor = InstanceEditor(label = 'Edit',
kind = 'modal'))),
handler = UserComponentHandler(_user_digitizers_dict))
d = Digitizer()
if __name__ == '__main__':
d.configure_traits()

GtkListBox, how to prevent auto-selecting a row on window show

I have a list box with several rows attached to a window.
list_box = Gtk.ListBox()
list_box.insert(Gtk.Label('foo'), -1)
list_box.insert(Gtk.Label('bar'), -1)
list_box.insert(Gtk.Label('qux'), -1) # ListBoxRow is added automatically
window = Gtk.Window()
window.add(list_box)
window.show_all()
When I call show_all(), the first row of the list is being selected automatically what I don't want to happen. How to prevent auto-selecting it?
I tried changing the order of the functions call
window.show_all()
window.add(list_box)
which broke the layout and the size of the window doesn't fit to the list.
I was running into this issue as well, I used the following code to do it:
listbox = Gtk.ListBox(margin=0)
listbox.set_selection_mode(Gtk.SelectionMode.NONE)
I can still click on each row and do a callback with the following, as well:
listbox.connect("row-activated", self.callback)
The ListBox has a property selection-mode, which you can set to Gtk.SELECTION_NONE. In this case none of the rows will be selected (and cannot be selected later). I don't know if that is what you want.
You can also call the method unselect_all, which will unselect all rows. For this to work, the ListBox must be in SELECT_MULTIPLE or SELECT_SINGLE mode.
This example seems to work completely as expected (i.e. no selection at the start, and if a line is selected, the button can unselect it). If in your installation it doesn't work, I would try to update your packages:
from gi.repository import Gtk
class MainWindow(Gtk.Window):
def __init__(self):
Gtk.Window.__init__(self)
self.connect("delete-event", self.on_delete)
self.listbox = Gtk.ListBox()
self.listbox.insert(Gtk.Label('foo'), -1)
self.listbox.insert(Gtk.Label('bar'), -1)
self.listbox.insert(Gtk.Label('qux'), -1) # ListBoxRow is added automatically
button = Gtk.Button("Clear selection")
button.connect("clicked", self.on_button_clicked)
vbox = Gtk.VBox()
vbox.pack_start(button, False, True, 0)
vbox.pack_start(self.listbox, False, True, 0)
self.add(vbox)
self.show_all()
Gtk.main()
def on_button_clicked(self, btn):
self.listbox.unselect_all()
def on_delete(self, win, event):
Gtk.main_quit()
def main():
w = MainWindow()
return 0
if __name__ == '__main__':
main()
A note about gtk3 themes: Some themes do not show selected rows at all. Particularly dark themes such as eg. FlatStudioDark, but also some light themes.
Add a dummy label to the top of your list_box and hide it:
dummyLabel = Gtk.Label('nothing') # workaround for focus of title entry
list_box.insert(dummyLabel, -1)
list_box.insert(Gtk.Label('foo'), -1)
list_box.insert(Gtk.Label('bar'), -1)
list_box.insert(Gtk.Label('qux'), -1) # ListBoxRow is added automatically
window = Gtk.Window()
window.add(list_box)
window.show_all()
dummyLabel.hide()
Gtk.main()
The result:
result

Ironpython in Spotfire - draw curve and modify chart

I have a code that changes my visualisation type from a Line to a Bar chart based on a property type. I need add a query to draw a straight line based on a property within my visualisation. The code I have so far is this:
from Spotfire.Dxp.Application.Visuals import VisualContent
from Spotfire.Dxp.Application.Visuals import VisualTypeIdentifiers
vc1 = viz1.As[VisualContent]()
Yaxis=vc1.YAxis.Expression
Xaxis=vc1.XAxis.Expression
ColorAxis=vc1.ColorAxis.Expression
if type=="LINE":
viz1.TypeId = VisualTypeIdentifiers.LineChart
if type == "BAR":
viz1.TypeId = VisualTypeIdentifiers.BarChart
vc1.XAxis.Expression=Xaxis
vc1.YAxis.Expression=Yaxis
vc1.ColorAxis.Expression=ColorAxis
Thanks in advance for your help!
from Spotfire.Dxp.Application.Visuals import LineChart
if vis.As[LineChart]().FittingModels[0].Enabled == False:
vis.As[LineChart]().FittingModels[0].Enabled = True
else:
vis.As[LineChart]().FittingModels[0].Enabled = False
This code requires a vis parameter defined as Type: Visualization Value: Page > Line Chart

Python 3.x tkinter - can't get checkbox' variable value

Please help! As it says in the title - I can't get checkbox' variable value.
def init_widgets(self):
ttk.Button(self.root, command=self.insert_txt, text='Button', width='10').place(x=10, y=10)
...
cbcc = ttk.Checkbutton(root, text="Damage", onvalue="on", offvalue='off').place(x=235, y=12)
...
def insert_txt(self):
...
cbcd = StringVar()
cbcd.get()
print(cbcd)
if cbcd == "on":
self.damage
else:
Print delivers "PY_VAR2" and counting up from there with every time I click (PY_VAR3, etc.)
It seems in your code, the argument 'variable' in your Checkbutton is not bounded, furthermore to get the value from IntVar or StringVar you would use (IntVar.get(), StringVar().get()), you could use the next code as example to use Checkbutton widget.
'''
CheckBox Test
References:
http://effbot.org/tkinterbook/checkbutton.htm
'''
from tkinter import *
class App:
def __init__(self, master):
self.var = IntVar() #This is the variable bounded to checkbutton to
#get the checkbutton state value
#
frame = Frame(master)
frame.pack()
self.checkbutton = Checkbutton(frame, text="Hello Checkbutton",
command=self.say_hello, variable=self.var)
self.checkbutton.pack(side=LEFT)
#
self.button = Button(frame, text="QUIT", fg="red", command=frame.quit)
self.button.pack(side=LEFT)
def say_hello(self):
'''
Function Bounded to Checkbutton in command parameter, every click
either check or un-check print the current state of the checkbutton
'''
print("State Changed:", self.var.get())
if __name__ == '__main__':
root = Tk()
app = App(root)
#
root.mainloop()
root.destroy() # Quit the App when you click "Quit"
Every click on the check button, you will see printed in the console the value of the current state for the checkbutton. You can check the next reference to get an general overview tkinter widgets: http://effbot.org/tkinterbook/checkbutton.htm
I hope this snippet helps you.
Very Best Regards.