I'm trying to add an axis to a Bokeh plot in Python, with ticks at locations specified and labels as specified.
The plot I am making is a collection of daily data, but I am not using x_axis_type="datetime" because I do not want to assign a specific year to the data. That is, I am plotting data for the years 1950-2015 but I want the axis to say only "1 January", not "1-January-2000".
Originally I was using a CategoricalAxis, but this crowds out the labels because it places one for each of 366 ticks. I would like to reduce this to around 12 ticks to show each month.
I am able to use a LinearAxis to place the ticks in the location that I want, which is the first date of each month. However the tick labels are numeric and I would like to use string labels instead.
How can I change the tick labels to use a specific string?
# Remove default axis
p.xaxis.visible = False
# Add custom axis
ticker = FixedTicker()
ticker.ticks = first_day_of_month
xaxis = LinearAxis(ticker=ticker)
p.add_layout(xaxis, 'below')
1st attempt using standard CategoricalAxis, the x-axis is crowded:
2nd attempt using code as posted, I want to change the numbers to labels:
EDIT
The DatetimeTickFormatter was not immediately useful because the source format for the data was not a proper date. The x data is actually strings in the form "mmdd", eg "1230", which is why I was using CategoricalAxis in the first place.
Using FuncTickFormatter has been successful, if a little cumbersome. I'm using the code below which gives basically what I want.
CustomFuncTickFormatter = FuncTickFormatter(code = '''
return {0: 'January', 366: '', 335: 'December', 305: 'November', 274: 'October', 244: 'September', 213: 'August', 182: 'July', 152: 'June', 121: 'May', 91: 'April', 60: 'March', 31: 'February'}
[tick]
''')
You should be able to use x_axis_type="datetime", FixedTicker and a custom instance of DatetimeTickFormatter (documentation) with all fields set to [%d %m]. If that doesn't work for some reason, you can always use FuncTickFormatter (documentation).
Related
I have tried to find a way to plot a graph where the x-axis wraps at a specified position and then continues at 0 to the right of the max value.
I am attaching an example where the x-axis wraps at 720, e.g. 720 == 0.
It does not matter which tool to use as long it is easy to install on Linux (Ubuntu)
I am trying to assign a x-label column to my data serie where the x axis is in column B and data in column D and x-labels in column C.
but that does not work for me, e.g. the x-axis in above example spans from 685 to 735 instead of 685 to 720 then to 15
So using line diagram instead of scatter as #pnuts did solved my problem.
Instead of x values for the x-axis apply the remainder after x has been divided by 720:
In GNUPLOT, I would like to plot 5 values on a single bar chart, separated with some spacing in between. If I have data formatted as such:
3342336, 3375103, 7110653, 32770, 0
where those 5 values are the y-values, how can I specify the x-values myself for where they should belong?
For example, I would like my bar chart to have each entry be of length 1,
so I plot y-value 3342336 at x-value 1,
y-value 3375103 at x-value 3,
y-value 7110653 at x-value 5,
y-value 32770 at x-value 7,
and y-value 0 at x-value 9.
I would appreciate any example code that can achieve this. Thanks.
If your data is in one row as shown, you can achieve this by using the plot for syntax looping over the column index, and calculating the x value from that index. We can grab the column by using the column function which retrieves the specified column number.
set boxwidth 1
set datafile separator comma # only if data is comma separated
plot for [i=1:5] (2*i-1):(column(i)) with boxes
If we need to ensure the same line type is used each time, we can explicitly state it in the plot command.
plot for [i=1:5] (2*i-1):(column(i)) with boxes lt 1
Additionally, if a key is to be generated, and we don't wish each plot statement to generate one, we can test for and only give a nonempty title on the first iteration (an empty title is treated the same as no title).
plot for [i=1:5] (2*i-1):(column(i)) with boxes lt 1 title (i==1)?"Title":""
If your data is separated into rows as is the normal format, this can be obtained a different way.
Gnuplot has several pseuduocolumns (see help pseudocolumns for details). In your case, column 0 is of interest. Column 0 gives the line number of the data starting at 0. Thus to get sequential odd numbers like that, you can use 2*$0+1.
For example, if your data (stored in datafile.txt) looks like
3342336
3375103
7110653
32770
0
and you wish to plot boxes of length 1 at those values, you can do
set boxwidth 1
plot "datafile.txt" u (2*$0+1):1 with boxes
This is my graph:
What I need is to display just the 0 and 1 in the y-axis without 0.1 ,0.2, .., 0.9
Graph tag
The default type of the graph is a pie chart - to change it to a barchart change to You also may change the orientation.
:Example :
<graph string="Sales Order Lines" orientation="horizontal" type="bar">
Field tag
The first field is the X axis. The second one is the Y axis and the optional third one is the Z axis for 3 dimensional graphs. You can apply a few attributes to each field/axis:
group: if set to true, the client will group all item of the same value for this field. For each other field, it will apply an operator
operator: the operator to apply is another field is grouped. By default it's '+'.
Allowed values are:
+: addition
*: multiply
**: exponent
min: minimum of the list
max: maximum of the list
(I hope you get the meaning of what I write, english isn't my mother tongue.)
I have trouble creating a heat map showing air humidity using a txt file.
My data looks like this:
26.02.13 10:30:00 MEZ 31.79688 31.0625 32.875 31.8125 31.46875 30.9375 39.0 36.71875 36.1875
26.02.13 10:45:00 MEZ 31.875 31.10938 32.75 31.8125 31.46875 30.9375 39.0 36.71875 36.1875
26.02.13 11:00:00 MEZ 31.82813 31.15625 32.84375 31.8125 31.48438 30.9375 39.0 36.71875 36.1875
...
Its not a matrix, it's:
date1, time1, timezone, value1-room1, value1-room2, value1-room3,...
date2, time2, timezone, value2-room1, value2-room2, value2-room3,...
I inserted a blank line each 96 values to "seperate" the days from each other
this is what my code, so far, looks like(i left out labels etc.):
reset
set cbrange [0:100]
set palette defined (0 '#0000BB',0.091 '#0055FF',0.182 '#44BBEE',0.2728 '#DDFFDD',0.273 '#DDFFBB',0.45 '#DDFF44',0.5 '#FFFF00',0.55 '#FFF600',0.61 '#FFEE00',0.66 '#FFDD00',0.727 '#FFBD00',0.7272 '#FFBB00',0.86 '#FA2200',0.92 '#EA0000',1.0 '#880000')
set cblabel "Humidity"
set cbtics 0,20,100
set timefmt '"%d.%m.%y %H:%M:%S"'
set format x '"%d.%m.%y"'
set xrange ['"26.02.13"':'"27.03.13"']
set format y '"%H:%M:%S"'
set xrange ['"00:00:00"':'"23:59:59"']
plot "data.txt" using 1:2:4
My intention was to create a heat map for room 1. If that works I want to create heat maps for the other rooms, but first things first :-)
**the problems i can't solve are:
"Skipping unreadable file "data.txt""
and
"Can't plot with an empty x range"**
why is my file unreadable? its in ANSI, the blank lines should tell gnuplot where to start over again
why is the x range empty? did i specify it wrong?
all files are located in the "bin" directory of gnuplot, the "data.txt" has a length of ca. 2000 lines, my gnuplot version is 4.6
thanks in advance
Johannes
Plotting time data in gnuplot is tricky, but there are a few things to remember:
You should set xdata time somewhere in your script to tell gnuplot that you are working with time.
When it comes to time specifiers, be very careful how your time columns are delimited. If your data file does not have quote characters you do not need them in your specifier.
If your time data spans multiple columns and you say so in your format specifier, gnuplot will figure it out. You only have to specify the column where the time data starts (column 1 in your case).
Here is a script that works for me:
#!/usr/bin/env gnuplot
reset
set terminal pngcairo enhanced color rounded dashed size 800,500
set output 'test.png'
set cbrange [0:100]
set palette defined (0 '#0000BB',0.091 '#0055FF',0.182 '#44BBEE',0.2728 '#DDFFDD',0.273 '#DDFFBB',0.45 '#DDFF44',0.5 '#FFFF00',0.55 '#FFF600',0.61 '#FFEE00',0.66 '#FFDD00',0.727 '#FFBD00',0.7272 '#FFBB00',0.86 '#FA2200',0.92 '#EA0000',1.0 '#880000')
set cblabel "Humidity"
set cbtics 0,20,100
# need these three lines for time data
set xdata time
set timefmt '%d.%m.%y %H:%M:%S' # no quotes in specifier weil sie sind nicht im file
set format x '%d.%m.%y' # no extra quotes here, otherwise they appear in the output
set xrange ['26.02.13':'27.03.13']
# removed y formatting - not sure what you intended there
plot "data.dat" using 1:4 title 'Room 1'
Which makes the following output:
Turning this into a heatmap is another question entirely..
Is there a way to get quantmod to draw a square line chart?
I've tried modifying my time series so that each data point is replicated one second before the next datapoint (hoping this would approximate a square line), but quantmod seems to data on the x axis sequentially & evenly spaces without regard to the actually values of x (i.e. the horizontal space between one point an the next is the same whether the delta-T is 1 second or 1 minute).
I suppose I could convert my timeseries from a sparse to a dense one (one entry per second instead of one entry per change in value), but this seems very kludgy and should be unnecessary.
I'm constructing my time series thus:
library(quantmod)
myNumericVector <- c(3,7,2,9,4)
myDateTimeStrings <- paste("2011-10-31", c("5:26:00", "5:26:10", "5:26:40", "5:26:50", "5:27:00"))
myXts <- xts(myNumericVector, order.by=as.POSIXct(myDateTimeStrings))
And drawing the chart like so:
chartSeries(myXts, type="line", show.grid="true", theme=chartTheme("black"))
To illustrate what I have vs. what I want, the result looks like the blue line below but I'd like something more like the green:
Also, for the curious, here is the code that replicates points in the time series such that the gap between one value and the next are as small as possible:
mySquareDateTimes <- rep(as.POSIXct(myDateTimeStrings),2)[-1]
mySquareDateTimes[seq(2,8,by=2)] <- mySquareDateTimes[seq(2,8,by=2)] - 1
mySquareXts <- xts(rep(myNumericVector,each=2)[-10], order.by=mySquareDateTimes)
chartSeries(mySquareXts, type="line", show.grid="true", theme=chartTheme("black"))
The results are less than ideal.
You want a line.type of "step":
chartSeries(myXts, line.type="s")
See ?plot, specifically "type" under ... in the Arguments section (you may want "S" instead of "s").