How to show text in a Bokeh Slider widget - slider

I would like to use a Bokeh slider widget to show a list of month or a list of text instead of integer. E.g. Nov 2018, Dec 2018, Jan 2019, Feb 2019.....
Is it possible?
Many Thanks

As of Bokeh 1.3.4 Slider widget text is not configurable. Adding a hook for a formatter seems like a reasonable ask (and also a good task for a first-time contributor), so a Github Issue would be appropriate.
For now, you could put the slider in column with a Div and update the text property of the div with a CustomJS callback (or a Python callback, if this is a Bokeh server app).

Just to elaborate on what #bigreddot described:
from bokeh.models import CustomJS, Slider, Legend, Div
from bokeh.layouts import column
from bokeh.plotting import ColumnDataSource, show, output_file
div = Div(text= '<b>text0</b>', style={'font-size': '150%', 'color': 'blue'})
str_list = ['text0', 'text1', 'text2']
str_slider = Slider(start=0, end=len(str_list)-1, value=0, step=1, title="string")
callback = CustomJS(args=dict(div=div, str_list = str_list, str_slider=str_slider),
code="""
const v = str_slider.value
div.text = str_list[v]
""")
str_slider.js_on_change('value', callback)
layout = column(str_slider, div)
output_file('test.html')
show(layout)

Related

Setting the view of a scene via mlab in traitsui is not working

I am trying to code a program based on traitsUI and Mayavi, but I have some problems. Following the code I am using:
#!/usr/bin/env python
import os
from traits.api import HasTraits, Instance, String, on_trait_change
from traitsui.api import View, Item
from tvtk.pyface.scene_editor import SceneEditor
from mayavi.tools.mlab_scene_model import MlabSceneModel
from mayavi.core.ui.mayavi_scene import MayaviScene
class ActorViewer(HasTraits):
scene = Instance(MlabSceneModel, ())
view = View(Item(name='scene',
editor=SceneEditor(scene_class=MayaviScene),
show_label=True,
resizable=True,
dock='tab',
height=500,
width=500),
resizable=True
)
def __init__(self, engine=None, **traits):
HasTraits.__init__(self, **traits)
if engine is not None:
self.scene=MlabSceneModel(engine=engine)
else:
self.scene=MlabSceneModel()
self.generate_data()
#on_trait_change('scene.activated')
def generate_data(self):
src=self.scene.mlab.pipeline.open(Path+i)
self.scene.mlab.view(40, 50)
self.scene.mlab.pipeline.outline(src)
self.scene.mlab.pipeline.iso_surface(src, contours=60, opacity=0.5)
if __name__ == '__main__':
Path = "/path/to/my/folder"
filelist = os.listdir(Path)
for i in filelist:
if i.endswith(".vtr"):
if ("E1_" in i) or ("E2_" in i):
print("file name ", i)
a = ActorViewer()
a.configure_traits()
The call self.scene.mlab.view(40, 50) returns AttributeError: 'NoneType' object has no attribute 'active_camera', thus I don't know how to set the camera. I have read that it is related to when the scene is activated, but I couldn't find a solution.
Without setting the view, the code works, but each file is loaded and rendered alone. In order to proceed with the main loop, each render has to be closed. I would like to dock each of the file without closing them.
I couldn't find a way to set a custom label to each tab after allowing show_label=True and to have it aligned horizontally at the top of the scene.
I tried to set the outline with the 'cornered' layout, but I couldn't find a way to do that. self.scene.mlab.pipeline.outline.outline_mode('cornered') gets simply ignored.
Thank you for your help!

PyQt5 - Get the pixel color inside a QWidget

I made a QWidget and inside I made some other items like QLabels which display images.
Consider what is inside that parent Widget I was trying to get the color where I would click.
Searching I found this thread but it is a bit old and I am not able to translate it to Python.
thread:
https://www.qtcentre.org/threads/49693-How-to-get-color-of-pixel-or-point
code:
QPixmap qPix = QPixmap::grabWidget(ui->myWidget);
QImage image(qPix.toImage());
QColor color(image.pixel(0, 1));
How would this translate this to PyQt5 if it is the correct answer?
QPixmap.grabWidget() is considered obsolete, and you should use QWidget.grab() instead.
pixmap = self.someWidget.grab()
img = pixmap.toImage()
color = img.pixelColor(0, 1)

How to change the icon for the matplotlib 'configure subplot' window?

