I want to use a slider in R Shiny to give the user control over the frequency a category is sampled from a data frame. The slider should have a default value of 0.5 (and range from 0 to 1), and at the default value (0.5), I have defined the frequency by which each category should be sampled. When the user adjusts the slider towards 1 (the maximum), I would like the frequencies of the highest categories to become even higher at the expense of the lowest frequency categories and vice-versa when the slider is adjusted towards 0 (the lowest frequency categories should increase, while the highest decrease). The frequencies should always sum to 1.
For example, I have a data frame that contains six categories and the frequencies by which each category is initially sampled. For instance:
df <- data.frame(food = c("fish", "shrimp", "chicken", "lamb", "beef", "tofu"), frequency = c(0.20, 0.06, 0.30, 0.10, 0.23, 0.11))
When the R Shiny slider is set to 1, I want the frequency of the initial highest category (chicken) to be 1.0, with the other categories being 0. As the slider goes to 1, I also want the next highest categories (beef and fish) to increase, but they should maintain the initial frequency order (with chicken remaining highest) until (as the slider gets closer to 1) they also go to 0 and chicken goes to 1.0. The highest categories (chicken, beef, and fish) should grow at the expense of the lowest categories (tofu, lamb, and shrimp), with shrimp (the lowest frequency) being the first to go to 0, followed by lamb and tofu.
I would like a similar (but opposite) process to occur as the slider goes to 0, with shrimp eventually being at a frequency of 1 (and lamb and tofu initially increasing at the expense of the higher frequency categories) and chicken being the first to go to 0 (followed by beef, fish, tofu, and lamb).
Essentially I need to rework the sample_data function in the example below:
library(shiny)
sample_data <- function(slider_value, data) {
adjusted_frequency <- data$frequency + (slider_value) * (max(data$frequency) - data$frequency)
data$sampled_frequency <- adjusted_frequency / sum(adjusted_frequency)
return(data)
}
ui <- fluidPage(
titlePanel("Input Data Using a Slider"),
sidebarLayout(
sidebarPanel(
sliderInput("value", "Enter a value:",
min = 0, max = 1, value = 0.5)
),
mainPanel(
tableOutput("data")
)
)
)
server <- function(input, output) {
df <- data.frame(food = c("fish", "shrimp", "chicken", "lamb", "beef", "tofu"), frequency = c(0.20, 0.06, 0.30, 0.10, 0.23, 0.11))
data <- reactive({
sample_data(input$value, df)
})
output$data <- renderTable({
data()
})
}
shinyApp(ui, server)
Right now, the slider I have gives the results as depicted in the image below:
When set to 0, it displays the default frequencies, and when set to 1 it has all categories at equal frequencies. How can I improve the sample_data function to accomplish the more complicated procedure I have described?
Thank you very much for your help!
need help pls.
In Tradingview I use "Compare" to see the BTCUSDT vs. ETHUSDT on Binance and it's basically OK. But lines on the chart are too "up & down" and I want to see the SMA or EMA for those tickers.
I'm trying to do it step by step but I can't pass through the issue that my code takes only last calculated value in consideration and "percentage change line" starts from 0 with each new data. So it makes no sence. Meaning, my last data doesn't add upon prior value, but always starts from zero.
So, data (value) that comes out is good (same as when I put same tickers on Tradingview "Compare") but Tradingview "Compare" calculates / adds data on historical data, while my code starts from 0.
Here is the Pine script code:
//#version=4
study(title="Compare", shorttitle="Compare", overlay=false, max_bars_back=0)
perc_change = (((close[0] - open[0]) / open [0]) * 100)
sym1 = "BINANCE:BTCUSDT", res1 = "30", source1 = perc_change
plot(security(sym1, res1, source1), color=color.orange, linewidth=2)
sym2 = "BINANCE:ETHUSDT", res2 = "30", source2 = perc_change
plot(security(sym2, res2, source2), color=color.blue, linewidth=2)
Sounds like the delta between the two ROCs is what you are looking for. With this you can show only the 2 ROCs, but also columns representing the delta between the two. you can also change the ROC's period:
//#version=4
study(title="Compare", shorttitle="Compare")
rocPeriod = input(1, minval = 1)
showLines = input(true)
showDelta = input(true)
perc_change = roc(close, rocPeriod)
sym1 = "BINANCE:BTCUSDT"
sym2 = "BINANCE:ETHUSDT"
res = "30"
s1 = security(sym1, res, perc_change)
s2 = security(sym2, res, perc_change)
delta = s1 - s2
plot(showLines ? s1 : na, "s1", color.orange)
plot(showLines ? s2 : na, "s2", color.blue)
hline(0)
plot(showDelta ? delta : na, "delta", delta > 0 ? color.lime : color.red, 1, plot.style_columns)
I am using dygraphs for R and I opened the following issue on GitHub the other day, however, I have not yet received an answer. Therefore, I am hoping someone in here will be able to answer my question.
I want to know if it is possible to show all the values of the prediction interval in the legend, i.e. , lower, actual, upper, without having them as three separate plain dySeries? I like the look of the shading that the upper/lower bars bring, but I would also like to be able to hover over a point and see all the values for that particular point, not just the middle one. If such a function does not exists, is there an easy workaround, maybe with fillGraph = TRUE or something?
library(dygraphs)
hw <- HoltWinters(ldeaths)
p <- predict(hw, n.ahead = 72, prediction.interval = TRUE)
dygraph(p, main = "Predicted Lung Deaths (UK)") %>%
dySeries(c("lwr", "fit", "upr"), label = "Deaths")
The preceding code is the example from the web page, which is similar to my problem. I simply want to see the lwr and upr values in the legend when hovering.
So I found a workaround for anybody looking for something similar.
library(dygraphs)
hw <- HoltWinters(ldeaths)
p <- predict(hw, n.ahead = 72, prediction.interval = TRUE)
max <- p[,2]
min <- p[,3]
p <- ts.union(p, max, min)
dygraph(p, main = "Predicted Lung Deaths (UK)") %>%
dySeries(c("p.lwr", "p.fit", "p.upr"), label = "Deaths") %>%
dySeries("max", label = "Max", pointSize = 0.01, strokeWidth = 0.001) %>%
dySeries("min", label = "Max", pointSize = 0.01, strokeWidth = 0.001)
Obviously, this can be modified to suit your needs (e.g. color of the points etc.) The main idea in this method is simply to create two new columns containing the same information that is used in the bands, and then to make the lines to these too small to see.
I am trying to figure out the alignment of Markers in "ax.plot" . Apart from plotting 2 bar graphs, I also need to plot 2 points, one per bar graph.
Here's what I am looking for -:
Centering/alignment of markers ('o' and '' here, in the center of each bar, rather than at the edge of the bar graph. "o" should come at the center of the 1st bar graph and "" should come at the center of the 2nd bar graph, their individual heights will differ though, as on the scale "Performance" -the "o" and "" are "Performance" objects (right hand side scale, as in the figure) - centering, thus means, overlay of the markers("o" and "" against its respective stacked graph.
Removing the duplicate marker symbols, with 'o' and '*' in the legend on the upper right corner. And, understanding why that happens for par2.plot , but not for ax.bar object. Could I have done this without using ax.twinx(), which generates two scales (one for "#candidates" and other for "Performance" - and if this double entry of legend is related to using the 2 scales ? (I hope not)
For (2), I also used plt.legend(numpoints=1) just before the last line, plt,show() according to the answer here, multiple markers in legend , but that didn't seem to remove the "duplicate markers" in this context.
Also attached is the graph, with (1) and (2) highlighted
Tip -: Ignore the looping constructs, they are a part of the larger piece, and did not want to change that while pasting, focus on this snippet of the entire code (IMO, this should narrow the problem?)
rects1 = ax.bar(ind, Current_Period, width, color=colors)
rects2 = ax.bar(ind+width, Next_Period, width, color='c')
lines_1=par1.plot(perform_1,linestyle='', marker='H', markerfacecolor ='k')
lines_2=par1.plot(perform_2,linestyle='', marker='*',markerfacecolor ='m')
ax.legend((rects1[0], rects2[0],lines_1[0],lines_2[0]), ('Current time period', 'Next time Period','Current Period Performance', 'Next Period Performance'),prop=dict(size=10) )
Here is the complete code that I used -:
#Final plotting file
import numpy as np
import matplotlib.pyplot as plt
from matplotlib import rc
#placing anchored text within the figure
from mpl_toolkits.axes_grid.anchored_artists import AnchoredText
rc('mathtext', default='regular')
history_P=[[1.4155322812819471, 4.9723842851306213, 3.6831354714462456, 3.0345047089322521, 5.3355879766963819], [2.3240101637275856, 4.7804345245879354, 7.0829471987293973, 6.1050663075245852, 3.6087166298399973], [3.5770722538162265, 3.4516290562530587, 4.4851829512197678, 5.1158026103364733, 3.7873662329909235], [4.7137003352158136, 5.0792119756378593, 4.4624078437179504, 3.1790266221827754, 4.8711126648436895], [4.8043291762010414, 5.6979872315568576, 3.4869780377350339, 3.892755123606721, 3.8142509389863095], [4.8072846135271492, 4.2055137431209033, 5.0441056822018417, 4.1014759291893306, 5.327936039526822]]
history_C=[[14000, 14000, 14000, 14000, 14000], [5373, 18874, 13981, 11519, 20253], [6806, 14001, 20744, 17880, 10569], [12264, 11834, 15377, 17540, 12985], [14793, 15940, 14004, 9977, 15286], [15500, 18384, 11250, 12559, 12307]]
N = 5
ind = np.arange(N) # the x locations for the groups
width = 0.35
def make_patch_spines_invisible(ax):
ax.set_frame_on(True)
ax.patch.set_visible(False)
for sp in ax.spines.itervalues():
sp.set_visible(False)
def autolabel(rects):
# attach some text labels
for rect in rects:
height = rect.get_height()
ax.text(rect.get_x()+rect.get_width()/2., 1.05*height, '%d'%int(height),ha='center', va='bottom')
alphab = ['M1', 'M2', 'M3', 'M4', 'M5', 'M6']
for k in range(0,5):
colors=[]
Current_Period=history_C[k]
Next_Period = history_C[k+1]
perform_1=history_P[k]
perform_2=history_P[k+1]
for i in range(0,5):
if perform_1[i]==max(perform_1) :
colors.append('g')
best=i
elif perform_1[i]==min(perform_1):
colors.append('r')
worst=i
elif (perform_1[i] != min(perform_1) or perform_1[i] != max(perform_1)):
colors.append('b')
fig, ax = plt.subplots()
fig.subplots_adjust(right=0.75)
par1 = ax.twinx()
make_patch_spines_invisible(par1)
rects1 = ax.bar(ind, Current_Period, width, color=colors)
rects2 = ax.bar(ind+width, Next_Period, width, color='c')
lines_1=par1.plot(perform_1,linestyle='', marker='H', markerfacecolor ='k')
lines_2=par1.plot(perform_2,linestyle='', marker='*',markerfacecolor ='m')
ax.set_xlabel("Model #",style='italic',size='large')
ax.set_ylabel("Candidate #",style='italic',size='large')
par1.set_ylabel("Performance",style='italic',size='large')
ax.set_title('Aggregated Performace Rolled out to candidates, per period',style='italic')
#fontdict=dict('fontsize':rcParams['axes.titlesize'],'verticalalignment': 'baseline', 'horizontalalignment': loc)
ax.set_xticks(ind+width)
ax.set_xticklabels( ('M1', 'M2', 'M3', 'M4', 'M5') )
ax.annotate('Worst Performer', xy=(worst,0), xycoords='data',xytext=(-30, 30), textcoords='offset points',size=12, va="center", ha="center",arrowprops=dict(arrowstyle="simple", connectionstyle="arc3,rad=-0.2"))
ax.annotate('Best Performer', xy=(best,0), xycoords='data',xytext=(-30, 30), textcoords='offset points',size=12, va="center", ha="center",arrowprops=dict(arrowstyle="simple", connectionstyle="arc3,rad=-0.2"))
ax.legend((rects1[0], rects2[0],lines_1[0],lines_2[0]), ('Current time period', 'Next time Period','Current Period Performance', 'Next Period Performance'),prop=dict(size=10) )
#placing anchored text within the figure, per Period
at = AnchoredText("Time Period :"+str(k+1),prop=dict(size=10), frameon=True,loc=2,)
at.patch.set_boxstyle("round,pad=0.,rounding_size=0.2")
ax.add_artist(at)
par1.set_ylim(0, 10)
autolabel(rects1)
autolabel(rects2)
plt.show()
You have to provide the plot method with x-coordinate arguments. If given only one list-like object, matplotlib will use this list as the y-coordinates and use x = np.arange(len(y)) (where y are the given y-coordinates).
You should not call the legend method several times for each Axes; include the numpoints kwarg in your original legend call.
In other words, replace the lines
lines_1=par1.plot(perform_1,linestyle='', marker='H', markerfacecolor ='k')
lines_2=par1.plot(perform_2,linestyle='', marker='*',markerfacecolor ='m')
ax.legend((rects1[0], rects2[0],lines_1[0],lines_2[0]), ('Current time period', 'Next time Period','Current Period Performance', 'Next Period Performance'),prop=dict(size=10) )
with
lines_1=par1.plot(ind + 0.5*width, perform_1,linestyle='', marker='H', markerfacecolor ='k')
lines_2=par1.plot(ind + 1.5*width, perform_2,linestyle='', marker='*',markerfacecolor ='m')
ax.legend((rects1[0], rects2[0],lines_1[0],lines_2[0]), ('Current time period', 'Next time Period','Current Period Performance', 'Next Period Performance'),prop=dict(size=10), numpoints=1 )
This gives the desire output:
I think it is slightly better style to use bar(..., align='center'), as that is what you really want here:
rects1 = ax.bar(ind, Current_Period, width, color=colors, align='center')
rects2 = ax.bar(ind+width, Next_Period, width, color='c', align='center')
lines_1=par1.plot(ind, perform_1,linestyle='', marker='H', markerfacecolor ='k')
lines_2=par1.plot(ind+width, perform_2,linestyle='', marker='*',markerfacecolor ='m')
ax.set_xticks(ind + width/2)
ax.set_xticklabels( ('M1', 'M2', 'M3', 'M4', 'M5') )
ax.legend((rects1[0], rects2[0],lines_1[0],lines_2[0]), ('Current time period', 'Next time Period','Current Period Performance', 'Next Period Performance'),prop=dict(size=10), numpoints=1 )
From a philosophical point of view, it it better to tell the plotting library to do what you want, than to contort your self (and inject details of how the plotting library does things internally) to accommodate the fact that you only are using part of the api.