plotly go Scattermapbox is not showing markers - mapbox

I some how have encountered some odd bug. When i try to create a Scattermapbox the markers dont render. This bug came out of no where, It was working perfectly fine then my internet went out and now for the last 8 hours it has not been working.
Ive tried running it in different IDE's
running it in google colab to make sure its not my machine
different data sets.
i am unsure what i have done wrong
The tooltips do display however when i hover over the invisible points.
and if use the export to png button everything is shown.
but no matter what it wont show up on the actual map itself and i am at my wits end.
I will include the callback function bellow.
#app.callback(
Output('2dmap','figure'),
[Input('2dgraph', 'clickData'),
Input('checklist', 'value')])
def update_map_2d(clickData,checklist):
# =============================================================================
# P1. Render Map when no point is clicked
# =============================================================================
# If No point has been clicked
if clickData is None:
#make a map
maps2d = go.Figure(go.Scattermapbox(
lat=[], # set lat and long
lon=[],
mode='markers',
marker =({'size':5.5}) # make markers size variable
))
# set up map layout
maps2d.update_layout(
autosize=True, # Autosize
hovermode='closest', # Show info on the closest marker
showlegend=True, # show legend of colors
mapbox=dict(
accesstoken=mapbox_access_token, # token
bearing=0, # starting facing direction
# starting location
center=dict(
lat=td.cLat,
lon=td.cLong
),
#angle and zoom
pitch=0,
zoom=12
),
#height and width
width=1000,
height=1000
)
return maps2d
else:
xCoord = int(clickData['points'][0]['x'])
yCoord = int(clickData['points'][0]["y"])
solutionRow = preatoFrontier.loc[(preatoFrontier['x'] == xCoord)&(preatoFrontier['y'] == yCoord)]
solId = int(solutionRow['SolId'])
#solId = 49
solution = td.getSolution(solutions, solId)
color = []
for row in solution['upGrade']:
if row == 0:
color.append('grey')
if row == 1:
color.append('green')
if row == 2:
color.append('blue')
if row == 3:
color.append('red')
solution['color'] = color
solution2 = solution[solution['color'].isin(checklist)]
maps2d = go.Figure(go.Scattermapbox(
lat=solution2['lat'],
lon=solution2['long'],
mode='markers',
#marker =({'color':solution['color']},{'size':5.5})
marker=dict(
size=12,
color=solution2['color'], #set color equal to a variable
colorscale='Viridis', # one of plotly colorscales
showscale=True
)
))
#=============================================================================
# P3. Map Layout
#=============================================================================
#set up map layout
maps2d.update_layout(
autosize=False, # Autosize
hovermode='closest', # Show info on the closest marker
showlegend=True, # show legend of colors
mapbox=dict(
accesstoken=mapbox_access_token, # token
bearing=0, # starting facing direction
# starting location
center=dict(
lat=td.cLat,
lon=td.cLong
),
#angle and zoom
pitch=0,
zoom=10
),
#height and width
width=1000,
height=1000
)
return maps2d

After a lot of hair pulling, i thought to try creating a new venv and uploading packages one by one and running to see how and where it fails. The last package i installed before it broke was dash-tools and sure enough some how that was causing mapbox to bug out hard. So dont install dash-tools

Related

Unmerge and Assign Values Only Vertically or Horizontally Openpyxl

Using the answer provided by aka863 here: How to split merged Excel cells with Python?
I can unmerge, fill values and copy the styling. My questions is how to make the value assigning/filling process configurable.
I want the user to be able to choose whether the values will be filled vertically/horizontally.
I have tried changing the last loop where we assign the top_left_cell_values to unmerged cells. However I couldn't find a way to make it horizontal/vertical configurable. (I'm planning to use radio buttons and tkinter for this)
Its certainly possible to have the code de-merge cells and fill cells in whichever direction, vertically or horizontally regardless of which way the merge was originally. Or not fill at all, so only the top left cell retains the 'value' of the previously merged cells, which is default on unmerge.
Changing the direction of the fill requires some change and re-calculation on the max row and column values in the iter_rows loop, but is simple enough.
However it seems in your last comment you just want to give the user the option to fill or not fill on horizontal merges. In that case you just need to ask the question, and then run the iter_rows loop only if the response is yes.
The code sample below is based on the answer referenced question.
I'm assuming only single line horizontal merges since you dont mention what if anything should be done with vertical merges in the comment.
The code does initially check and indicate the merge direction either vertically or horizontally so it can be included take some action if a merge is vertical.
On code run after displaying the range and direction of the merge, the question is asked to fill, yes or no. If yes the cells are de-merged and all cells filled with the top left cell value using the iter_rows loop. If answer no then the cells are just de-merged.
from openpyxl import load_workbook
from openpyxl.utils.cell import range_boundaries
wb = load_workbook(filename='foo.xlsx')
st = wb['Sheet1']
mcr_coord_list = [mcr.coord for mcr in st.merged_cells.ranges]
direction_dict = {'v': 'vertical', 'h': 'horizontal'}
for mcr in mcr_coord_list:
print('---------------------------------------------------\n')
merge_direction = ''
min_col, min_row, max_col, max_row = range_boundaries(mcr)
top_left_cell_value = st.cell(row=min_row, column=min_col).value
if min_col == max_col:
merge_direction = 'v'
elif min_row == max_row:
merge_direction = 'h'
print(f"The cell range {mcr} is merged {direction_dict[merge_direction]}ly with the data '{top_left_cell_value}'")
while True:
demerge_fill = input('Do you want the de-merge to fill all cells(y|n)? ')
if demerge_fill.lower() in ["y", "n"]:
break
else:
print('Invalid response')
st.unmerge_cells(mcr)
if demerge_fill == 'y':
for row in st.iter_rows(min_col=min_col, min_row=min_row, max_col=max_col, max_row=max_row):
for cell in row:
cell.value = top_left_cell_value
else:
print(f"Only the top left cell {mcr.split(':')[0]} will contain the data!")
wb.save('merged_tmp.xlsx')