I found that matplotlib's NavigationToolbar2Tk 'configure plot' window is being pulled from widgets.py
for ref: https://matplotlib.org/2.0.2/mpl_examples/pylab_examples/subplot_toolbar_01.pdf
The title for this window is Click on slider to adjust subplot param
Please advice me how to change its icon from default tkinter icon.
self.axleft = toolfig.add_subplot(711)
self.axleft.set_title('Click on slider to adjust subplot param')
self.icon = self.resource_path('icon.ico')
self.axleft.icon_bitmap = ImageTk.PhotoImage(Image.open(self.icon))
self.axleft.wm_iconbitmap(self.icon)
self.axleft.set_navigate(False)
I changed the above code starting in line 1115 in widgets.py. Here self.resource_path is a method I created to find the icon's path.
But getting error as subplots don't have the method wm_icon_bitmap
As #ImportanceOfBeingErnest pointed out.. I had to modify the configure_subplots method in _backend_tk.py. Used the wm_icon_bitmap method for the Toplevel widget.
def configure_subplots(self):
toolfig = Figure(figsize=(6,3))
window = Tk.Toplevel()
icon = self.resource_path('icon.ico')
window.icon_bitmap = ImageTk.PhotoImage(Image.open(icon))
window.wm_iconbitmap(icon)
canvas = type(self.canvas)(toolfig, master=window)
toolfig.subplots_adjust(top=0.9)
canvas.tool = SubplotTool(self.canvas.figure, toolfig)
canvas.draw()
canvas.get_tk_widget().pack(side=Tk.TOP, fill=Tk.BOTH, expand=1)
window.grab_set()

what is the proper way to set kivy scrollview effects_cls property?

I want to stop the user from over scrolling. kivy doc say that the effects_cls property will change this behavior, but I have not found a way to make it work.
Although you have solved your problem I will provide an example for future users.
You can change what effect is being used by setting effect_cls to any effect class. If you want to disable the overscroll effect to prevent the scroll bouncing effect ScrollEffect solve the problem.
Example using kivy Language:
from kivy.app import App
from kivy.uix.scrollview import ScrollView
from kivy.lang import Builder
Builder.load_string('''
#:import ScrollEffect kivy.effects.scroll.ScrollEffect
#:import Button kivy.uix.button.Button
<RootWidget>
effect_cls: ScrollEffect
GridLayout:
size_hint_y: None
height: self.minimum_height
cols: 1
on_parent:
for i in range(10): self.add_widget(Button(text=str(i), size_hint_y=None))
''')
class RootWidget(ScrollView):
pass
class MainApp(App):
def build(self):
root = RootWidget()
return root
if __name__ == '__main__':
MainApp().run()
Output:
so I was trying to use effect_cls: ScrollEffect when it should be effect_cls: 'ScrollEffect'.
have to pass it as a string.

oop instantiation pythonic practices

I've got the code below, and I was planning on making several classes all within the same "import". I was hoping to instantiate each class and get a return value with the widgets I'm making.
This isn't really a PyQt question at all, more of a "good practices" question, as I'll have a class for each widget.
Should I make functions that return the widgets that were created, if so how? How do I ensure it is difficult to directly instantiate the class if that is the best method for what I'm after?
I'd like to be able to do something like ....
tabs = wqTabWidget( ['firstTab', 'Second', 'Last Tab'] )
or (which ever is a better practice)
tabs = wqInstance.createTabs( ['firstTab', 'Second', 'Last Tab'] )
Here's my class so far....
from PyQt4 import QtCore as qc
from PyQt4 import QtGui as qg
class wqTabWidget(qg.QTabWidget):
def __init__(self, *args):
apply(qg.QTabWidget.__init__,(self, ))
tabList = []
tabNames = args[0]
for name in tabNames:
tabWidget = qg.QWidget()
self.addTab(tabWidget, name)
tabList.append( { name:tabWidget } )
print 'hi'
if __name__ == '__main__':
app = qg.QApplication(sys.argv)
window = wqTabWidget(['hi', 'there', 'and', 'stuff'])
window.show()
app.exec_()
The answer will be decided if the list of tabs can be changed at runtime. If this widget really only supports adding a set of tabs, but never changing or appending new ones, the list of tabs should come from the initializer. Otherwise you should also add a method to do the job. Consider the QLabel widget which can set the label's text in the initializer and through the setText method.
Other code idea tips.
Your initializer's arguments is a little confusing because you accept an arbitrary number of arguments, but only do something with the first one, and expect it to be a list of strings. A clear list of arguments is important.
Your use of apply to call the base class initializer is unnecessary. Change the code to simply qg.QTabWidget.__init__(self)
When creating a PyQt widget, I almost always prefer to allow a "parent" argument, even when I know the widget is going to be a toplevel widget. This is what all the built in Pyqt methods do, and feels like good practice to follow.
I also can't see the reason to store a list of tabs, with each one being a single element dictionary. I suspect you won't need to keep your own list of tabs and tab names. The QTabWidget can answer all questions about the contents.
If I were to bend this example code to my own preferences it would look like this.
from PyQt4 import QtCore as qc
from PyQt4 import QtGui as qg
class wqTabWidget(qg.QTabWidget):
def __init__(self, parent, tabNames):
qg.QTabWidget.__init__(self, parent)
self.createTabs(tabNames)
def createTabs(tabNames):
for name in tabNames:
tabWidget = qg.QWidget()
self.addTab(tabWidget, name)
if __name__ == '__main__':
app = qg.QApplication(sys.argv)
window = wqTabWidget(None, ['hi', 'there', 'and', 'stuff'])
window.show()
app.exec_()