简体   繁体   English

将此散景 plot 转换为 JavaScript?

[英]Converting this Bokeh plot to JavaScript?

I asked this question a few weeks ago about making a graph like this in Python, and got a couple ideas from the answer there.几周前我问了这个问题,关于在 Python 中制作这样的图表,并从那里的答案中得到了一些想法。 Basically, I'm trying to make a interactive web chart.基本上,我正在尝试制作一个交互式 web 图表。 It's supposed to be a bunch of points connected by line segments (a connected scatterplot, of sorts).它应该是由线段连接的一堆点(某种连接的散点图)。 Each point has two corresponding axes labels - one that's a box with some text, and one below that which has a number (this number is also what is plotted in that "column" on the chart)每个点都有两个对应的轴标签 - 一个是带有一些文本的框,另一个是在带有数字的框下方(这个数字也是图表上“列”中绘制的内容)

I decided on trying to make my plot using the Python library Bokeh.我决定尝试使用 Python 库 Bokeh 制作我的 plot。 Here's where I'm at so far:这是我目前所处的位置:

import bokeh.io
from bokeh.resources import INLINE
from bokeh.embed import components
from bokeh.models.tools import HoverTool
from bokeh.models import CategoricalAxis, FactorRange
from bokeh.plotting import figure, output_file, show, output_notebook

x = ['label1', 'label2', 'label3', 'label4', 'label5', 'label6', 'label7', 'label8']
y = [1.1, 2.2, 1.8, 4.0, 1.0, 2.8, 3.6, 1.7]
p = figure(x_range=[*x], y_range=(0, 5), plot_height=500)
# dotted line graph is constructed of a circle glyph and a line glyph together
dots = p.circle(x=x, y=y, color='black', size=10)
line = p.line(x=x, y=y, color='black')

numbers = ['1.1', '2.2', '1.8', '4.0', '1.0', '2.8', '3.6', '1.7']
p.extra_x_ranges = {"extra_numbers": FactorRange(factors=numbers)}
p.add_layout(CategoricalAxis(x_range_name="extra_numbers"), 'below')
p.toolbar.logo = None
show(p)

在此处输入图像描述

My apologies about the image resolution.我对图像分辨率表示歉意。

As you can see, the actual plot is a pretty good approximation of what I was aiming for, but the axes don't look good at all.如您所见,实际的 plot 非常接近我的目标,但轴看起来一点也不好看。 Unfortunately, it seems like multi-line axes support is pretty hard in Bokeh, and the difficulty in adding styling to the two x-axes is making me think I should switch my approach.不幸的是,在 Bokeh 中,多线轴支持似乎相当困难,而为两个 x 轴添加样式的困难让我觉得我应该改变我的方法。

I see three possibilities moving forward:我看到了三种可能性:

  1. Try to create a template of the graph in JS, and add the plot into that template.尝试在 JS 中创建图形的模板,并将 plot 添加到该模板中。 In other words, create the bottom two rows of boxes and the y-axis legend in JS, create a connected scatterplot in Bokeh, and place that scatterplot into the JS template.换句话说,在 JS 中创建底部两行框和 y 轴图例,在 Bokeh 中创建连接散点图,并将该散点图放入 JS 模板中。

  2. Recreate this chart in a JS plotting library, like D3.js.在 JS 绘图库中重新创建此图表,例如 D3.js。 This seems like the best long-term solution.这似乎是最好的长期解决方案。

  3. Try to figure it out in Bokeh or some other Python library (I'm a pretty inexperienced dev, but this doesn't seem like it's gonna happen).尝试在 Bokeh 或其他一些 Python 库中弄清楚(我是一个非常缺乏经验的开发人员,但这似乎不会发生)。

I am not super familiar with JS - it'd be great if someone could give me some skeleton code for what this might look like if JavaScript is needed.我对 JS 不是很熟悉——如果需要 JavaScript 的话,如果有人能给我一些骨架代码,那就太好了。 Any suggestions or ideas would be greatly appreciated.任何建议或想法将不胜感激。

If you're not familiar with JS, d3.js may be a little overwhelming.如果你对 JS 不熟悉, d3.js可能有点不知所措。

I personally use highcharts: https://www.highcharts.com/demo我个人使用highcharts: https://www.highcharts.com/demo

You can just find a template and put your data inside, it's also possible to pass the data from python dict to json so that highcharts can render the plot easily, you can forget the front-end and graphical part completely. You can just find a template and put your data inside, it's also possible to pass the data from python dict to json so that highcharts can render the plot easily, you can forget the front-end and graphical part completely.

Here's a similar graph as yours using basic line chart template: https://jsfiddle.net/gpv93e4j/1/这是使用基本折线图模板的类似图表: https://jsfiddle.net/gpv93e4j/1/

<script src="https://code.highcharts.com/highcharts.js"></script>
<script src="https://code.highcharts.com/modules/series-label.js"></script>
<script src="https://code.highcharts.com/modules/exporting.js"></script>
<script src="https://code.highcharts.com/modules/export-data.js"></script>
<script src="https://code.highcharts.com/modules/accessibility.js"></script>

<figure class="highcharts-figure">
    <div id="container"></div>
    <p class="highcharts-description">
        Basic line chart showing trends in a dataset. This chart includes the
        <code>series-label</code> module, which adds a label to each line for
        enhanced readability.
    </p>
</figure>

.highcharts-figure, .highcharts-data-table table {
    min-width: 360px; 
    max-width: 800px;
    margin: 1em auto;
}

.highcharts-data-table table {
    font-family: Verdana, sans-serif;
    border-collapse: collapse;
    border: 1px solid #EBEBEB;
    margin: 10px auto;
    text-align: center;
    width: 100%;
    max-width: 500px;
}
.highcharts-data-table caption {
    padding: 1em 0;
    font-size: 1.2em;
    color: #555;
}
.highcharts-data-table th {
    font-weight: 600;
    padding: 0.5em;
}
.highcharts-data-table td, .highcharts-data-table th, .highcharts-data-table caption {
    padding: 0.5em;
}
.highcharts-data-table thead tr, .highcharts-data-table tr:nth-child(even) {
    background: #f8f8f8;
}
.highcharts-data-table tr:hover {
    background: #f1f7ff;
}

Highcharts.chart('container', {

    title: {
        text: 'title'
    },

    subtitle: {
        text: 'dummy'
    },

    yAxis: {
        title: {
            text: 'y'
        }
    },

    xAxis: [{

        'categories': ['label1', 'label2', 'label3', 'label4', 'label5', 'label6', 'label7', 'label8']
    },
       {
        'categories': ['1.1', '2.2', '1.8', '4.0', '1.0', '2.8', '3.6', '1.7'],
        'linkedTo': 0
       }
    ],

    legend: {
        layout: 'vertical',
        align: 'right',
        verticalAlign: 'middle'
    },



    series: [{
        data: [1.1, 2.2, 1.8, 4.0, 1.0, 2.8, 3.6, 1.7]
    }],

    responsive: {
        rules: [{
            condition: {
                maxWidth: 500
            },
            chartOptions: {
                legend: {
                    layout: 'horizontal',
                    align: 'center',
                    verticalAlign: 'bottom'
                }
            }
        }]
    }

});

NB: I only needed to change the Highcharts.chart part.注意:我只需要更改Highcharts.chart部分。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM