Unexpected labels when creating bar graph with plotly.js - javascript

Basic Problem
I'm making a bar graph using plotly.js where the x-axis represents dates. Dates are being fed to plotly as strings; when there are only 1 or 2 elements on the x-axis the labels don't match the strings being fed to plotly.
Context
This is part of a web-application using Flask and Python3, the data for the graph is coming from the Python backend; using console.log() statements I have confirmed that the arrays being given to plotly are as expected.
Example code that results in my error
x_labels = ["2019-01-14", "2019-01-15"]
y_axis = [11, 6]
var trace = {
type: 'bar',
x: x_labels,
y: y_axis,
}
var data = [trace]
var layout = {
xaxis: {
title: 'Date',
},
yaxis: {
title: 'Data'
}
}
Plotly.newPlot(graph, data, layout, {responsive: true})
JS Fiddle Demonstration
http://jsfiddle.net/yjk7r4x1/
Expected Output
The x-axis should just be showing dates such as Jan 13, 2019, Jan 14, 2019... etc. Instead, it is showing up as 12:00 Jan 13, 2019, 0:00 Jan 14, 2019... and so on. I assume those are meant to represent time, but I don't know where the time is coming from or why it is being displayed.

When defining your X-Axis you can modify it to include a "Type" and set the value to "category". By default, the library looks at the data attempts to determine the type for you if it is not specified. Here are what your changes should look like:
JFIDDLE:
http://jsfiddle.net/xa1uy5dz/
<head>
<!-- Plotly.js -->
<script src="https://cdn.plot.ly/plotly-latest.min.js"></script>
</head>
<body>
<!-- Plotly chart will be drawn inside this DIV -->
<div id="incorrect_output" style="width: 100%; height: 500px;"></div>
<script>
graph = document.getElementById("incorrect_output");
x_labels = ["2019-01-14", "2019-01-15"]
y_axis = [11, 6]
var trace = {
type: 'bar',
x: x_labels,
y: y_axis,
}
var data = [trace]
var layout = {
xaxis: {
title: 'Date',
type: 'category'
},
yaxis: {
title: 'Data'
}
}
Plotly.newPlot(graph, data, layout, {responsive: true})
</script>
<div id="accurate_output" style="width: 100%; height: 500px;"></div>
<script>
graph = document.getElementById("accurate_output");
x_labels = ["2019-01-14", "2019-01-15", "2019-01-16"]
y_axis = [11, 6, 8]
var trace = {
type: 'bar',
x: x_labels,
y: y_axis,
}
var data = [trace]
var layout = {
xaxis: {
title: 'Date',
type: 'category'
},
yaxis: {
title: 'Data'
}
}
Plotly.newPlot(graph, data, layout, {responsive: true})
</script>
</body>
Referenced Info:
https://plot.ly/javascript/reference/#layout-xaxis-type

Related

Chart.js not displaying when passing dynamic labels

