I am iterating through my dataframe, using each value in each column to add in popup. However width of popup is too small therefore one value is shown in multiple rows.
this is what my code looks like:
c = folium.Map(
location=[12.323, 146.029326],
zoom_start=14
)
for row in df.itertuples():
name = getattr(row, "name")
age = getattr(row, "age")
folium.Marker(
location = location,
popup=folium.Popup(f"""name= {name} <br>
age = {age} <br>
"""),
icon=plugins.BeautifyIcon(
border_color = color,
border_width = 2,
text_color = 'black'
)
).add_to(c)
I want enough space for each column value. How can I do this?
You can use the parameter max_width for the Popup object. You can specify a number that depends on the number of caracters in the line of the name like this :
popup=folium.Popup(f"""name= {name} <br>
age = {age} <br>
""", max_width=len(f"name= {name}")*20),
Related
I have the following bits of code that creates a toplevel window and parses a dictionary into a Text widget:
def escrito(**kwargs):
write_window = Toplevel(root)
#write_window.title(kwargs) (problematic code)
writing_box = tk.Text(write_window, font = ("calibri", 20), width = 60, height = 15, wrap=WORD)
writing_box.pack(expand = tk.YES, fill = tk.X)
writing_box.grid(row = 0, column = 0, sticky = 'nswe')
texto = '\n'.join(key + ":\n" + value for key, value in kwargs.items())
writing_box.insert("1.0", texto)
def septic_osteo():
escrito(**infections.Septic_arthritis)
Septic_arthritis = {
'Empirical Treatment':
'Flucloxacillin 2g IV 6-hourly',
'If non-severe penicillin allergy':
'Ceftriaxone IV 2g ONCE daily',
'If severe penicillin allergy OR if known to be colonised with
MRSA':
'Vancomycin infusion IV, Refer to Vancomycin Prescribing
Policy',
'If systemic signs of sepsis': 'Discuss with Consultant
Microbiologist'
}
So when I run the code, the escrito functions parses the dictionary and writes its content onto a text widget contained on a Toplevel window. What I would like to know is how to dynamically rename the Toplevel window with the dicitonary's name. I do know that I can do this:
def septic_osteo():
escrito(**infections.Septic_arthritis)
write_window.title('Septic_arthritis)
but I do have like 100 functions like the one above, so, aside from labour intensive, I am not sure is the more pythonic way, so, is there a way that the window can be renamed with the dictionary name? (i.e. 'Septic_arthritis)
Thanks
If your data is in an object named infections, with attributes such as Septic_arthritis, the most straight-forward solution is to pass the data and the attribute as separate arguments, and then use getattr to get the data for the particular infection.
It would look something like this:
def escrito(data, infection):
write_window = Toplevel(root)
write_window.title(infection)
writing_box = tk.Text(write_window, font = ("calibri", 20), width = 60, height = 15, wrap="word")
writing_box.pack(expand = tk.YES, fill = tk.X)
writing_box.grid(row = 0, column = 0, sticky = 'nswe')
texto = '\n'.join(key + ":\n" + value for key, value in getattr(data, infection).items())
writing_box.insert("1.0", texto)
The important bit about the above code is that it uses getattr(data, infection) to get the data for the given infection.
If you want to create a button to call this function, it might look something like this:
button = tk.Button(..., command=lambda: escrito(infections, "Septic_arthritis"))
This will call the command escrito with two arguments: the object that contains all of the infections, and the key to the specific piece of information you want to display.
customerqtyUI = Label(homeUI, text = (str('number of customer:'), customer) , font = ('calibri', 20), background="floral white", foreground = 'black')
this is my code👆.
May i know why i cannot combine the string and my variable 'customer' together?
My output👆 will have a {} and i cannot remove it
I'm not sure how tkinter works, but in this case, you've passed a tuple consisting of str('number of customer:') and customer to the text keyword argument. What you really want to do is combine 'number of customers:' with the customer variable. Try this:
customerqtyUI = Label(homeUI, text = f'number of customer: {customer}', font = ('calibri', 20), background="floral white", foreground = 'black')
text field accepts a string. Passing a tuple (or any other type) will be counted as undefined behaviour. So the solution becomes
Label(..., text = 'number of customer: ' + str(customer), ...)```
I need your help to figure out how to make the following coding:
My idea is to get a message if fields name and quantity are in blank at the time I execute a function through a button. I printed what is the value if name and quantity are in blank and program says it is .!entry and .!entry2 respectively.
Unfortunately it doesn't work. What I am doing wrong?
if name == .!entry and quantity == .!entry2:
message = Label(root, text = 'Name and Quantity required' , fg = 'red')
message.grid(row = 4, column = 0, columnspan = 2, sticky = W + E)
return
As #JordyvanDongen pointed out in the comments you should use entry.get() to get the text inside the the entry object.
I suggest this for you code, assuming the entry objects are named name and quantity:
if not name.get() or not quantity.get():
message = Label(root, text = 'Both name and quantity are required', fg = 'red')
message.grid(row = 4, column = 0, columnspan = 2, sticky = W + E)
return None
I changed the conditional to or so that if either of the fields are blank it will be triggered but you may want to change it back to and depending on your purposes..
Currently I am using the following code to define and replace
Placeholder (Text data) in existing Powerpoint presentations.
current_dir = os.path.dirname(os.path.realpath(__file__))
prs = Presentation(current_dir + '/test2.pptx')
slides = prs.slides
title_slide_layout = prs.slide_layouts[0]
slide = slides[0]
for shape in slide.placeholders:
print('%d %s' % (shape.placeholder_format.idx, shape.name))
title = slide.shapes.title
subtitle1 = slide.shapes.placeholders[0]
subtitle2 = slide.shapes.placeholders[10]
subtitle10 = slide.shapes.placeholders[11]
subtitle11 = slide.shapes.placeholders[12]
subtitle1.text = "1"
subtitle2.text = "2"
subtitle10.text = "3"
subtitle11.text = "4"
slide2 = slides[1]
for shape in slide2.placeholders:
print('%d %s' % (shape.placeholder_format.idx, shape.name))
subtitle3 = slide2.shapes.placeholders[10]
subtitle4 = slide2.shapes.placeholders[11]
subtitle5 = slide2.shapes.placeholders[12]
subtitle6 = slide2.shapes.placeholders[13]
subtitle12 = slide2.shapes.placeholders[16]
companydate = slide2.shapes.placeholders[14]
subtitle3.text = "1"
subtitle4.text = "2"
subtitle5.text = "3"
subtitle6.text = "4"
subtitle12.text = "40%"
companydate.text = "Insert company"
slide3 = slides[2]
for shape in slide3.placeholders:
print('%d %s' % (shape.placeholder_format.idx, shape.name))
subtitle7 = slide3.shapes.placeholders[10]
subtitle8 = slide3.shapes.placeholders[11]
subtitle9 = slide3.shapes.placeholders[12]
subtitle13 = slide3.shapes.placeholders[16]
companydate2 = slide3.shapes.placeholders[14]
subtitle7.text = "1"
subtitle8.text = "2"
subtitle9.text = "3"
subtitle13.text = "5x"
companydate2.text = "Insert Company"
slide4 = slides[3]
# for shape in slide4.placeholders:
#print('%d %s' % (shape.placeholder_format.idx, shape.name))
companydate3 = slide4.shapes.placeholders[14]
companydate3.text = "Insert Company"
"'Adapting Charts'"
from pptx.chart.data import ChartData
from pptx.enum.chart import XL_CHART_TYPE
from pptx.util import Pt
"Adapting Chart 1"
prs1 = Presentation(current_dir + '/output4.pptx')
slides1 = prs1.slides
chart1 = prs1.slides[0].chart
However, I am also running analytics in the background and I was wondering if it is possible to recognize (define) charts in the same presentation along with extracting and replacing the data in those charts. These chards are not embedded in the template.
As plotting charts with plotly or mathplotlib does not render a compliant image I am not able to use these , unless fully modified into the following format:Graph budget Click Correl
If yes, would it be possible to give concrete coding examples?
Thanks in advance!
Yes, it's possible to do that. The documentation will be your best source.
This will find the chart shapes:
for shape in slide.shapes:
if shape.has_chart:
chart = shape.chart
print('found a chart')
Data is extracted from the chart series(es):
for series in chart.series:
for value in series.values:
print(value)
Data is replaced by creating a new ChartData object and calling .replace_data() on the chart using that chart data object:
chart_data = ChartData(...)
... # add categories, series with values, etc.
chart.replace_data(chart_data)
http://python-pptx.readthedocs.io/en/latest/api/chart.html#pptx.chart.chart.Chart.replace_data
Adding to the answer by #scanny above, this worked for me:
if shape.name == 'Chart1':
chart = shape.chart
print(shape.name)
for series in chart.plots:
print(list(series.categories))
cat = list(series.categories)
for series in chart.series:
ser = series.values
print(series.values)
try:
# ---define new chart data---
chart_data = CategoryChartData()
chart_data.categories = cat
chart_data.add_series('category', df['column'])
# ---replace chart data---
chart.replace_data(chart_data)
except KeyError:
continue
Using the code above, you can print the categories and the series values, then replace them with your new values (while keeping category the same).
I added the KeyError exception because without it, you get a "rId3" error. From the forums it seems like there is some XML writing issue in writing to PPTX.
How do you turn off (or hide) the seconds y axis scale on a combination chart in openpyxl?
I can find the xml difference by comparing the before and after changes to hide the scale (I just change the excel file extension to '.zip' to access the xml):
-<c:valAx>
<c:axId val="156672520"/>
-<c:scaling>
<c:orientation val="minMax"/>
</c:scaling>
<c:delete val="0"/>
<c:axPos val="r"/>
<c:majorGridlines/>
<c:numFmt sourceLinked="1" formatCode="0.0"/>
<c:majorTickMark val="out"/>
<c:minorTickMark val="none"/>
<c:tickLblPos val="none"/> # this changes from 'nextTo'
<c:crossAx val="207247000"/>
<c:crosses val="max"/>
<c:crossBetween val="between"/>
</c:valAx>
I've tried this (last few lines are the 'tickLblPos' ):
mainchart = LineChart()
mainchart.style = 12
v2 = Reference(WorkSheetOne, min_col=1, min_row=2+CombBarLineDataOffsetFromTop, max_row=3+CombBarLineDataOffsetFromTop, max_col=13)
mainchart.add_data(v2, titles_from_data=True, from_rows=True)
mainchart.layout = Layout(
ManualLayout(
x=0.12, y=0.25, # position from the top
h=0.9, w=0.75, # this is scaling the chart into the container
xMode="edge",
yMode="edge",
)
)
mainchart.title = "Chart Title"
# Style the lines
s1 = mainchart.series[0]
#Marker type
s1.marker.symbol = "diamond" # triangle
s1.marker.size = 9
s1.marker.graphicalProperties.solidFill = "C00000" # Marker filling
s1.marker.graphicalProperties.line.solidFill = "000000" # Marker outline
s1.graphicalProperties.line.noFill = False
# Line color
s1.graphicalProperties.line.solidFill = "000000" # line color
s2 = mainchart.series[1]
s2.graphicalProperties.line.solidFill = "000000"
s2.graphicalProperties.line.dashStyle = "dash"
mainchart.dataLabels = DataLabelList()
mainchart.dataLabels.showVal = False
mainchart.dataLabels.dLblPos = 't'
mainchart.height = 15
mainchart.width = 39
#Create the Chart
chart2 = BarChart()
chart2.type = "col"
chart2.style = 10 # simple bar
chart2.y_axis.axId = 0
dataone = Reference(WorkSheetOne, min_col=2, min_row=CombBarLineDataOffsetFromTop+1, max_row=CombBarLineDataOffsetFromTop+1, max_col=13 )
doneseries = Series(dataone, title="Series Title")
chart2.append(doneseries)
cats = Reference(WorkSheetOne, min_col=2, min_row=CombBarLineDataOffsetFromTop, max_row=CombBarLineDataOffsetFromTop, max_col=13)
chart2.set_categories(cats)
# Set the series for the chart data
series3Total = chart2.series[0]
fill3Total = PatternFillProperties(prst="pct5")
fill3Total.foreground = ColorChoice(srgbClr='996633') # brown
fill3Total.background = ColorChoice(srgbClr='996633')
series3Total.graphicalProperties.pattFill = fill3Total
chart2.dataLabels = DataLabelList()
chart2.dataLabels.showVal = False
chart2.shape = 2
mainchart.y_axis.crosses = "max"
mainchart.y_axis.tickLblPos = "none" # nextTo -- this doesn't work
mainchart += chart2
WorkSheetOne.add_chart(mainchart, 'A1')
How can I translate the difference in the XML to an attribute with openpyxl?
The problem here is with some of default values for some attributes which use 3-valued logic at times so that None != "none", ie. <c:tickLblPos /> != <c:tickLblPos val="none"/> because the default is "nextTo". This plays havoc with the Python semantics (3-valued logic is always wrong) where the default is not to set an attribute if the value is None in Python. This really only affects ChartML and I've added some logic to the descriptors for the relevant objects so that "none" will be written where required.
But this code isn't publicly available yet. Get in touch with my by e-mail if you'd like a preview.