I've been trying to create a plot with many (~1000s) of boxplots using Bokeh (v0.8.1). I noticed that whenever I try to use the bokeh.charts.BoxPlot function I hit an error with plots with more than 6 boxplots.
import numpy as np
from bokeh.charts import BoxPlot
test = {}
for i in range(0,7):
test[str(i)] = np.random.normal(0,1,100)
plot = BoxPlot(test)
show(plot)
Stacktrace:
ipython-input-321-6a3614410bf5> in <module>()
4 for i in range(0,7):
5 test[str(i)] = np.random.normal(0,1,100)
----> 6 plot = BoxPlot(test)
7 show(plot)
/opt/pkg/python27/lib/python2.7/site-packages/bokeh/charts/builder/boxplot_builder.pyc in BoxPlot(values, marker, outliers, xscale, yscale, xgrid, ygrid, **kw)
79 return create_and_build(
80 BoxPlotBuilder, values, marker=marker, outliers=outliers,
---> 81 xscale=xscale, yscale=yscale, xgrid=xgrid, ygrid=ygrid, **kw
82 )
83
/opt/pkg/python27/lib/python2.7/site-packages/bokeh/charts/_builder.pyc in create_and_build(builder_class, values, **kws)
38 chart_kws = { k:v for k,v in kws.items() if k not in builder_props}
39 chart = Chart(**chart_kws)
---> 40 chart.add_builder(builder)
41
42 return chart
/opt/pkg/python27/lib/python2.7/site-packages/bokeh/charts/_chart.pyc in add_builder(self, builder)
113 def add_builder(self, builder):
114 self._builders.append(builder)
--> 115 builder.create(self)
116
117 # Add tools if supposed to
/opt/pkg/python27/lib/python2.7/site-packages/bokeh/charts/_builder.pyc in create(self, chart)
161 def create(self, chart=None):
162 self._adapt_values()
--> 163 self._process_data()
164 self._set_sources()
165 renderers = self._yield_renderers()
/opt/pkg/python27/lib/python2.7/site-packages/bokeh/charts/builder/boxplot_builder.pyc in _process_data(self)
185 out_x.append(level)
186 out_y.append(o)
--> 187 out_color.append(self.palette[i])
188
189 # Store
IndexError: list index out of range
It appears that whatever predefined color list for the BoxPlot function has run out of colors for new boxplots.
Is there a way to either define a new color list (ideally, a cycle that will simply repeat colors if it runs out) or disable coloring entirely?
Cycle colors implementation to repeat colors on bokeh.charts have been added in recent versions (IIRC 0.8). It seems like it's a bug. Stack Overflow is really not the best place for such discussion and to track issues.
I've opened an issue related to the cycle_colors/palette bug on charts that also contains a quick way you can use to bypass the problem. You can see it here. Basically you can explicitly build and pass you own big enough palette. If you'd like to help or provide other feedbacks please use the related GH issue mostly because it's easier for us to track.
Thanks!
Related
I am plotting my benchmark tests with plotly and the results look as expected:
This is just a preliminary view as the rest of the data is still calculated. Yet it's obvious already that the current plotting doesn't make too much sense as there will be by far more plotted data in different segments (10-100,100-1000,1000+). As here the smaller data is just not seen any more (if not zoomed in)
Is there a proper way to set the displayed bars (by definition of groups?)?
There is apparently a solution with Dash (https://community.plotly.com/t/how-can-i-select-multiple-options-to-pick-from-dropdown-as-a-group/60482) which seems to be what I am looking for but it's not an independent HTML-File which can be sent and/or exported.
Alternatively I thought about displaying it in log, but the result is irritating as it doesn't really show what I'd like to display.
This code here works and gives the result shown:
if __name__ == '__main__':
filep="Tests/10k-node-test/"
data=[]
quantities=[]
for p1 in next(os.walk(filep))[1]:
quantities.append(p1)
df = pd.read_csv(filep+p1+'/'+"timing.csv")
for index, row in df.iterrows():
if index>=2:
if index%2==0:
val=row[2]
else:
val=row[2]-val
data.append([p1,row[1],val])
df = pd.DataFrame(data, columns=["Records","Iteration","Insertion Time"])
fig = px.bar(df, x="Records", y="Insertion Time",
hover_data=["Records","Iteration","Insertion Time"], color="Insertion Time",
height=400,
log_y=True)
fig.update_layout(barmode='stack', xaxis={'categoryorder':'total ascending'})
fig.write_html("plotlye.html")
The data-frame looks like this:
Records Iteration Insertion Time
0 250 3 1.137531
1 250 4 1.137239
2 250 5 1.146533
3 250 6 1.131248
4 250 7 1.123308
.. ... ... ...
189 10 95 0.123577
190 10 96 0.131645
191 10 97 0.122587
192 10 98 0.124850
193 10 99 0.126864
I am not tied to plotly, but so far it returned what I desired - just the fine-tuning is not really what I'm lacking off. If there are alternatives I'd be open to that too, it should just convey my benchmarking-results in a proper way.
I am brand new at using R/Rattle and am having difficulty understanding how to interpret the last line of this code output. Here is the function call along with it's output:
> head(weatherRF$model$predicted, 10)
336 342 94 304 227 173 265 44 230 245
No No No No No No No No No No
Levels: No Yes
This code is implementing a weather data set in which we are trying to get predictions for "RainTomorrow". I understand that this function calls for the predictions for the first 10 observations of the data set. What I do NOT understand is what the last line ("Levels: No Yes") means in the output.
It's called a factor variable.
That is the list of permitted values of the factor, here the values No and Yes are permitted.
Big picture explanation is I am trying to do a sliding window analysis on environmental data in R. I have PAR (photosynthetically active radiation) data for a select number of sequential dates (pre-determined based off other biological factors) for two years (2014 and 2015) with one value of PAR per day. See below the few first lines of the data frame (data frame name is "rollingpar").
par14 par15
1356.3242 1306.7725
NaN 1232.5637
1349.3519 505.4832
NaN 1350.4282
1344.9306 1344.6508
NaN 1277.9051
989.5620 NaN
I would like to create a loop (or any other way possible) to subset the data frame (both columns!) into two week windows (14 rows) from start to finish sliding from one window to the next by a week (7 rows). So the first window would include rows 1 to 14 and the second window would include rows 8 to 21 and so forth. After subsetting, the data needs to be flipped in structure (currently using the melt function in the reshape2 package) so that the values of the PAR data are in one column and the variable of par14 or par15 is in the other column. Then I need to get rid of the NaN data and finally perform a wilcox rank sum test on each window comparing PAR by the variable year (par14 or par15). Below is the code I wrote to prove the concept of what I wanted and for the first subsetted window it gives me exactly what I want.
library(reshape2)
par.sub=rollingpar[1:14, ]
par.sub=melt(par.sub)
par.sub=na.omit(par.sub)
par.sub$variable=as.factor(par.sub$variable)
wilcox.test(value~variable, par.sub)
#when melt flips a data frame the columns become value and variable...
#for this case value holds the PAR data and variable holds the year
#information
When I tried to write a for loop to iterate the process through the whole data frame (total rows = 139) I got errors every which way I ran it. Additionally, this loop doesn't even take into account the sliding by one week aspect. I figured if I could just figure out how to get windows and run analysis via a loop first then I could try to parse through the sliding part. Basically I realize that what I explained I wanted and what I wrote this for loop to do are slightly different. The code below is sliding row by row or on a one day basis. I would greatly appreciate if the solution encompassed the sliding by a week aspect. I am fairly new to R and do not have extensive experience with for loops so I feel like there is probably an easy fix to make this work.
wilcoxvalues=data.frame(p.values=numeric(0))
Upar=rollingpar$par14
for (i in 1:length(Upar)){
par.sub=rollingpar[[i]:[i]+13, ]
par.sub=melt(par.sub)
par.sub=na.omit(par.sub)
par.sub$variable=as.factor(par.sub$variable)
save.sub=wilcox.test(value~variable, par.sub)
for (j in 1:length(save.sub)){
wilcoxvalues$p.value[j]=save.sub$p.value
}
}
If anyone has a much better way to do this through a different package or function that I am unaware of I would love to be enlightened. I did try roll apply but ran into problems with finding a way to apply it to an entire data frame and not just one column. I have searched for assistance from the many other questions regarding subsetting, for loops, and rolling analysis, but can't quite seem to find exactly what I need. Any help would be appreciated to a frustrated grad student :) and if I did not provide enough information please let me know.
Consider an lapply using a sequence of every 7 values through 365 days of year (last day not included to avoid single day in last grouping), all to return a dataframe list of Wilcox test p-values with Week indicator. Then later row bind each list item into final, single dataframe:
library(reshape2)
slidingWindow <- seq(1,364,by=7)
slidingWindow
# [1] 1 8 15 22 29 36 43 50 57 64 71 78 85 92 99 106 113 120 127
# [20] 134 141 148 155 162 169 176 183 190 197 204 211 218 225 232 239 246 253 260
# [39] 267 274 281 288 295 302 309 316 323 330 337 344 351 358
# LIST OF WILCOX P VALUES DFs FOR EACH SLIDING WINDOW (TWO-WEEK PERIODS)
wilcoxvalues <- lapply(slidingWindow, function(i) {
par.sub=rollingpar[i:(i+13), ]
par.sub=melt(par.sub)
par.sub=na.omit(par.sub)
par.sub$variable=as.factor(par.sub$variable)
data.frame(week=paste0("Week: ", i%/%7+1, "-", i%/%7+2),
p.values=wilcox.test(value~variable, par.sub)$p.value)
})
# SINGLE DF OF ALL P-VALUES
wilcoxdf <- do.call(rbind, wilcoxvalues)
I am trying to draw a boxplot in R:
I have a dataset with 70 attributes:
The format is
patient number medical_speciality number_of_procedures
111 Ortho 21
232 Emergency 16
878 Pediatrics 20
981 OBGYN 31
232 Care of Elderly 15
211 Ortho 32
238 Care of Elderly 11
219 Care of Elderly 6
189 Emergency 67
323 Emergency 23
189 Pediatrics 1
289 Ortho 34
I have been trying to get a subset to only include emergency, pediatrics in a boxplot (there are 10000+ datapoints in reality)
I thought that I could just do this:
newdata<-subset(olddata[ms$medical_specialty=='emergency'|olddata$medical_specialty=='pediatrics',])
plot(newdata)
Since if I do a summary of newdata, all it has is the pediatrics and emergency results. But when it comes to plotting it still includes the ortho, OBGYN, care of elderly in the x axis with no boxplot.
I presume that there is a way to do this in ggplot by doing
ggplot(newdata, aes(x=medical_speciality, y=num_of_procedures, fill=cond)) + geom_boxplot()
but this gives me the error:
Don't know how to automatically pick scale for object of type data.frame.
Defaulting to continuous
Error: Aesthetics must either be length one, or the same length as the dataProblems:cond
Can someone help me out?
I believe your problem comes from the fact that the column medical_speciality is a factor.
So, even though you subset your data the right way, you still get all the levels (including "Ortho", "OBGYN", etc...).
You can get rid of them by using the function droplevels:
newdata<-subset(olddata[ms$medical_specialty=='emergency'|olddata$medical_specialty=='pediatrics',])
newdata <- droplevels(newdata) ## THIS IS THE NEW ADDITION
plot(newdata)
Does this help?
I'm trying to build quite a complex loop in R.
I have a set of data set as an object called p_int (p_int is peak intensity).
For this example the structure of p_int i.e. str(p_int) is:
num [1:1599]
The size of p_int can vary i.e. [1:688], [1:1200] etc.
What I'm trying to do with p_int is to construct a complex loop to extract the monoisotopic peaks, these are peaks with certain characteristics which will be extracted into a second object: mono_iso:
search for the first eight sets of data results in p_int. Of these eight, find the set of data with the greatest score (this score also needs to be above 50).
Once this result has been found, record it into mono_iso.
The loop will then fix on to this position of where this result is located within the large dataset. From this position it will then skip the next result along the dataset before doing the same for the next set of 8 results.
So something similar to this:
16 Results: 100 120 90 66 220 90 70 30 70 100 54 85 310 200 33 41
** So, to begin with, the loop would take the first 8 results:
100 120 90 66 220 90 70 30
**It would then decide which peak is the greatest:
220
**It would determine whether 220 was greater than 50
IF YES: It would record 220 into "mono_iso"
IF NO: It would move on to the next set of 8 results
**220 is greater than 50... so records into mono_iso
The loop would then place it's position at 220 it would then skip the "90" and begin the same thing again for the next set of 8 results beginning at the next data result in line: in this case at the 70:
70 30 70 100 54 85 310 200
It would then record the "310" value (highest value) and do the same thing again etc etc until the end of the set of data.
Hope this makes perfect sense. If anyone could possibly help me out into making such a loop work with R-script, I'd very much appreciate it.
Use this:
mono_iso <- aggregate(p_int, by=list(group=((seq_along(p_int)-1)%/%8)+1), function(x)ifelse(max(x)>50,max(x),NA))$x
This will put NA for groups such that max(...)<=50. If you want to filter those out, use this:
mono_iso <- mono_iso[!is.na(mono_iso)]