I am trying to create dropdown menu using the following code on Python.
pqrs = ['Segment1', 'Segment2', 'Segment3']
#Segment Criteria
Segment_selected = widgets.Text()
# print('=' * term_size.columns)
# print('\n' +"\033[1m" + 'Select a Segment criteria for Selecting HCP Universe' + "\033[0m")
# python code to run in jupyter notebook
from ipywidgets import interact, interactive, Layout
def lx(Segmentation):
Segment_selected.value = str(Segmentation)
int_widget = interactive(lx, Segmentation=pqrs,)
int_widget.children[0].layout = Layout(width='400px',height = '40px')
display(int_widget)
This is generating the following output:
Code Output
Now, the problem is I want to show the complete text on the left side of the dropdown. It appears as "Segmentati..." in my case which I want it to be "Segmentation" in my case. But I am unable to do so.
Can you please help me?
Initially comments widths are fixed. You can set a style to make it bigger - this will reduce the overall other sizes of your widget:
pqrs = ['Segment1', 'Segment2', 'Segment3']
int_widget = interactive(lx, Segmentation=pqrs, )
int_widget.children[0].layout = Layout(width='auto',height = '40px')
int_widget.children[0].style = {'description_width': '200px'} # increase size
display(int_widget)
to get:
The essential documentation for this is here: Widget Styling#Description
Try "auto" or "initial" for auto-fitting the description_width.
Related
I have a function that takes the names of image files and creates a grid of them as buttons using the image attribute, which is where the issue arises, since I need the button object to create the image due to another function of mine fit_image() (which in this case fits the image inside the object completely, hence full=True). The result of running this without adding the images to these buttons is fine and all the buttons are clickable:
self.image_buttons = {}
count = 0
# goes by column
for y in range(height_divisor):
# row
for x in range(width_divisor):
self.image_buttons[count] = tk.Button(self.preview_frame)
self.image_buttons[count].place(
relx=0 + (1 / width_divisor * x),
rely=0 + (1 / height_divisor * y),
relwidth=1 / width_divisor,
relheight=1 / height_divisor,
anchor="nw",
)
# self.current_image = fit_image(
# Image.open(names_of_files[count]), self.image_buttons[count], full=True
# )
# self.image_buttons[count].configure(image=self.current_image)
count += 1
print(self.image_buttons)
Result of print statement:
{0: <tkinter.Button object .!toplevel2.!frame2.!button>, 1: <tkinter.Button object .!toplevel2.!frame2.!button2>, 2: <tkinter.Button object .!toplevel2.!frame2.!button3>, 3: <tkinter.Button object .!toplevel2.!frame2.!button4>}
However, once I uncomment this code, only the last button is clickable and does have the image on it, but all the others are blank and not clickable buttons. I have tried putting the commented (image configuration) lines in a separate for loop afterwards to go through and configure each button to no avail. Though I've previously had this work and even tried combing through my repo's commits (nothing before Aug 8th should be relevant) to see how it worked before, it must've been working then I most likely broke it before committing.
This was solved thanks to #jasonharper 's comment by changing these two lines and adding a new dictionary:
self.image_buttons, self.images = {}, {}
#for loops here
self.images[count] = fit_image(
Image.open(names_of_files[count]), self.image_buttons[count], full=True
)
self.image_buttons[count].configure(image=self.images[count])
I have a Chart Placeholder, into which I have inserted a chart of chart_type 'DOUGHNUT'. I've added data labels to it and want to change their positions. For some reason, the method given in the documentation has no effect on my chart.
Here is my code, please help if I'm doing something wrong -
from pptx import Presentation
from pptx.chart.data import ChartData
from pptx.enum.chart import XL_CHART_TYPE, XL_LABEL_POSITION, XL_DATA_LABEL_POSITION, XL_TICK_MARK, XL_TICK_LABEL_POSITION
chart_data = ChartData()
chart_data.add_series('', tuple(input_chart_data[x] for x in input_chart_data))
graphic_frame = content_placeholder.insert_chart(XL_CHART_TYPE.DOUGHNUT, chart_data)
chart = graphic_frame.chart
chart.has_legend = False
#Adding Data-Labels with custom text
chart.plots[0].has_data_labels = True
data_labels = chart.plots[0].data_labels
i = 0
series = chart.series[0]
for point in series.points:
fill = point.format.fill
fill.solid()
fill.fore_color.rgb = RGBColor(<color_code>)
point.data_label.has_text_frame = True
#Assigning custom text for data label associated with each data-point
point.data_label.text_frame.text = str(chart_data.categories[i].label) + "\n" + str(float(chart.series[0].values[i])) + "%"
for run in point.data_label.text_frame.paragraphs[0].runs:
run.font.size = Pt(10)
i+=1
data_labels.position = XL_LABEL_POSITION.OUTSIDE_END
PowerPoint is finicky about where you place certain chart attributes and feels free to ignore them when it wants (although it does so consistently).
A quick option worth trying is to set the value individually, point-by-point in the series. So something like:
for point in series.points:
point.data_label.position = XL_LABEL_POSITION.OUTSIDE_END
The most reliable method is to start by producing the effect you want by hand, using PowerPoint itself on an example chart, then inspecting the XML PowerPoint produces in the saved file, perhaps using opc-diag. Once you've identified what XML produces the desired effect (or discovered PowerPoint won't let you do it), then you can proceed to working out how to get the XML generated by python-pptx. That might make a good second question if you're able to get that far.
I made it work by writing the below code.
def apply_data_labels(self, chart):
plot = chart.plots[0]
plot.has_data_labels = True
for series in plot.series:
values = series.values
counter = 0
for point in series.points:
data_label = point.data_label
data_label.has_text_frame = True
data_label.text_frame.text = str(values[counter])
counter = counter + 1
the cause of error is setting the label position. no matter what you set it asks to repair the PPT. will have to drill down more to see why is it so.
Also to save some more time the formatting doesn't works(font color, size)
If anybody has any leads then please help.
To add on Vibhanshu's response, I could get the formatting (font type, font color, size etc) to work using the following code:
for idx, point in enumerate(chart.series[0].points):
# set position
point.data_label.position = XL_LABEL_POSITION.OUTSIDE_END
# set text
point.data_label.has_text_frame = True
point.data_label.text_frame.text = "This is an example"
# set formatting
for paragraph_idx, paragraph in enumerate(point.data_label.text_frame.paragraphs):
paragraph.line_spacing = 0.6 # set paragraph line spacing
for run in paragraph.runs:
run.font.size = Pt(30) #set font size
run.font.name = 'Poppins Medium' #set font name
run.font.color.rgb = RGBColor.from_string("FF0000") #set font color
I have a script which is designed to place inset maps onto specific pages while exporting Data Driven Pages, the script is amalgamation of a friend's work and some of my own code from other projects.
The issue is the code exports pages 15 and 16 twice one with my inset maps and the other without and I can't figure out why.
I think it is something to do with the indentation within the Loop but I cant get it so it behaves in any other way. Any help would be appreciated!
import arcpy, os, time, datetime
from datetime import datetime
start_time = datetime.now()
PageNumber = "Page "
# Create an output directory variable i.e the location of your maps folder
outDir = r"C:\Users\support\Desktop\Python\Book of Reference"
# Create a new, empty pdf document in the specified output directory
# This will be your final product
finalpdf_filename = outDir + r"\FinalMapBook.pdf"
if os.path.exists(finalpdf_filename): # Check to see if file already exists, delete if it does
os.remove(finalpdf_filename)
finalPdf = arcpy.mapping.PDFDocumentCreate(finalpdf_filename)
# Create a Data Driven Pages object from the mxd you wish to export
mxdPath = r"C:\Users\support\Desktop\Python\Book Of Reference\Book_Of_Reference_20160526_Python_Test.mxd"
tempMap = arcpy.mapping.MapDocument(mxdPath)
tempDDP = tempMap.dataDrivenPages
# Create objects for the layout elements that will be moving, e.g., inset data frame, scale text
Page15 = arcpy.mapping.ListDataFrames(tempMap)[1]
Page16 = arcpy.mapping.ListDataFrames(tempMap)[2]
# Instead of exporting all pages at once, you will need to use a loop to export one at a time
# This allows you to check each index and execute code to add inset maps to the correct pages
for pgIndex in range(1, tempDDP.pageCount + 1, 1):
# Create a name for the pdf file you will create for each page
temp_filename = r"C:\Users\support\Desktop\Python\Book of Reference\Book of Reference" + \
str(pgIndex) + ".pdf"
if os.path.exists(temp_filename):
os.remove(temp_filename) #Removes pdf if it is already in the folder
# Code for setting up the inset map on the first page #
if (pgIndex == 15):
# Set position of inset map to place it on the page layout
Page15.elementPositionX = 20.1717
Page15.elementPositionY = 2.0382
# Set the desired size of the inset map for this page
Page15.elementHeight = 9.7337
Page15.elementWidth = 12.7115
# Set the desired extent for the inset map
Page15insetExtent = arcpy.Extent(518878,108329,519831,107599)
Page15insetExtent = Page15insetExtent
arcpy.RefreshActiveView()
tempDDP.exportToPDF(temp_filename, "RANGE", pgIndex)
finalPdf.appendPages(temp_filename)
Page15.elementPositionX = 50 #Move the Inset back off the page
arcpy.RefreshActiveView() #Refresh to ensure the Inset has been removed
print PageNumber + str(pgIndex)
if (pgIndex == 16):
# Set up inset map
Page16.elementPositionX = 2.1013
Page16.elementPositionY = 18.1914
Page16.elementHeight = 9.7337
Page16.elementWidth = 12.7115
Page16insetExtent = arcpy.Extent(520012, 107962, 521156,107086)
Page16insetExtent = Page16insetExtent
arcpy.RefreshActiveView()
print PageNumber + str(pgIndex)
tempDDP.exportToPDF(temp_filename, "RANGE", pgIndex)
finalPdf.appendPages(temp_filename)
print PageNumber + str(pgIndex)
Page16.elementPositionX = 50
arcpy.RefreshActiveView()
# Else Fuction takes care of the pages that dont have insets and just itterates through using the loop on line 28
else :
tempDDP.exportToPDF(temp_filename, "RANGE", pgIndex)
finalPdf.appendPages(temp_filename)
print PageNumber + str(pgIndex)
# Clean up
del tempMap
# Update the properties of the final pdf
finalPdf.updateDocProperties(pdf_open_view="USE_THUMBS",
pdf_layout="SINGLE_PAGE")
# Save your result
finalPdf.saveAndClose()
end_time = datetime.now()
print('Duration: {}'.format(end_time - start_time))
I believe your problem is that when the pgIndex is 15 it performs the export as intended. Then it checks if the pgIndex is 16. The pgIndex is not 16 so it drops into the else and re-exports without the inset maps. I would recommend changing the second if to an elif
I have developed a console-based adventure game for my Sixth Form Computing class, and now want to migrate it into Tkinter. The main reason for this is that I can make use of pictures, mainly ones from game-icons.net.
So far so good, but the images are such high quality that they appear huge when I display them. Here is an example:
The code works by using a for loop to iterate through a list of items that are in the current area (that the player is in). Here is the code:
if len(itemKeys) > 0:
l = Label(lookWindow, text="Looking around, you see the following items....\n").pack()
for x in range(0, len(itemKeys)):
icon = PhotoImage(file=("icons\\" + itemKeys[x] + ".png"))
l = Label(lookWindow, image=icon)
l.photo = icon
l.pack()
l = Label(lookWindow, text=("" + itemKeys[x].title())).pack()
l = Label(lookWindow, text=(" " + locations[position][2][itemKeys[x]][0] + "\n")).pack()
else:
l = Label(lookWindow, text="There's nothing at this location....").pack()
The part saying ("icons\\" + itemKeys[x] + ".png") simply goes into the icons folder in the game directory and strings together a file name, which in this case would result in "key.png" because the item we're currently looking at is a key.
Now, however, I want to resize the image. I've tried using PIL (which people say is deprecated but I managed to install just fine?) but so far no luck.
Any help appreciated.
Jake
EDIT:
The question has been marked as a duplicate, but I've already tried to use it, but the person who answered seems to open a file, save it as a ".ppm"(?) file and then display it, but when I try I get a huge error that says that I couldn't display a "PIL.Image.Image".
EDIT 2:
Changed it to this:
im_temp = PILImage.open(("icons\\" + itemKeys[x] + ".png")).resize((250,250), PILImage.ANTIALIAS)
photo = PhotoImage(file=im_temp)
label = Label(lookWindow, image=photo)
label.photo = photo
label.pack()
and now get this:
For python 2 you can do something like this, it should work for python 3 as well after small changes of import
from tkinter import Tk, Label
from PIL import Image, ImageTk
root = Tk()
file = 'plant001.png'
image = Image.open(file)
zoom = 0.5
#multiple image zise by zoom
pixels_x, pixels_y = tuple([int(zoom * x) for x in image.size])
img = ImageTk.PhotoImage(image.resize((pixels_x, pixels_y))) # the one-liner I used in my app
label = Label(root, image=img)
label.image = img # this feels redundant but the image didn't show up without it in my app
label.pack()
root.mainloop()
Instead of resizing those huge images on-the-fly, you could preprocess them before bunding them with your application. I took the 'key' and 'locked chest' images and placed them in a 'icons' subdirectory, then ran this code:
from PIL import Image
import glob
for infn in glob.glob("icons/*.png"):
if "-small" in infn: continue
outfn = infn.replace(".png", "-small.png")
im = Image.open(infn)
im.thumbnail((50, 50))
im.save(outfn)
It created a 'key-small.png' and 'locked-chest-small.png', which you can use in your application instead of the original images.
I have this problem with chaco.
In the plot, I need select some points (are points that I generate). This points, I can select with two tools: RangenSelection and ScatterInspector. If I work with only one tool, the code work well and I can detect with points I select, but when I work with both tools, both tools write the same metadata name: selections. This is the most important part of the code:
#this are all the tools.append
my_plot.tools.append(ScatterInspector(my_plot, selection_mode="toggle", persistent_hover=False))
my_plot.overlays.append(
ScatterInspectorOverlay(my_plot,
hover_color = "transparent",
hover_marker_size = 10,
hover_outline_color = "purple",
hover_line_width = 2,
selection_marker_size = 8,
selection_color = "red")
)
my_plot.tools.append(RangeSelection(my_plot, left_button_selects = False, rigth_button_selects = True, auto_handle_event = False))
my_plot.overlays.append(RangeSelectionOverlay(component=my_plot))
my_plot.tools.append(PanTool(my_plot))
my_plot.overlays.append(ZoomTool(my_plot, drag_button="right"))
return plot
#the rest of the code
def _metadata_handler(self):
sel_indices = self.index_datasource.metadata.get('selections', [])
su = self.index_datasource.metadata.get('annotations', [])
print su
print "Selection indices:", sel_indices
def _plot_default(self):
plot = _create_plot_component()
# Retrieve the plot hooked to the tool.
my_plot = plot.plots["my_plot"][0]
# Set up the trait handler for the selection
self.index_datasource = my_plot.index
self.index_datasource.on_trait_change(self._metadata_handler,
"metadata_changed")
return plot
When I run the code, and see what are in annotations, is always empty. But in selections the code write with both tools and this give an error.
How can I tell to some tool in where metadata key write??
Thanks for your help.
The solution is put metadata_name="annotations" in RangeSelection and in RangeSelectionOverlay