So I have read that using global is a bad practice. Earlier I did this entire program using just functions now I want to use classes inside the function. These are two of the functions inside the class. I am getting a function object has no attribute amountentry Error.
def addmoneyindb(self,amountentry):
#global accno
moneyentry_ip = amountentry.get()
query = "select balance from bankui where accountno ="+accno_log+""
cur.execute(query)
queryy = cur.fetchone()
amt = int(queryy[0])+int(moneyentry_ip)
amt = str(amt)
print amt
query1 = "update bankui set balance='"+amt+"' where accountno ="+accno_log+""
cur.execute(query1)
tkMessageBox.showinfo("Sucess", "Money Added Sucessfully")
db.commit()
def addmoney(self):
# global amountentry
Screen2 = Toplevel()
Screen2.title("Add Money")
Screen2.geometry("1366x768")
Screen2.configure(background = "light cyan")
Label(Screen2,text = "ADD MONEY" , height = 3, width = 155, fg = "black" , bg = "RoyalBlue" , font = ("Arial",20)).pack()
Label(Screen2,text = "" , height = 2, width = 10, fg = "black" , bg = "light cyan").pack()
Label(Screen2,text = "Enter Amount:" , height = 1, width = 20, fg = "black" , bg = "RoyalBlue" , font = ("Arial",12)).pack()
Label(Screen2,text = "" , height = 2, width = 10, fg = "black" , bg = "light cyan").pack()
amountentry = Entry(Screen2)
amountentry.pack()
Label(Screen2,text = "" , height = 2, width = 10, fg = "black" , bg = "light cyan").pack()
Button(Screen2 , text = "Submit", height =4 , width =20, fg = "black" , bg = "RoyalBlue" , command = self.addmoneyindb.amountentry.get(), font = ("Arial",12)).pack()
Label(Screen2,text = "" , height = 2, width = 10, fg = "black" , bg = "light cyan").pack()
Label(Screen2,text = "" , height = 1, width = 10, fg = "black" , bg = "light cyan").pack()
Button(Screen2 , text = "Exit", height =4 , width =20, fg = "black" , bg = "RoyalBlue" , command = Screen2.destroy , font = ("Arial",12)).pack()
Label(Screen2,text = "" , height = 1, width = 10, fg = "black" , bg = "light cyan").pack()
Screen2.mainloop()
You need to add self to the variables you want to access through other methods of the same class. Also your Button command won't work - i have modified it to print the result of self.amountentry instead.
def addmoneyindb(self): #don't need the amountentry arg
moneyentry_ip = self.amountentry.get()
...
def addmoney(self):
...
self.amountentry = Entry(Screen2)
self.amountentry.pack()
...
Button(Screen2, text="Submit", height=4, width=20, fg="black", bg="RoyalBlue",
command=lambda: print(self.amountentry.get()), font=("Arial", 12)).pack()
...
Related
sorry if this is repetitive and so simple it is annoying, but I am new to Shiny.
I need help with a shiny app I am trying to create for my golf game. I have loaded a CSV file with previous distance and accuracy observations to Rstudio and completed a script file with what will generally be done: data preprocessing and then visualizations.
I am now struggling with converting that to the app.R file, specifically, how to create a widget where I can add new numeric observations to the current data frame. The end goal is to use the app to log data as I play (practice or an actual round), which updates in real time for quick insight into the average distance and accuracy for each club.
Here is the very basic shiny code I have got to work for the numeric input:
`library(shiny)
# Define UI for application that draws a histogram
ui <- fluidPage(
titlePanel("Numeric Add Test"),
column(3,
numericInput("num",
h3("Numeric input"),
value = 1,
min = 50,
max = 400,
step = 25))
)
# Define server logic required to draw a histogram
server <- function(input, output) {
}
# Run the application
shinyApp(ui = ui, server = server)`
I have found ways to include an 'add' button to a list, but what I am hoping to do is have the new numeric input be added to the specified variable (club, distance, accuracy) in the referenced dataset. This action would change the existing data, but add to it and grow the dataset over time.
Not sure if this helps for context at all, but below is the script file for preprocessing and visuals I described above:
`######### Golf Data Practice for App #############
## Read in Data set and address the column names starting with a number
Golfdata <- data.frame(read_csv("Shiny Apps/Golf Dataset .csv"))
Golfdata <- as.data.frame(Golfdata)
#Drop the last two columns for only clubs. Then create shot bias DF as well.
Clubs <- Golfdata %>% select(-c(11,12))
ShotBias <- Golfdata %>% select(c(11,12))
#Visualize the Average club distance
##Convert the club df by summarizing each variable by its average,
## then use the gather() to convert to long instead of wide to finally
## prepare the df for visualizing.
ClubAverage <- Clubs %>% summarise_all(mean) %>% gather(ClubAverage) %>%
mutate_if(is.numeric, round, digits = 0)
library(ggplot2)
value <- ClubAverage$value
ggplot(ClubAverage) +
aes(x = fct_reorder(ClubAverage, value, .desc = TRUE), y = value, label = value,
color = ClubAverage) +
geom_col( show.legend = FALSE, fill = "white") +
geom_text(nudge_y = 10, color = "black", size=4, fontface = "bold") +
labs(x = "Club",
y = "Yards", title = "Average Club Distance") +
theme(panel.background = element_rect(fill="forestgreen"),
panel.grid.major.x = element_blank(),
panel.grid.major = element_line(color = "yellow"),
panel.grid.minor = element_line(color = "yellow1")) +
theme(plot.title = element_text(size = 24L,
face = "bold", hjust = 0.5), axis.title.y = element_text(size = 18L, face = "bold"), axis.title.x =
element_text(size = 18L,
face = "bold"))
## Visualize the Average Accuracy ##
## This time, summarize the columns by their mean,
## but keep as wide -- no gather() function needed.
AverageShotBias <- ShotBias %>% summarise_all(mean)
ggplot(AverageShotBias) +
aes(x = Accuracy.Bias, y = Distance.Bias) +
geom_point(shape = "circle filled",
size = 18L, fill = "yellow") +
labs(x = "Accuracy", y = "Distance", title = "Average Shot Bias") +
theme(panel.background = element_rect(fill="forestgreen")) +
theme(plot.title = element_text(size = 24L, face = "bold", hjust = 0.5), axis.title.y =
element_text(size = 14L,
face = "bold"), axis.title.x = element_text(size = 14L, face = "bold")) +
xlim(-1, 1) +
ylim(-1, 1) +
geom_hline(yintercept = 0, size=1) +
geom_vline(xintercept = 0, size=1)`
Something I have found regarding the add button is the code here:
` ,actionButton('add','add')
,verbatimTextOutput('list')
)`
This does create an add button, which after updating the server code does create a list of added inputs, however I would like to be able to adjust the code for adding the observation to the variables in the data set.
I assume I would create an add button for each variable, just need to understand better how to do that.
The structure of your data used in the plot is not clear, but this is how to get the inputs or update dataset using eventReactive or observeEvent in the server. you can read this to learn the difference
server <- function(input, output) {
distance <- eventReactive(input$addButton, {
input$distInput
}, ignoreInit = T, ignoreNULL = F)
accbias <- eventReactive(input$accBiasButton, {
input$accslider
})
distbias <- eventReactive(input$DistBiasButton, {
input$distslider
}, ignoreNULL=F)
output$plot1 <- renderPlot({
input$distInput
mydist <- distance()
# plot
})
output$plot2 <- renderPlot({
input$distInput # use the inputs here
mydist <- distance() # or the reactives
})
}
the two output plots in your code have the same outputId
Follow UP to my Question: I have written the code for the ui, now I am still trying to figure out how to code the server properly so the distance and accuracy numeric inputs can be added to a data frame. That data frame will then be used to create the two visuals.
library(shiny)
library(gridlayout)
library(DT)
library(tidyverse)
ui <- grid_page(
layout = c(
"title title title",
"h1 h2 h3 ",
"h4 h4 h5 "
),
row_sizes = c(
"100px",
"0.86fr",
"1.14fr"
),
col_sizes = c(
"250px",
"0.71fr",
"1.29fr"
),
gap_size = "1rem",
grid_card_text(
area = "title",
content = "My Golf Data",
alignment = "center",
is_title = FALSE
),
grid_card(
area = "h2",
title = "Distance Input",
numericInput(
inputId = "distInput",
label = "Distance",
value = 50L,
min = 50L,
max = 400L,
step = 15L
),
actionButton(
inputId = "addButton",
label = "Add",
width = "100%"
)
),
grid_card(
area = "h1",
title = "Club Select",
radioButtons(
inputId = "clubRadiobuttons",
label = "",
choices = list(
Driver = "D",
`5Wood` = "5W",
`4H` = "4H",
`5I` = "5I",
`6I` = "6I",
`7I` = "7I",
`8I` = "8I",
`9I` = "9I",
PW = "PW",
SW = "SW"
),
width = "100%"
)
),
grid_card(
area = "h3",
title = "Accuracy",
sliderInput(
inputId = "accslider",
label = "Accuracy Bias",
min = -1L,
max = 1L,
value = 0L,
width = "98%",
step = 1L
),
actionButton(
inputId = "accBiasButton",
label = "Add Acc Bias",
width = "100%"
),
sliderInput(
inputId = "distslider",
label = "Distance Bias",
min = -1L,
max = 1L,
value = 0L,
width = "100%",
step = 1L
),
actionButton(
inputId = "DistBiasButton",
label = "Add Dist Bias",
width = "100%"
)
),
grid_card(
area = "h5",
title = "Average Club Distance",
plotOutput(
outputId = "plot",
width = "100%",
height = "400px"
)
),
grid_card(
area = "h4",
title = "Accuracy Average",
plotOutput(
outputId = "plot",
width = "100%",
height = "400px"
)
)
)
server <- function(input, output) {
}
shinyApp(ui, server)
I have this sample app to display and download dataTable. But it is also printing HTML script on top of the downloaded attachment. It is printing logo and title HTML but I also want to preserve them on the app.
library(shiny)
library(DT)
ui <- fluidPage(
titlePanel(title = tags$div(img(src = "test.jpg", width = 170, height = 115, align = "left"))),
titlePanel(title = tags$div(class = "header" , tags$p("Cars", tags$br(), tags$h4("MTCARS", style = "text-align: center; color:navy;"), style = "text-align: center; color:navy;"))),
dataTableOutput("table_output")
)
server <- function(input, output, session){
output$table_output <- renderDataTable(server=FALSE,{
DT::datatable(head(mtcars), extensions = c('Buttons'),
options = list(autoWidth = FALSE, dom = 'lfrtipB',
buttons = list(list(extend = "csv", text = "CSV", filename = "cars",
exportOptions = list(modifier = list(page = "all"))),
list(extend = "excel", text = "EXCEL", filename = "cars",
exportOptions = list(modifier = list(page = "all"))),
list(extend = "pdf", text = "PDF", filename = "cars",
exportOptions = list(modifier = list(page = "all")))
))) })
}
shinyApp(ui, server)
I had to change the UI function to get the proper attachment.
ui <- fluidPage(
img(src = "test.jpg", width = 170, height = 115, align = "left"),
tags$div(class = "header" , tags$h2("Cars", tags$br(), tags$h4("MTCARS", style = "text-align: center; color:navy;"), style = "text-align: center; color:navy;")),
dataTableOutput("table_output")
)
output$plot <- renderImage({
outfile <- tempfile(fileext = '.png')
png(outfile, width = 400, height = 300)
venn.diagram(
x = list(
T = T,
I = I
),
main = "Venn Diagram ",
filename =outfile, output=TRUE,
lwd = 2,na = "remove",
fill = c("orange", "blue"),
alpha = c(0.5,0.5),
label.col = "black",
cex=1.5,
fontface = "plain",
cat.col = c("cornflowerblue", "pink"),
cat.cex = 1.5,
cat.fontfamily = "serif",
cat.fontface = "plain",
cat.dist = c(0.05, 0.05),
cat.pos = c(-20, 14),
cat.default.pos = "text",
scaled = FALSE
)
dev.off()
list(src = outfile,
contentType = 'image/png',
width = 400,
height = 300,
alt = "This is alternate text")
}, deleteFile = TRUE)
I was trying plot a venn diagram using this code. But it only displays This is alternate text and not outputting any image on the app, Any Idea ?
Try to create a reactive graph as shown below
output$plot <- renderImage({
vennd <- reactive({venn.diagram(
x = list(
T = T,
I = I
),
main = "Venn Diagram ",
filename =outfile, output=TRUE,
lwd = 2,na = "remove",
fill = c("orange", "blue"),
alpha = c(0.5,0.5),
label.col = "black",
cex=1.5,
fontface = "plain",
cat.col = c("cornflowerblue", "pink"),
cat.cex = 1.5,
cat.fontfamily = "serif",
cat.fontface = "plain",
cat.dist = c(0.05, 0.05),
cat.pos = c(-20, 14),
cat.default.pos = "text",
scaled = FALSE
)
})
outfile <- tempfile(fileext = '.png')
png(outfile, width = 400, height = 300)
vennd()
dev.off()
list(src = outfile,
contentType = 'image/png',
width = 400,
height = 300,
alt = "This is alternate text")
}, deleteFile = TRUE)
output$plot <- renderImage({
vennd <- reactive({venn.diagram(
x = list(
T = T,
I = I
),
main = "",
filename =outfile, output=TRUE,
lwd = 2,na = "remove",imagetype="png",
fill = c("orange", "blue"),
alpha = c(0.5,0.5),
label.col = "black",
cex=1.5,
fontface = "plain",
cat.col = c("cornflowerblue", "pink"),
cat.cex = 1.5,
cat.fontfamily = "serif",
cat.fontface = "plain",
cat.dist = c(0.05, 0.05),
cat.pos = c(-20, 14),
cat.default.pos = "text",
scaled = FALSE
)
})
outfile <- tempfile(fileext = '.png')
png(outfile, width = 500, height = 500,type="cairo")
vennd()
dev.off()
list(src = outfile,
contentType = 'image/png',
width = 500,
height = 500,
alt = "This is alternate text")
}, deleteFile = TRUE)
Need to add imagetype="png" and type="cairo" thank you #YBS
The column bar is too small. And I couldn't adjust their height. The screen shot is attached here: https://prnt.sc/p09hj9.
I have tried all the methods of column series at https://www.amcharts.com/docs/v4/reference/columnseries/.
am4core.ready(function() {
// Create chart instance
var chart = am4core.create("historical_monthly_chart_range", am4charts.XYChart);
// Push data into the charts
var dateAxis = chart.xAxes.push(new am4charts.DateAxis());
var valueAxis = chart.yAxes.push(new am4charts.ValueAxis());
var series = chart.series.push(new am4charts.LineSeries());
series.name = "Price Range";
valueAxis.title.text = 'Price (S$ psf)';
series.dataFields.dateX = "date";
series.dataFields.openValueY = "min";
series.dataFields.valueY = "max";
series.tooltipText = "{date} \n Maximum: {max} \n Average: {average} \n Minimum: {min} \n Volume: {value}";
// Setting the appearance
series.tooltip.background.cornerRadius = 20;
series.tooltip.background.strokeOpacity = 0;
series.tooltip.pointerOrientation = "vertical";
series.tooltip.label.minWidth = 40;
series.tooltip.label.minHeight = 40;
series.tooltip.label.textAlign = "left";
series.tooltip.label.textValign = "middle";
series.fillOpacity = 0.5;
series.tensionX = 0.8;
series.fill = am4core.color("#697e69");
var series2 = chart.series.push(new am4charts.LineSeries());
series2.name = "Minimum Price";
series2.dataFields.dateX = "date";
series2.dataFields.valueY = "min";
series2.stroke = am4core.color("#697e69");
series2.tensionX = 0.8;
var series_average = chart.series.push(new am4charts.LineSeries());
series_average.name = "Average Price";
series_average.dataFields.valueY = "average";
series_average.dataFields.dateX = "date";
series_average.stroke = am4core.color("#000");
/* Bar chart series */
var barSeries = chart.series.push(new am4charts.ColumnSeries());
barSeries.dataFields.valueY = "value";
barSeries.dataFields.dateX = "date";
barSeries.fill = am4core.color("#000");
barSeries.columns.width = am4core.percent(60);
chart.cursor = new am4charts.XYCursor();
chart.cursor.xAxis = dateAxis;
chart.legend = new am4charts.Legend();
});
There is a bounty on this issue from AM charts however one workaround can be using scrollbar in Y axis like this following:
chart.scrollbarY = new am4core.Scrollbar();
This is not the best solution i agree but you can use it to slightly zoom with the buttons and scale and see
let me know if it works!
Someone can help me to resolve this display problem ?
It depends on what layout you are using. If you are using Column based layout for your boxes, then you can set the box(width=NULL). That should fix the issue. From you code it looks like you are using column based layout. width =25 does not make sense. Since, the overall width of the are is 12. So, set it to width = NULL, it will fix the issue.
If you are using row based layout that is when you mess with the width parameters.
ui <- dashboardPage(
skin = "red",
dashboardHeader(title = "TEXT MINING", disable = F),
dashboardSidebar(
tags$style(
"text/css",
".navbar {background-color:bule;}",
"html,body,#map body {width:120%;height:100%}"
),
br(),
br(),
br(),
br(),
tags$head(tags$style(
".wrapper {overflow: visible !important;}"
)),
selectInput("choix", h2("ALL vs PRIO"), c("ALL", "PRIO")),
helpText("ALL= Tout les clients, PRIO= Clients séléctionés(Prioritaires)"),
selectInput("w", h2("Pondération de la matrice "), c("Tf", "TfIdf")),
br(),
br(),
br(),
br(),
helpText("Cliquer pour téléharger la table"),
downloadButton('downloadData', 'Download'),
br(),
br(),
br(),
br(),
br(),
br(),
br(),
br()
),
dashboardBody(mainPanel(tabsetPanel(
navbarPage(
"",
tabPanel("Données", icon = icon("database"), dataTableOutput('donnees')),
tabPanel(
"Analyses exploratoires",
icon = icon("bar-chart"),
box(
title = "Les pages visitées",
status = "warning",
width = 25,
solidHeader = TRUE,
collapsible = TRUE,
plotOutput("pages", height = "650px")
),
box(
title = "Histogramme des notations ",
status = "warning",
width = 25,
solidHeader = TRUE,
collapsible = TRUE,
plotOutput("his", height = "650px")
),
box(
title = "score par nombre d'étoile",
status = "warning",
width = 25,
solidHeader = TRUE,
collapsible = TRUE,
plotOutput("sc", height = "650px")
) ,
box(
title = "Mots fréquents",
status = "warning",
width = 25,
solidHeader = TRUE,
collapsible = TRUE,
plotOutput("mots", height = "650px")
)
),
tabPanel(
"Nuages et assosciations des mots ",
icon = icon("cloud"),
fluidRow(column(12, wellPanel(
sliderInput(
"max",
"Nombre maximal de mots",
min = 100,
max = 300,
value = 200,
step = 10
)
)),
column(
12,
box(
title = "Word Cloud",
status = "warning",
width = 18,
solidHeader = TRUE,
collapsible = TRUE,
plotOutput("nuage", height = "450px")
)
)),
fluidRow(column(12, wellPanel(
sliderInput(
"lowf",
"Choisir n tel que Fréquence(mots)>n",
min = 5,
max = 30,
value = 10,
step = 1
)
)),
column(
12,
box(
title = "Graphe des associations",
status = "warning",
width = 18,
solidHeader = TRUE,
collapsible = T,
plotOutput("asso", height = "650px")
)
))
),
tabPanel("Clustering", icon = icon("sitemap"), fluidRow(column(
12,
box(
title = "K-means",
status = "warning",
width = 30,
solidHeader = TRUE,
collapsible = TRUE,
plotOutput("cl", height = "650px")
)
),
column(
12,
box(
title = "CAH",
status = "warning",
width = 30,
solidHeader = TRUE,
collapsible = TRUE,
plotOutput("cl2", height = "650px")
)
))),
tabPanel(
"Rapport",
icon = icon("book") ,
tags$iframe(style = "height:800px; width:100%; scrolling=yes",
src =
"rapportTextMining.pdf")
)
)
))))