I am trying to draw a chart by passing values for labels and data dynamically using char.js.
The chart.js module refuses to accept the labels when passed as a variable.
When I hardcode it, it works just fine.
The label variable prints out the values on the page and seems to be correct in format.
Very similar to the problem described in the below query, except that I am already using a proper array.
[https://stackoverflow.com/questions/60453491/chart-js-not-showing-data-when-pass-dynamic-labels][1]
mypage.html:
<script src="https://cdn.jsdelivr.net/npm/chart.js#2.9.4"></script>
{{Messages.vm_size_in_use_labels}}
{{Messages.vm_size_in_use_data}}
<canvas id="chart" width="50" height="50"></canvas>
<script lang="JavaScript">
let ctx = document.getElementById("chart").getContext("2d");
let chart = new Chart(ctx, {
type: "pie",
data: {
labels: {{Messages.vm_size_in_use_labels}},
datasets: [
{
label: "Gross volume ($)",
backgroundColor: "#79AEC8",
borderColor: "#417690",
data: {{Messages.vm_size_in_use_data}},
}
]
},
options: {
title: {
text: "Gross Volume in 2020",
display: true
}
}
});
</script>
The page shows the printed value correctly but chart doesn't display:
['Standard_B1ls', 'Standard_D2_v2', 'Standard_D4s_v3', 'Standard_B1s']
[3, 3, 1, 1]
If I change the label to hard values,
labels: ['Standard_B1ls', 'Standard_D2_v2', 'Standard_D4s_v3', 'Standard_B1s'],
this works just fine and chart is displayed.
Not sure what is missing here. the framework is django if it matters.

How to use highstock with django

I can't use Highstock correctly.
I'm trying to display a candlestick chart with using django and highstock.
My code transfers some ohlcv data from django backend to HTML frontend in JSON format.
And Highstock displays chart but not correctly.
I read highstock official documents but I can't understand many options because I'm a newbie(not only python and javascript even programming).
Please look at my code and a result.
I'd like to teach me.
models.py
from django.db import models
class OandaChartData(models.Model):
exchange_name = models.CharField(max_length=50)
pair = models.CharField(max_length=10)
open_time = models.DateTimeField()
open_value = models.FloatField()
high_value = models.FloatField()
low_value = models.FloatField()
close_value = models.FloatField()
volume = models.FloatField()
write_time = models.DateTimeField(null=True)
views.py
from django.shortcuts import render
from .models import OandaChartData
from django.core import serializers
import json
from datetime import timezone
def highstock_view(request):
record_list = []
records = OandaChartData.objects.all().order_by("id")[0:43200]
for record in records:
open_time = record.open_time.replace(tzinfo=timezone.utc).timestamp() * 1000
open_value = record.open_value
high_value = record.high_value
low_value = record.low_value
close_value = record.close_value
volume = record.volume
record_list_tmp = [open_time, open_value, high_value, low_value, close_value, volume]
record_list.append(record_list_tmp)
record_json = json.dumps(record_list)
return render(request, 'scraping/highstock_view.html', {'record_json':record_json})
HTML
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>HighStockView</title>
</head>
<body>
<script src="https://code.jquery.com/jquery-3.1.1.min.js"></script>
<script src="https://code.highcharts.com/stock/highstock.js"></script>
<script src="https://code.highcharts.com/stock/modules/exporting.js"></script>
<div id="container" style="height: 400px; min-width: 310px"></div>
<script>
let data = {{record_json|safe}},
ohlc = [],
volume = [],
datalength = data.length,
groupingUnits = [[
'minutes',
[1, 5, 15, 30]
], [
'hours',
[1, 2, 4, 12]
], [
'month',
[1, 2, 3, 4, 6]
]],
i = 0;
for (i ; i < datalength ; i += 1) {
ohlc.push([
data[i][0],
data[i][1],
data[i][2],
data[i][3],
data[i][4],
]);
volume.push([
data[i][0],
data[i][5],
]);
}
// create the chart
Highcharts.stockChart('container', {
rangeSelector: {
selected: 1
},
title: {
text: 'OANDA USD/JPY'
},
yAxis: [{
labels: {
align: 'right',
x: -3
},
title: {
text: 'OHLC'
},
height: '60%',
lineWidth: 2,
resize: {
enabled: true
}
}, {
labels: {
align: 'right',
x: -3
},
title: {
text: 'Volume'
},
top: '65%',
height: '35%',
offset: 0,
lineWidth: 2
}],
tooltip: {
split: true
},
series: [{
type: 'candlestick',
name: 'USD/JPY',
data: ohlc,
dataGrouping: {
units: groupingUnits
}
}, {
type: 'column',
name: 'Volume',
data: volume,
yAxis: 1,
dataGrouping: {
units: groupingUnits
}
}]
});
</script>
{{ record_json }}
This is screenshot of above HTML page.
JSON data is a 1-minute data for 1 month.
I want to display a 1-minute chart but above HTML seems to display a 1-month chart(But 2 candlesticks(two months period ?) are displayed.)
And above HTML has some grey out button.
note: The raw text following the chart in the HTML is to confirm data transferring correctly.
Please help me.
db.sqlite3 file is in the following link.
https://drive.google.com/file/d/1bFun10rcbOjmqSTv45QfkL26pfMpvzZZ/view?usp=sharing
And sample.txt that received by frontend HTML is in the following link.
https://drive.google.com/file/d/1KXASJDunrKkVHmn5Y9u5R-f1x_ZH5lrn/view?usp=sharing

Long tick labels getting cut off in plotly.js chart

Is it possible to give more room for tick labels in plotly.js? Long labels in my charts are getting cut off.
HTML:
<div id="plot"></div>
JavaScript:
var data = [{
type: 'bar',
x: [20, 14, 23],
y: ['giraffes', 'orangutans', 'a looooooooong string'],
orientation: 'h'
}];
var layout = {
title: 'Bar Chart'
};
Plotly.newPlot('plot', data, layout);
I can't see how to do this in the API for y-axes tick settings.
Given the nature of my charts, I need to use a horizontal orientation. So a solution I can't use is a vertical orientation with ticks rotated 90 degrees.
Update: plotly added support for automargins (see https://github.com/plotly/plotly.js/pull/2243), via the .axis.automargin configuration option.
To use, you'd change:
var layout = {
title: 'Bar Chart'
};
to:
var layout = {
title: 'Bar Chart',
yaxis: {
automargin: true
}
};
For more information, see https://plot.ly/javascript/axes/
Original Answer:
You can adjust the margins of plotly charts to give yourself some more space. For instance, change:
var layout = {
title: 'Bar Chart'
};
to
var layout = {
title: 'Bar Chart',
margin: {
l: 200
}
};
you can read more about adjusting margins here: https://plot.ly/javascript/setting-graph-size/
and overall layout options here: https://plot.ly/javascript/#layout-options
You can also set margin dynamically, based on label length:
var maxLabelLength = d3.max(data, d => d3.max(d.y, label => label.length));
const letterWidth = 7;
var layout = {
title: 'Bar Chart',
margin:{
l: maxLabelLength * letterWidth
}
};

How does one load a json encoded array as the x-axis for c3.js?

Pretty much the title. I have an array of serial numbers that I want to make as the x-axis. The array data itself was sucked up from a database via PHP. I then json_encode'd it and made it into a js array. The problem I'm having is that there is a separate section for both json: and columns: when generating a C3js graph.
var jsarray = <?php echo json_encode($array) ?>;
var chart = c3.generate({
bindto: '#chart',
data: {
x: 'js_array',
columns: [
['x', js_array]
],
json: {
Data_points,
Data_points2
},
axis: {
y: {
label: { // ADD
text: 'Y axis title',
position: 'outer-middle'
}
}
}
});
I tried looking for an example in the c3.js documentation, but they have separate sections for JSON data and formatting the x-axis. I didn't see a section where they combined the two though.
If I understand correctly, you're looking to be able to label the X-Axis data points while using JSON data, kind of like this example: http://c3js.org/samples/data_stringx.html ?
Assuming you have data in your PHP that looks something like this:
$php_data = array(
'x_labels' => array('MON', 'TUE', 'WED', 'THU', 'FRI'),
'data1' => array(30, 200, 100, 400, 150, 250),
'data2' => array(50, 20, 10, 40, 15, 25)
);
...then you should be able to achieve something similar to the example above using JSON data like so:
var json_data = <?php echo json_encode($php_data) ?>;
var chart = c3.generate({
bindto: "#chart",
data: {
x: 'x_labels',
json: json_data
},
axis: {
x: {
type: 'category'
},
y: {
label: 'number'
}
}
});
The data: { x: 'x_labels' } part tells the library to use the data under the array key "x_labels" at the axis labels, and then under axis: { x: { type: 'category' } }, we specify that we want to use strings for the label type rather than numbers. You don't have to specify this if your axis labels are numbers (e.g. 'x_labels' => array(1, 2, 3, 4, 5)).
Here's a jsfiddle if you want to play around with it:
https://jsfiddle.net/WingZero/Ldk4shLz/3/

Highcharts not plotting Date string as Category

I am using Highcharts to plot JSON Data. The dates are in the string format.
JSON Data:
[{"BRENT_SPOT":70.88,"TRADE_DATE":"31-JUL-2009"},{"BRENT_SPOT":73.28,"TRADE_DATE":"03-AUG-2009"},{"BRENT_SPOT":74.31,"TRADE_DATE":"04-AUG-2009"},{"BRENT_SPOT":74.96,"TRADE_DATE":"05-AUG-2009"},{"BRENT_SPOT":74.4,"TRADE_DATE":"06-AUG-2009"},{"BRENT_SPOT":72.84,"TRADE_DATE":"07-AUG-2009"},{"BRENT_SPOT":73.29,"TRADE_DATE":"10-AUG-2009"},{"BRENT_SPOT":72.04,"TRADE_DATE":"11-AUG-2009"}]
HighCharts / JQuery Code :
<script>
var chart;
$(function() {
var options = {
chart: {
renderTo: 'container',
zoomType: 'xy',
type: 'line'
},
title: {
text: 'Brent Daily Price Curve (FPC as at <cfoutput>#f_date#</cfoutput>)'
},
xAxis: {
labels: {
rotation: 45,
step: 3
},
type: 'category'
},
yAxis: {
lineWidth: 1,
title: {
text: '$ USD'
},
min: 0
},
series: []
};
$.getJSON("brentpricehc_test.cfm?f_date=<cfoutput>#f_date#</cfoutput>", {}, function(jsonResult) {
var BrentUSDPrice = {
name: "Brent Spot (USD)",
type: "line",
data: [],
marker: {
radius: 2
}
};
$(jsonResult).each(function(index) {
BrentUSDPrice.data.push([this.TRADE_DATE, this.BRENT_SPOT]);
});
/*options.series[0] = BrentUSDPrice;*/
options.series.push(BrentUSDPrice);
chart = new Highcharts.Chart(options);
});
});
</script>
I'm unable to plot any values wrt each of the date strings. I tried converting the JSON dates to datetime instead but still the same issue.
Few More details (for testing purposes):
Modifying to the below line plots the graph with the correct "brent_spot" values. This means that the issue lies with the way the "trade_dates" are 'not' plotting.
BrentUSDPrice.data.push([index, this.BRENT_SPOT]);
Edit 2 : (Using Datetime type to make the code work)
JSON Data (New): Returned as TO_CHAR(TRADE_DATE, 'YYYY/MM/DD')
[{"BRENT_SPOT":70.88,"TRADE_DATE":"2009\/07\/31"},{"BRENT_SPOT":73.28,"TRADE_DATE":"2009\/08\/03"},{"BRENT_SPOT":74.31,"TRADE_DATE":"2009\/08\/04"},{"BRENT_SPOT":74.96,"TRADE_DATE":"2009\/08\/05"},{"BRENT_SPOT":74.4,"TRADE_DATE":"2009\/08\/06"},{"BRENT_SPOT":72.84,"TRADE_DATE":"2009\/08\/07"},{"BRENT_SPOT":73.29,"TRADE_DATE":"2009\/08\/10"},{"BRENT_SPOT":72.04,"TRADE_DATE":"2009\/08\/11"}]
$(jsonResult).each(function(index) {
BrentUSDPrice.data.push([new Date(this.TRADE_DATE), this.BRENT_SPOT]);
});
Server side language used : Coldfusion
Database : Oracle
Am I doing something silly somewhere?
I have just tried your code, and it works perfectly fine, see: http://jsfiddle.net/3bQne/1026/
I guess, you need to update to Highcharts 3.0.10 to get this working.
If you are using type: 'category' then you need to assign name: to the data points. See the categories entry at http://api.highcharts.com/highcharts#xAxis
If categories are present for the xAxis, names are used instead of numbers for that axis. Since Highcharts 3.0, categories can also be extracted by giving each point a name and setting axis type to "category".
So the question is whether you are using Highcharts 3.0 and if you do then it needs to look something like this:
data: [{
name: 'Point 1',
color: '#00FF00',
y: 0
}, {
name: 'Point 2',
color: '#FF00FF',
y: 5
}]
see: http://api.highcharts.com/highcharts#series.data

Categories

Resources