React-vis: Muti series and Y Axes, how to use map and scale

Created on 13 Apr 2017  路  7Comments  路  Source: uber/react-vis

Hi, I have 2 line series and 2 Y axes, but I don't know how to bind each line series to different Y axes

Here is my code

<XYPlot
    width={1000}
    height={600}>
    <HorizontalGridLines />
    <LineSeries data={this.props.temperature} />
    <XAxis title="Time" tickFormat={tickFormatter} />
    <YAxis title="Temperature" />
    <LineSeries data={this.props.pressure} />
    <YAxis title="Pressure" orientation="right" />
</XYPlot>
question

All 7 comments

Hey @nichliu

Unfortunately there isn't a straight forward way to bind axes to series. The core thing to know about the XYplot is that is projecting a coordinate system underneath your data and all marks made in it will adhere to that coordinate system. Said XY coordinate system is formed by looking at the domain of the data for each of the series. In order to make your data appear as you wish in a multiple y-axis type series you will have to modify your data and specify the tick values for each YAxis. Here is a rough sketch on the technique:

  • "Non-dimensionalize" your data: begin by rescaling your data so that y values exist in the range that you wish to shows them. Eg if you have temperatures that go from [50, 97], and pressures that go from [1, 10], you might rescale them to [0, 1]. This will allow them to be expressed in a common zone. (we are referring to this as nondimensionalization, in a hand-wavy kind of way because you are stripping the variables of their hypothetically physical meaning in order to manipulate them computationally). Once all of your yValues exisit in this band [0, 1], it will be easy to compare them.

  • Specify your YAxis tick values: The new artificial coordinate domain will not be meaningful to your reader, so you project the values into your desired coordiantes (temperature, pressure, etc).

<YAxis tickValues={[0, 1, 2, 3, 4]}>

Alternatively if you used a function to rescale your data you can also invert it and use tickFormat.

I am assuming your data sets are properly formatted for LineSeries ([{x: 1, y: 1}, ...] etc). There is some additional discussion in #131. Now that we've said all that, indulge me in a Data Visualizationist Nit Pick: Dual y-axis charts are bad news, they obscure information and can easily be replaced by small multiples.

I'm gonna close this, but feel free to re-open if this doesn't address you question

Hi, @mcnuttandrew

I did rescale all my data range from 0-1, the chart scale still min/max of my readings value provided, not from 0-1
screen shot 2017-04-16 at 8 34 20 am

then I setup tickValues on YAxis, But on chart, the new tickValues never show up, even automatic one gone

screen shot 2017-04-16 at 8 36 05 am

Can you provide a sample of your data? Also can you provide your updated code?

@mcnuttandrew

Here is my code

<XYPlot width={1000} height={600} yDomain={[0,70]} legends={["Test2","Test1"]}  >
    <XAxis title="Time" tickFormat={tickFormatter} />
    <YAxis tickValues={[0,10,20,30,40,50,60]}  title="Temperature" />
    <LineSeries  data={this.props.readings} color="red" format={this.showTemperatureDetail}   />
    <YAxis  tickValues={[10,20,30,40,50,60,70]}  title="Humidity" orientation="right"  />
    <LineSeries  data={this.props.sensorHumidityData} color="blue"   />
</XYPlot>

My data just like
[{x: 1492450301,y:23},{x: 1492450328,y:21.5}]

Right now the chart scale is working, tickValues on left side yAxis is working, but tickValues on second yAxis, right side of the chart are not show up. Here is my screen shot

screen shot 2017-04-17 at 11 29 12

So my comment about rescaling your data is a little bit different. Because your two data sets are unrelated, it is necessary to move them into a common domain. This can be anything, as long it looks correct to you. Specifically, I am suggesting your data should be formatted like:

data = [{x: 1492450301,y:1},{x: 1492450328,y:0}]

then your whole chart should look something like

<XYPlot width={1000} height={1000} >
<XAxis />
<YAxis tickFormat={tick => RESCALING_FUNCTION_FOR_PRESSURE(tick)}/>
<YAxis tickFormat={tick => RESCALING_FUNCTION_FOR_TEMPERATURE(tick)} right={10}/>
<LineSeries data={data1} />
<LineSeries data={data2} />
</XYPlot>

Instead of rescaling all my data, I just made two graphs and positioned them over top of each other with one YAxis on the left and the other YAxis on the right. Only one has an XAxis. Essentially the following:

<div style={{ position: 'relative' }}>
  <div>
    <XYPlot height={400} width={730} margin={{ left: 90, right: 90, bottom: 70 }}>
      <VerticalGridLines />
      <HorizontalGridLines />
      <XAxis />
      <YAxis />
      <LineSeries data={this.props.data1} color="green" />
    </XYPlot>
  </div>
  <div style={{ position: 'absolute', top: 0 }}>
    <XYPlot height={400} width={730} margin={{ left: 90, right: 90, bottom: 70 }}>
      <YAxis orientation="right"/>
      <LineSeries data={this.props.data2} color="blue"/>
    </XYPlot>
  </div>
</div>

You can see it live here: https://goo.gl/o8YC7Y

Was this page helpful?
0 / 5 - 0 ratings

Related issues

cang-afero picture cang-afero  路  4Comments

kbouaazzi-ds picture kbouaazzi-ds  路  3Comments

cvalmonte picture cvalmonte  路  4Comments

jckr picture jckr  路  5Comments

basilaiman picture basilaiman  路  3Comments