I'm trying to create a tool that will allow a user to select different parameters for plotting model data. I can generate the widgets initially, but I'd like to update one of the widgets based on a possible selection from the user.
Bokeh page
In this example, I've defaulted the value "Phase" to "Water" and "Effective Radius" to a list of values that correspond with water-only. If the user selects "Ice" from "Phase", I'd like the widget to update from a different list of values. Here is the relevant code:
from bokeh.models.widgets import (Slider, Button, CheckboxGroup,
RadioButtonGroup, RadioGroup, Dropdown, Select)
# Selector for phase.
#--------------------
phs = [ "Water", "Ice", "Clear" ]
phs_select1 = Select( title="Cloud Phase", value=phs[0], options=phs,
width=150 )
phs_select2 = Select( title="Cloud Phase", value=phs[0], options=phs,
width=150 )
def update_phs( flag ):
if flag == 0:
fname[flag,3] = phs_select1.value.lower()
update_de_list( )
de_select1.update()
if flag ==1:
fname[flag,3] = phs_select2.value.lower()
update_de_list( )
phs_select1.on_change( 'value', lambda attr, new, old: update_phs(0) )
phs_select2.on_change( 'value', lambda attr, new, old: update_phs(1) )
# Selector for effective diameter.
#----------------------------
de = [np.str(x) for x in (8, 20, 32, 50)]
def update_de_list():
# Add something here to update the widget?
?????????????????????????
if phs_select1.value.lower() == "water":
de = [np.str(x) for x in (8, 20, 32, 50)]
elif phs_select1.value.lower() == "ice":
de = [np.str(x) for x in (21.86, 46.34, 115.32)]
????????????????????????????????????
?
? Once user has selected a different phase, I need to update
? "Effective Diameter field.
?
?????????????????????????
de_select1= Select( title="Effective Diameter", value=de[0], options=de,
width=150 )
de_select2 = Select( title="Effective Diameter", value=de[0], options=de,
width=150 )
def update_de( flag ):
if flag == 0:
fname[flag,5] = "de"+de_select1.value
if flag == 1:
fname[flag,5] = "de"+de_select2.value
de_select1.on_change( 'value', lambda attr, new, old: update_de(0) )
de_select2.on_change( 'value', lambda attr, new, old: update_de(1) )
# Layout the widgets for the first file
lft_pnl = [srf_select1,igbp_select1,tau_select1,ws_select1,aod_select1]
rgt_pnl = [ prf_select1, phs_select1, de_select1, cld_select1 ]
lft_col = WidgetBox( *lft_pnl, sizing_mode="fixed", width=150)
rgt_col = WidgetBox( *rgt_pnl, sizing_mode="fixed", width=150)
# Layout the widgets for the first file
lft_pnl = [srf_select2,igbp_select2,tau_select2,ws_select2,aod_select2]
rgt_pnl = [ prf_select2, phs_select2, de_select2, cld_select2 ]
lft_col2 = WidgetBox( *lft_pnl, sizing_mode="fixed", width=150)
rgt_col2 = WidgetBox( *rgt_pnl, sizing_mode="fixed", width=150)
pnl_layout = layout([[lft_col, rgt_col],[lft_col2,rgt_col2],[plt_button]])
l = layout(children=[[grid,pnl_layout]])
curdoc().add_root( l )
Some bits of code are missing in your example, so I hope I understood your problem correctly :). As far as I can tell, you would like to change the options in the "Effective Diameter" field when the user changes the selection in the "Cloud Phase" field. I think to achieve what you would like to, you could just replace the following line inside the update_de_list() callback:
de = [np.str(x) for x in (21.86, 46.34, 115.32)]
with:
de_select1.options = [np.str(x) for x in (21.86, 46.34, 115.32)]
de_select2.options = [np.str(x) for x in (21.86, 46.34, 115.32)]
Related
I am trying to create a table of events with gtsummary and I would like to obtain a final row counting the events of the previous rows. add_overall() and add_n() do add the total but in a column, counting the same event across groups but not the overall events.
I created this example.
x1 <- sample(c("No", "Yes"), 30, replace = TRUE, prob = c(0.85, 0.15))
x2 <- sample(c("No", "Yes"), 30, replace = TRUE, prob = c(0.9, 0.1))
x3 <- sample(c("No", "Yes"), 30, replace = TRUE, prob = c(0.75, 0.25))
y <- sample(c("A", "B"), 30, replace = TRUE, prob = c(0.5, 0.5))
df <- data.frame(as_factor(x1), as_factor(x2), as_factor(x3), as_factor(y))
colnames(df) <-c("event_1", "event_2", "event_3", "group")
tbl_summary(df, by=group, statistic = all_categorical() ~ "{n}")
example
I tried using summary_rows() function from gt package after converting the table to a gt object but there is an error when summarising because these variables are factors.
Any other ideas?
You can do this by adding a new variable to your data frame that is the row sum of each of the events. Then you can display that variable's sum in the summary table. Example below!
library(gtsummary)
#> #Uighur
library(tidyverse)
df <-
data.frame(
event_1 = sample(c(FALSE, TRUE), 30, replace = TRUE, prob = c(0.85, 0.15)),
event_2 = sample(c(FALSE, TRUE), 30, replace = TRUE, prob = c(0.9, 0.1)),
event_3 = sample(c(FALSE, TRUE), 30, replace = TRUE, prob = c(0.75, 0.25)),
group = sample(c("A", "B"), 30, replace = TRUE, prob = c(0.5, 0.5))
) |>
rowwise() |>
mutate(Total = sum(event_1, event_2, event_3))
tbl_summary(
df,
by = group,
type = Total ~ "continuous",
statistic =
list(all_categorical() ~ "{n}",
all_continuous() ~ "{sum}")
) |>
as_kable() # convert to kable to display on stack overflow
Characteristic
A, N = 16
B, N = 14
event_1
4
4
event_2
1
2
event_3
7
6
Total
12
12
Created on 2023-01-12 with reprex v2.0.2
Thank you so much (great package gtsummary). That works! I had some trouble summing over factors. If variables are factors the code
mutate(Total = sum(event_1=="Yes", event_2=="Yes", event_3=="Yes"))
does it.
As an author, I frequently have to swap two words, phrases or sentences. I do that by dragging and dropping or by using the clipboard history, or by retyping, all of which are cumbersome and prone to mistakes.
Is there a command or macro to automatically swap two selections?
Example: after selecting 'short' and 'simple' in the sentence 'This is a short and simple example' and swapping them, the sentence would become 'This is a simple and short example'
For simple word swapping, it would be handy if such a function would default to selecting the words with a cursor (empty selection) in them.
Example: place two cursors in the above sentence, one in the word 'simple' and one in 'short', and they'll be automatically selected and reversed.
For swapping a word and a phrase, it would be handy if I could select the word by Ctrl-clicking and the phrase by dragging to have it automatically selected (that is, a combination of 1 and 2).
More generally, I would like to be able to invert any number of selections of any length anywhere in a document.
Simple example: the text 'a b c d e f g' with the a, the c, the e and the g selected becomes 'g b e d c f a'.
Obviously swapping two selections is a special case of reversing any number of selections.
Here is a JavaScript macro for EmEditor to swap multiple selections or words at the cursor positions.
Redraw = false; // optimize for speed
CombineHistory = true; // combine Undo
nMax = document.selection.Count; // retrieve the number of selections
ax = Array( nMax );
ax2 = Array( nMax );
ay = Array( nMax );
ay2 = Array( nMax );
as = Array( nMax );
for( i = 0; i < nMax; ++i ) { // retrieve position of each selection
ax[i] = document.selection.GetTopPointX( eePosLogical, i + 1 );
ax2[i] = document.selection.GetBottomPointX( eePosLogical, i + 1 );
ay[i] = document.selection.GetTopPointY( eePosLogical, i + 1 );
ay2[i] = document.selection.GetBottomPointY( eePosLogical, i + 1 );
}
for( i = 0; i < nMax; ++i ) { // retrieve word text and positions
if( ax[i] == ax2[i] && ay[i] == ay2[i] ) {
document.selection.SetActivePoint( eePosLogical, ax[i], ay[i] ); // set cursor position
document.selection.SelectWord(); // select a word
ax[i] = document.selection.GetTopPointX( eePosLogical ); // retrieve selection position
ax2[i] = document.selection.GetBottomPointX( eePosLogical );
as[i] = document.selection.Text; // retrieve selected text
}
else {
document.selection.SetActivePoint( eePosLogical, ax[i], ay[i] );
document.selection.SetActivePoint( eePosLogical, ax2[i], ay2[i], true );
as[i] = document.selection.Text; // retrieve selected text
}
}
for( i = nMax - 1; i >= 0; --i ) { // set a selection from bottom to top
document.selection.SetActivePoint( eePosLogical, ax[i], ay[i] );
document.selection.SetActivePoint( eePosLogical, ax2[i], ay2[i], true );
document.selection.Text = as[nMax - i - 1]; // set new text
}
To run this, save this code as, for instance, Macro.jsee, and then select this file from Select... in the Macros menu. Finally, select Run Macro.jsee in the Macros menu while multiple selections are made.
i am reading the document https://plotly.com/r/reference/sankey/, and want to change the links color for a sankey chart. But i can't quite understand the parameters in add_trace() function
where should i specify the color value?
add_trace(p,type='sankey', color=????)
You haven't provided a minimal reproducible example, so I can't jump right into your code. But I think I can point you in the right direction.
In the documentation you screenshotted, it's saying that the color argument is one key of the list link that defines links in the plot. Using this example from the R plotly documentation for adding links, let's take a look at where that goes:
library(plotly)
library(rjson)
json_file <- "https://raw.githubusercontent.com/plotly/plotly.js/master/test/image/mocks/sankey_energy.json"
json_data <- fromJSON(paste(readLines(json_file), collapse=""))
fig <- plot_ly(
type = "sankey",
domain = list(
x = c(0,1),
y = c(0,1)
),
orientation = "h",
valueformat = ".0f",
valuesuffix = "TWh",
node = list(
label = json_data$data[[1]]$node$label,
color = json_data$data[[1]]$node$color,
pad = 15,
thickness = 15,
line = list(
color = "black",
width = 0.5
)
),
link = list(
source = json_data$data[[1]]$link$source,
target = json_data$data[[1]]$link$target,
value = json_data$data[[1]]$link$value,
label = json_data$data[[1]]$link$label,
#### Color goes here! ####
color = "yellow"
)
)
fig <- fig %>% layout(
title = "Energy forecast for 2050<br>Source: Department of Energy & Climate Change, Tom Counsell via <a href='https://bost.ocks.org/mike/sankey/'>Mike Bostock</a>",
font = list(
size = 10
),
xaxis = list(showgrid = F, zeroline = F),
yaxis = list(showgrid = F, zeroline = F)
)
fig
The plotly documentation can be a bit opaque at times. I have found it helpful to sometimes review the documentation for python. For example, this part of the python documentation does give some more guidance about changing link colors.
I figured out how to compare dates in Google Sheets but when I try to enter more dates for some reason all the cells that were green and red become all red. Also how can I make two cells red if only one cell has a date?
Example: In cell D18 the Due date is 4-18-2014 and in cell E18 the cell is blank. I want to make both cells red so I would know that I should find out why is that cell red.
This is the code I have so far:
function onEdit() {
var ss = SpreadsheetApp.getActiveSpreadsheet();
var s = ss.getSheetByName('Copy of Project Sheet 1');
var values1Rule1 = s.getRange('E2:E1000').getValues();
var values2Rule1 = s.getRange('D2:D1000').getValues();
var range3Rule1 = s.getRange('D2:E2');
var color1 = 'Red';
var color2 = 'Green';
for (var row in values1Rule1) {
for (var col in values1Rule1[row]) {
if (values1Rule1[row][col] > values2Rule1[row][col]) s.getRange(s.getRange('D2').offset(row, col, 1, 2).getA1Notation()).setBackgroundColor(color1);
else if (values1Rule1[row][col] < values2Rule1[row][col]) s.getRange(s.getRange('D2').offset(row, col, 1, 2).getA1Notation()).setBackgroundColor(color2);
else s.getRange(s.getRange('D2').offset(row, col, 1, 2).getA1Notation()).setBackgroundColor('white'); }}
};
All you need to do is add this condition as an OR clause in your red condition, e.g.
if (values1Rule1[row][col] > values2Rule1[row][col] || values1Rule1[row][col] === '')
But there's lots of "minor" problems with your code. First of all, you're doing way too many API calls unnecessarily. This is a big performance issue. For example, when you offset, you already have the new range, there's no need to getA1Notation then get the range again, you could do:
s.getRange('D2').offset(row, col, 1, 2).setBackgroundColor(color1);
But that's still two calls, getting D2, then offseting. You could get the desired range at once:
s.getRange(row+1, 4, 1, 2).setBackgroundColor(color1);
I'd go even further and build a matrix of colors and set it all at once after the loop:
s.getRange('D2:E1000').setBackgroundColors(colors);
But even better, inside an onEdit you should only work on what has just being edited, instead of triggering a full recalculation of your colors because the user edited something on another column or another sheet entirely.
I think your code should be something like this:
function onEdit(e) {
var ss = e.source;
var s = ss.getActiveSheet();
if( s.getName() !== 'Copy of Project Sheet 1' ) return; //only interested in one sheet
var r = s.getActiveRange();
var c = r.getColumn();
if( c !== 4 && c !== 5 ) return; //only interested in changes on columns D or E
r = r.offset(0, c === 4 ? 0 : -1, 1, 2);
var v = r.getValues()[0];
r.setBackgroundColor(v[1] === '' || v[1] > v[0] ? 'red' : v[1] < v[0] ? 'green' : 'white');
}
--edit
You can not run this function manually directly, because it needs a parameter that is passed only when it runs automatically. But you can emulate it with a test function, like this:
function testEdit() { onEdit({source:SpreadsheetApp.getActive()}); }
Hey tired this new code to animate objects (here bubbles) and make them stationary using sprites. The code is as below,
local ui = require("ui")
local gameUI = require("gameUI")
local easingx = require("easingx")
require "sprite"
display.setStatusBar( display.HiddenStatusBar )
local physics = require("physics")
physics.start()
physics.setScale( 60 )
local backgroundPortrait = display.newImage( "sky.png", 0, 0 )
local backgroundLandscape = display.newImage( "sky.png", 80, 80 )
backgroundLandscape.isVisible = false
local disp = backgroundLandscape
local function selectBubble( event )
local tapped = event.target --event.target is how Corona points to the tapped bubble
if ( tapped.bubbleSelected == false ) then
local vx,vy = tapped:getLinearVelocity()
tapped.xVel = vx --stores the current velocity into bubble's "xVel" variable
tapped.yVel = vy --likewise for yVel
tapped:setLinearVelocity( 0,0 ) --set bubble's velocity to 0!
tapped.currentFrame = (3)
tapped.bubbleSelected = true
elseif ( tapped.bubbleSelected == true ) then
tapped:setLinearVelocity( tapped.xVel, tapped.yVel ) --read previous velocity and set
tapped.bubbleSelected = false
end
end
--BUBBLE1
local bubble1 = sprite.newSprite( spriteSet1 )
bubble1.x = 100
bubble1.y = 100
physics.addBody(bubble1, {bounce=0.04, filter = bubbleCollisionFilter})
bubble1:setLinearVelocity( 2, 4 )
bubble1:addEventListener( "tap", selectBubble )
bubble1.bubbleSelected = false
bubble1:prepare("bubble")
bubble1:play()
--BUBBLE2
local bubble2 = sprite.newSprite( spriteSet1 )
bubble2.x = 210
bubble2.y = 20
physics.addBody(bubble2, {bounce=0.05, filter = bubbleCollisionFilter})
bubble2:setLinearVelocity( 2, 4 )
bubble2:prepare("bubble")
bubble2:play()
--BUBBLE3
local bubble3 = sprite.newSprite( spriteSet1 )
bubble3.x = 100
bubble3.y = 17
physics.addBody(bubble3, {bounce=0.02, filter = bubbleCollisionFilter})
bubble1:setLinearVelocity( 1, 2 )
bubble3:prepare("bubble")
bubble3:play()
--BUBBLE4
local bubble4 = sprite.newSprite( spriteSet1 )
bubble4.x = 310
bubble4.y = 20
physics.addBody(bubble4, {bounce=0.4, filter = bubbleCollisionFilter})
bubble4:setLinearVelocity( 2, 4 )
bubble4:prepare("bubble")
bubble4:play()
The problem is firstly the code doesn't seem to work. Secondly though the bubble changes color on tap (this color is same for most). Yet, each bubble has a unique letter on it. How to get this to work. Please help.
It's hard to know what exactly you're asking because your question is pretty vague (what does "animate" mean? And what do you mean by "doesn't seem to work"? explain these terms because they can mean multiple things) but I think you want to set the physics bodies to "static" in the tap event listener. Refer here for what I'm talking about:
http://developer.anscamobile.com/reference/index/bodybodytype
So inside the selectBubble() function you would type something like tapped.bodyType="static"