Is there a way to get the ECharts series symbol to be passed in as the marker in the tooltip

I've got an ECharts chart that has multiple line series and a scatter series that represents events. For the line series, we left the symbol at the default, but for the event scatter series we set the symbol to 'diamond'. These symbols show up on the chart & in the series legend as expected. However, the tooltip always shows a 10 pixel dot for the marker. The color however is picked up from the series (and even from the visualMap config!). My initial assumption had been that the symbol would also be picked up from the series. In our case we wanted to use a function for tooltip.formatter and even in that function we couldn't figure out how to access and swap in the series symbol for the marker. We ended up working around it by just custom styling our own html to plug in for the marker that matched the diamond symbol pretty well.
So the open questions are:
Is there a way to have the tooltip marker pick up the symbol from the series?
If not, is this a bug? I'm happy to put in an issue on the project but I don't want to do that until I understand a bit more.
Here's some code to illustrate what we had to do to get the diamond in there in case it helps the discussion or if others want to leverage this workaround:
formatTooltip(args){
let time = DateTime.fromISO(args[0].data[0], { zone: this.user.timeZone })
let tooltip = `<div><b>${time.toFormat(TOOLTIP_FORMAT)}</b></div>`
args.forEach(({ marker, seriesName, value }) => {
if (seriesName === 'Events'){
let myMarker = `<span style="display:inline-block;margin-right:4px;width:10px;height:10px;background:${value[4]};transform:rotate(45deg);"></span>`
tooltip += `<div>${myMarker} ${value[3] ? value[3]: ''}</div>`
} else {
value = value || [0, 0]
tooltip += `<div>${marker} ${seriesName}: ${value[1]}</div>`
}
})
return tooltip
},

How to keep selected data persistent through callback in Dash/Plotly's clustered bar chart

I'm using Dash to plot some data. I currently have a clustered bar chart with two data sets (one for each bar in the clusters.) These data sets have their name and the corresponding color of the bars displayed in the top, left-hand corner of the figure. They can be clicked to be toggled on and off, which will remove their corresponding bars from the chart.
Separately, I have a checklist of items that can be displayed in the chart. I am using a callback to update the graph so that it only displays what the user has checked. This updates the graph as expected, however, it also resets the bars/datasets such that both are enabled. Ie. if you select only one of the bars, then select some new checklist items, it will display the new checklist items and both of the bars.
My thinking is that the logical way to do this is to pass some variable as a second input to the callback function, then set up the outputted figure within the function to only display the proper bars. However, I can't seem to find a variable that contains this data.
From what I can tell, the accessible properties of the Plotly graph object are 'id', 'clickData', 'clickAnnotationData', 'hoverData', 'clear_on_unhover', 'selectedData', 'relayoutData', 'figure', 'style', 'className', 'animate', 'animation_options', 'config', and 'loading_state'.
I've investigated all of these, and it seems that none hold the data that I am looking for. Does anyone know of an easy way to access this data?
This is how my callback is working right now:
#app.callback(
dash.dependencies.Output('theGraph', 'figure'),
[dash.dependencies.Input('theChecklist','values'),
dash.dependencies.Input('theGraph', 'clickData')
]
)
def updateGraph(checklistValues, figureInput):
#print to see what the variables hold
print(checklistValues)
print(figureInput)
figure=go.Figure(
data = [
go.Bar(
x = df[df['MyColumnName'].isin(checklistValues)].groupby('MyColumnName').size().index,
y = df[df['MyColumnName'].isin(checklistValues)].groupby('MyColumnName').size().values,
name = 'Bar 1'
),
go.Bar(
x = df[df['MyColumnName'].isin(checklistValues)].groupby('MyColumnName')['# cores'].sum().reset_index()['MyColumnName'],
y = df[df['MyColumnName'].isin(checklistValues)].groupby('MyColumnName')['# cores'].sum().reset_index()['MyOtherColumnName'],
name = 'Bar 2'
)
],
layout=go.Layout(
title='The Title',
showlegend=True,
legend=go.layout.Legend(
x=0,
y=1.0
),
margin=go.layout.Margin(l=40, r=40, t=40, b=110)
)
)
return figure

