Using canvas rectangles as buttons to create menus and actions - button

I am programing a GUI for a device that contains numerous sensors... I need to display their information accordingly... Some of them will require manual input which I want to input via using multiple rectangles used as menu items and adding a tag_bind to them to take action upon being clicked.
If you read carefully... I have attempted to erase the menu that has been pressed so it is not displayed after it is pressed. ( or at least at the last click, go back to only showing the main menu
I am running into an issue with the arguments... I little bit of help would be appreciated.
error: in onSecondClick
canvas.delete(square)
NameError: global name 'square' is not defined
I am able to delete the main menu rectangle but doesn't delete any other... I am a bit stomped
from Tkinter import *
#global square
def onObjectClick(event):
#. print(event.x, event.y)
square = canvas.create_rectangle(40, 50, 150, 100, width=1, fill="#BBB", tags="secondtag")
squaretxt = canvas.create_text(90,70, text="Sub-Menu")
canvas.delete(mainbutton)
canvas.delete(mainbuttontxt)
def onSecondClick(square, *args):
# print(event.x, event.y)
secondsquare = canvas.create_rectangle(60,70,160,110, width=1, fill="#AAA", tags="thirdtag")
secondText = canvas.create_text(110, 90, text="Final Choice")
canvas.delete(square)
def onThirdClick(secondsquare, secondText):
canvas.delete(secondsquare)
canvas.delete(secondText)
root = Tk()
canvas = Canvas(root, width=300, height=200)
mainbutton = canvas.create_rectangle(10, 30, 100, 60, width=5, fill="#666", tags="mainbuttontag")
manibuttontxt = canvas.create_text(55, 45, text="Main Menu", tags="mainbuttontag")
canvas.tag_bind("mainbuttontag", "<ButtonPress-1>", onObjectClick)
canvas.tag_bind('secondtag', "<ButtonPress-1>", onSecondClick)
canvas.tag_bind('thirdtag', "<ButtonPress-1>", onThirdClick)
canvas.pack()
root.mainloop()

I figured out how to do what I needed to do... I have dropped trying to use the canvas variable and used the "tags" option to choose what to delete upon a click action.
Here is the sample code I came up with. Feel free to butcher it if you think I am wrong or if there is a better way to approach this,
from Tkinter import *
txt2 = "Second Square"
txt3 = "Third Square"
global square
global mainbuttontxt
def onObjectClick(event):
square = canvas.create_rectangle(40, 50, 150, 100, width=1, fill="#BBB", tags="secondtag")
squaretxt = canvas.create_text(90,70, text=txt2, tags="secondtag")
canvas.delete("mainbuttontag")
def onSecondClick(event):
secondsquare = canvas.create_rectangle(60,70,160,110, width=1, fill="#AAA", tags="thirdtag")
secondText = canvas.create_text(110, 90, text=txt3, tags="thirdtag")
canvas.delete("secondtag")
def onThirdClick(event):
canvas.delete("thirdtag")
mainbutton = canvas.create_rectangle(10, 30, 100, 60, width=5, fill="#666", tags="mainbuttontag")
manibuttontxt = canvas.create_text(55, 45, text="Main Menu", tags="mainbuttontag")
root = Tk()
canvas = Canvas(root, width=300, height=200)
mainbutton = canvas.create_rectangle(10, 30, 100, 60, width=5, fill="#666", tags="mainbuttontag")
manibuttontxt = canvas.create_text(55, 45, text="Main Menu", tags="mainbuttontag")
canvas.tag_bind("mainbuttontag", '<ButtonPress-1>', onObjectClick)
canvas.tag_bind('secondtag', '<ButtonPress-1>', onSecondClick)
canvas.tag_bind('thirdtag', '<ButtonPress-1>', onThirdClick)
canvas.pack()
root.mainloop()

Related

RangeSlider does not work with scatter plot

Is it possible to make the range slider work with a scatter plot? The slider works if I change the scatter to a line plot but that does not work for me as I can not use the box select tool with line plots. The snippet below is simplified to demonstrate the issue. I suspect the embedded JavaScript is the issue but I may be wrong as it works just fine with a line plot. Thanks.
from bokeh.io import show
from bokeh.models import CustomJS, RangeSlider, Column, Row
from bokeh.plotting import figure
x = [0, 10, 20, 30, 40, 50, 60, 70, 80, 90, 100]
y = [0, 10, 20, 30, 40, 50, 60, 70, 80, 90, 100]
scatter_plot = figure(width=250, plot_height=600)
scatter_plot.scatter(x, y)
callback = CustomJS(args=dict(y_range=scatter_plot.y_range), code="""
var start = cb_obj.value
y_range.start = start[0]
y_range.end = start[1]
""")
depth_slider = RangeSlider(width=250, show_value=False, start=-20, end=120, value=(20, 80), step=20,
title="Y Scale")
depth_slider.js_on_change('value', callback)
layout = Column(Row(depth_slider), scatter_plot, )
show(layout)
There seems to be some race condition going on or a discrepancy between how Python and JS version of Bokeh work.
By default, all ranges are instances of DataRange1d class which recompute start and end when needed. In this case, it for some reason recomputes the values after you set them manually.
To fix it, specify the range manually from the get go:
scatter_plot = figure(..., y_range=(20, 80))

display problem of glmtree with terminal_panel node_bivplot or node_barplot

I use different decision trees applying to the same data but most of them can display like the following figure
.
When I use glmtree, there is an error at terminal nodes
Error in [.data.frame(X, , which, drop = FALSE) : undefined columns
selected
columncol<-hcl(c(250,10), 200, 60, 1)
labelcol<-hcl(265, 150, 100, 0.9)
indexcol<-hcl(270, 65, 65, 0.9)
#png(file='c:/glmtree-exmaple.png', width = 1024, height = 512)
plot(glm.model, drop_terminal = TRUE,
inner_panel = node_inner(glm.model, fill = c(labelcol, indexcol)),
terminal_panel=node_bivplot(glm.model, pointcol = "black", boxcol = "black", boxfill = "lightgray", bg = "white", cdplot = FALSE), main="glmtree")
#dev.off()
where glm.model is my result obtained from glmtree function.
If I delete the terminal_panel part, it works. But the information of terminal nodes is important, I was wondering if there is any solution that can display the terminal nodes in glmtree by colourfull boxplot?

global option for gganimate renderer (no loop)

I would like to stablish global options to a bunch of animations rendered using gganimate. The most important part is no-loop option but ...can not add to list of parameters this way. Every other option worked.
options(gganimate.dev_args = list(width = 14,
height = 7,
units = 'in',
res = 200,
renderer = gifski_renderer(loop = F)))
Error in device(files[i], ...) :
unused argument (renderer = function (frames, fps)

Adding values to charts in R Leaflet.minicharts

I want to add values above my chart, using lealfet.minicharts package.
My current code looks like this
addMinicharts(
87.2180, -45.3496,
chartdata = c(20, 40),
colorPalette = c("darkred", "darkblue"),
width = 45, height = 45, popup = popupArgs(
labels = c("Test1", "Test2")), showLabels = TRUE, labelText = TRUE)
It gives me a chart with a labels "true" and pop-up window with labels and values. But I would like to have values (not labels) on the top of charts or inside on bars (instead of text).
Looking into documentation and cannot figure it out.
Thanks
Resolved myself.
I disabled labelText = TRUE and increased width/height. It fixed everything.
Current code
addMinicharts(
87.2180, -45.3496,
chartdata = c(20, 40),
colorPalette = c("darkred", "darkblue"),
width = 100, height = 100, popup = popupArgs(
labels = c("Test1", "Test2")), showLabels = TRUE)

Resizing custom markers in Leaflet for R

I am interested in making custom icons while using Leaflet in R.
The documentation has a nice example, but when experimenting with it, I realized that there is no way to allow the custom marker to resize when the map changes size.
Since size is one of the parameters and is fixed (iconWidth = 38, iconHeight = 95,), obviously the marker will stay consistently sized as zoom changes for map beneath it.
greenLeafIcon <- makeIcon(
iconUrl = "http://leafletjs.com/docs/images/leaf-green.png",
iconWidth = 38, iconHeight = 95,
iconAnchorX = 22, iconAnchorY = 94,
shadowUrl = "http://leafletjs.com/docs/images/leaf-shadow.png",
shadowWidth = 50, shadowHeight = 64,
shadowAnchorX = 4, shadowAnchorY = 62
)
Are there any hacks / ideas / protocols for having custom icons resize along with zoom?

Resources