Perl Tk: Canvas dynamic updating

I'm trying to animate the results of a mathematical process in a 2D canvas with Tk. I've decided to do it with Tk and not SDL because right now i'm working with both Linux and Windows machines and Strawberry Perl doesn't compile proberly in windows, whil Tk is up on both pcs.
What i would like to do with Tk is that:
1)Popping up the canvas while my program is working out the coordinates of the points i would like to draw.
2)Drawing them instantly into the canvas without waiting for the process to reach the end
It's actually a simple animation, where a bunch of points moves around the Canvas while my script updates their coordinates.
Here you have a code snippet i've been writing so far for a single point:
use Tk;
#calcuate the coordinate of a single point
$x=10;
$y=10;
$top = MainWindow->new();
# create a canvas widget
$canvas = $top->Canvas(width => 600, height => 400) -> pack();
# For example, let's create 1 point inside the canvas
$canvas->create ('oval', $x, $y, $x+3, $y+3, -fill=>"black"); # fill color of object
MainLoop;
The problem with the above code is that i would like to add my 'math' script inside it in order to update the $x and $y coordinates above (with some sort of for/while cycle) without shutting down the original canvas, by obtaining a single point moving all around it (atually there are more points i'm supposed to display but that's a minor detail).
FYI, using a simple for cycle embedding the ''Mainloop'' directive doesn't fix the problem.
Thanks in advance guys
Quoting from Mastering Perl/Tk, chapter 15 "Anatomy of the MainLoop":
Option 1: use your own MainLoop implementation
use Tk qw(:eventtypes);
while (Tk::MainWindow->Count) {
# process events - but don't block waiting for them
DoOneEvent(ALL_EVENTS | DONT_WAIT);
# your update implementation goes here
}
Option 2: use a repeat timer event
Later in the chapter it is stated that DoOneEvent() isn't really necessary for most stuff. You could use timer events instead, e.g.
my $update = sub {
# your update implementation goes here
};
# run update every 50ms
$top->repeat(50, $update);
MainLoop;
SOLUTION:
As per Stefan Becker suggested option nr.2, here is what has finally fixed the problem:
use Tk:
$top = MainWindow->new();
# create a canvas widget
$canvas = $top->Canvas(width => 600,
height => 400,
background => 'black') -> pack();
$x=300;
$y=200;
my $update = sub {
$canvas->delete('all'); #unquote this line if you don't want the original point positions to be drawn in the canvas. Viceversa
$x=$x+(-5+rand(10)); #white noise
$y=$y-(-5+rand(10)); #white noise
$canvas->create ('oval', $x , $y , $x+5, $y+5, -fill=>"red");
};
$top->repeat(50, $update);
MainLoop;
I've just added the statement $canvas->delete('all') at the beginning of the updating loop in order to draw just actual points and not the history.

Controlling window position of a Powershell console

This works:
(Get-Host).UI.RawUI
$a = (Get-Host).UI.RawUI
$a.BackgroundColor = "white"
$a.ForegroundColor = "black"
$size = (Get-Host).UI.RawUI.WindowSize
$size.Width = 80
$size.Height = 30
(Get-Host).UI.RawUI.WindowSize = $size
But this doesn't work, and I am not sure how to make it work:
$position = (Get-Host).UI.RawUI.Windowposition
$position.X = 0
$position.Y = 30
(Get-Host).UI.RawUI.Windowposition = $position
The error I get is strange. It complains about "buffer" when I am trying to set external window position:
Exception setting "WindowPosition": "Cannot use the
specified Window X (column) position because it extends
past the width of the screen buffer. Specify another X
position, starting with 0 as the left most column of
the buffer.
The error is not really strange, because WindowPosition Gets and sets the position, in characters, of the view window relative to the screen buffer.
It does not set the position of the Window, but to put it crudely, the position in the buffer that you see through the view of the window. So in your case, you are getting the error because it is outside the buffer.
http://msdn.microsoft.com/en-us/library/system.management.automation.host.pshostrawuserinterface.windowposition%28v=vs.85%29.aspx
Unfortunately, setting the position of the window is not simple. There is a snapin for it though - http://wasp.codeplex.com/ ( use Set-WindowPosition)
Take a look at this script: Resize-Console.ps1 – Resize console window/buffer using arrow keys.
It is hopefully useful itself and partially should answer the question (the size part).