3d histogram without external programs3-dimensional histogram in pgfplotsHow to plot trinomial distribution...
What is a clear way to write a bar that has an extra beat?
Does an object always see its latest internal state irrespective of thread?
dbcc cleantable batch size explanation
Fully-Firstable Anagram Sets
A newer friend of my brother's gave him a load of baseball cards that are supposedly extremely valuable. Is this a scam?
Codimension of non-flat locus
Today is the Center
Intersection point of 2 lines defined by 2 points each
Why can't we play rap on piano?
Is it legal for company to use my work email to pretend I still work there?
Can I ask the recruiters in my resume to put the reason why I am rejected?
Which country benefited the most from UN Security Council vetoes?
High voltage LED indicator 40-1000 VDC without additional power supply
Is it tax fraud for an individual to declare non-taxable revenue as taxable income? (US tax laws)
Replacing matching entries in one column of a file by another column from a different file
Can I make popcorn with any corn?
What do the dots in this tr command do: tr .............A-Z A-ZA-Z <<< "JVPQBOV" (with 13 dots)
Arrow those variables!
When a company launches a new product do they "come out" with a new product or do they "come up" with a new product?
What's the point of deactivating Num Lock on login screens?
What's the output of a record needle playing an out-of-speed record
I'm flying to France today and my passport expires in less than 2 months
Are astronomers waiting to see something in an image from a gravitational lens that they've already seen in an adjacent image?
How can I prevent hyper evolved versions of regular creatures from wiping out their cousins?
3d histogram without external programs
3-dimensional histogram in pgfplotsHow to plot trinomial distribution in tikz?Sorting according to more than one key in pgfplotstableBuilding a 2D histogram with PGFPlotsHow to prevent rounded and duplicated tick labels in pgfplots with fixed precision?Specify marker color to come from colormap in @pre marker codeScatterplot from table with markers set by meta column valueNormalized histogram (density) in pgfplotspgfplots: percentage in matrix plotDefine colours of markers of scatterplot by rgb-valuesSymbolic coordinates with explicit labels are in wrong orderscatter plot - mark absolute size from data and custom colormappgfplots: updating and accessing a macro definition across different interations of plotting points
I have found the answer from @marmot in the following post, which looks very nice and doesn't need any external programs. But I have some problem to adjust the z axis to my data.
3-dimensional histogram in pgfplots
In this example the z values of my data are not between 0 and 100, but between 0 and 1000.
I don't get the part where it says "here one has to cheat". What do I need to adjust for z values not between 0 and 100?
documentclass[tikz,border=3.14pt]{standalone}
usepackage{pgfplots}
usepackage{pgfplotstable}
pgfplotsset{compat=1.15}
begin{document}
pgfplotstableread[col sep=comma,header=true]{%
x,y,color,myvalue
2,3,1,1000
4,3,2,30
2,7,3,0.75
7,7,4,450
8,5,2,300
2,5,1,100
4,-4,2,1
4,1,3,750
5,-1,4,4
5,2,2,300
1,-2,1,100
2,5,2,5
3,-8,3,750
4,5,4,420
7,-2,2,200
}{datatable}
%
pgfplotstablesort[col sep=comma,header=true]resulttable{datatable}
begin{tikzpicture}%[x={(0.866cm,-0.5cm)},y={(0.866cm,0.5cm)},z={(0cm,1 cm)}]
pgfplotsset{set layers}
begin{axis}[% from section 4.6.4 of the pgfplotsmanual
view={120}{40},
width=320pt,
height=280pt,
z buffer=none,
xmin=-1,xmax=8,
ymin=-10,ymax=8,
zmin=0,zmax=1000,
enlargelimits=upper,
ztick={0,500,1000},
zticklabels={0,500,1000}, % here one has to "cheat"
xtick=data,
extra tick style={grid=major},
ytick=data,
grid=minor,
xlabel={$x$},
ylabel={$y$},
zlabel={$z$},
minor tick num=1,
point meta=explicit,
colormap name=viridis,
scatter/use mapped color={
draw=mapped color,fill=mapped color!70},
]
addplot3 [visualization depends on={z as myz},
scatter/@pre marker code/.append style={/pgfplots/cube/size z=myz},%
scatter,only marks,
mark=cube*,mark size=5]
table[x expr={thisrow{x}},y expr={thisrow{y}},z
expr={thisrow{myvalue}},
meta expr={thisrow{color}}
] resulttable;
end{axis}
end{tikzpicture}
end{document}
Result:
EDIT:
Now after Marmot presented a really nice solution for plotting a 3d histogram, I am asking if it's possible to make it even more automatic, by also computing the depth and width of the bars?
ADDITION:
I have some data sets with a very high range in x and y. When I change the cube size like suggested in x and y direction I get very small bars (see first image below). My data is a classification, where the range is split up in 64 or 100 classes. So one bar needs to be as big as the range divided by 64 or 100 in x and y direction. The solution marmot suggested works fine, but in this specific case the cube sizes are to small. It says 0,00192pt in x and 0,00272pt in y direction. Right now I am calculating the cube size by hand. I take the values given by marmot and multiply them with my range and then divide them with my classes. For x direction: 0,00192pt*65000/64=1,95pt and for y: 0,00272pt*65000/64=2,7625pt. (Result in second image)
How can I adapt this to the code?
tikz-pgf pgfplots
add a comment |
I have found the answer from @marmot in the following post, which looks very nice and doesn't need any external programs. But I have some problem to adjust the z axis to my data.
3-dimensional histogram in pgfplots
In this example the z values of my data are not between 0 and 100, but between 0 and 1000.
I don't get the part where it says "here one has to cheat". What do I need to adjust for z values not between 0 and 100?
documentclass[tikz,border=3.14pt]{standalone}
usepackage{pgfplots}
usepackage{pgfplotstable}
pgfplotsset{compat=1.15}
begin{document}
pgfplotstableread[col sep=comma,header=true]{%
x,y,color,myvalue
2,3,1,1000
4,3,2,30
2,7,3,0.75
7,7,4,450
8,5,2,300
2,5,1,100
4,-4,2,1
4,1,3,750
5,-1,4,4
5,2,2,300
1,-2,1,100
2,5,2,5
3,-8,3,750
4,5,4,420
7,-2,2,200
}{datatable}
%
pgfplotstablesort[col sep=comma,header=true]resulttable{datatable}
begin{tikzpicture}%[x={(0.866cm,-0.5cm)},y={(0.866cm,0.5cm)},z={(0cm,1 cm)}]
pgfplotsset{set layers}
begin{axis}[% from section 4.6.4 of the pgfplotsmanual
view={120}{40},
width=320pt,
height=280pt,
z buffer=none,
xmin=-1,xmax=8,
ymin=-10,ymax=8,
zmin=0,zmax=1000,
enlargelimits=upper,
ztick={0,500,1000},
zticklabels={0,500,1000}, % here one has to "cheat"
xtick=data,
extra tick style={grid=major},
ytick=data,
grid=minor,
xlabel={$x$},
ylabel={$y$},
zlabel={$z$},
minor tick num=1,
point meta=explicit,
colormap name=viridis,
scatter/use mapped color={
draw=mapped color,fill=mapped color!70},
]
addplot3 [visualization depends on={z as myz},
scatter/@pre marker code/.append style={/pgfplots/cube/size z=myz},%
scatter,only marks,
mark=cube*,mark size=5]
table[x expr={thisrow{x}},y expr={thisrow{y}},z
expr={thisrow{myvalue}},
meta expr={thisrow{color}}
] resulttable;
end{axis}
end{tikzpicture}
end{document}
Result:
EDIT:
Now after Marmot presented a really nice solution for plotting a 3d histogram, I am asking if it's possible to make it even more automatic, by also computing the depth and width of the bars?
ADDITION:
I have some data sets with a very high range in x and y. When I change the cube size like suggested in x and y direction I get very small bars (see first image below). My data is a classification, where the range is split up in 64 or 100 classes. So one bar needs to be as big as the range divided by 64 or 100 in x and y direction. The solution marmot suggested works fine, but in this specific case the cube sizes are to small. It says 0,00192pt in x and 0,00272pt in y direction. Right now I am calculating the cube size by hand. I take the values given by marmot and multiply them with my range and then divide them with my classes. For x direction: 0,00192pt*65000/64=1,95pt and for y: 0,00272pt*65000/64=2,7625pt. (Result in second image)
How can I adapt this to the code?
tikz-pgf pgfplots
add a comment |
I have found the answer from @marmot in the following post, which looks very nice and doesn't need any external programs. But I have some problem to adjust the z axis to my data.
3-dimensional histogram in pgfplots
In this example the z values of my data are not between 0 and 100, but between 0 and 1000.
I don't get the part where it says "here one has to cheat". What do I need to adjust for z values not between 0 and 100?
documentclass[tikz,border=3.14pt]{standalone}
usepackage{pgfplots}
usepackage{pgfplotstable}
pgfplotsset{compat=1.15}
begin{document}
pgfplotstableread[col sep=comma,header=true]{%
x,y,color,myvalue
2,3,1,1000
4,3,2,30
2,7,3,0.75
7,7,4,450
8,5,2,300
2,5,1,100
4,-4,2,1
4,1,3,750
5,-1,4,4
5,2,2,300
1,-2,1,100
2,5,2,5
3,-8,3,750
4,5,4,420
7,-2,2,200
}{datatable}
%
pgfplotstablesort[col sep=comma,header=true]resulttable{datatable}
begin{tikzpicture}%[x={(0.866cm,-0.5cm)},y={(0.866cm,0.5cm)},z={(0cm,1 cm)}]
pgfplotsset{set layers}
begin{axis}[% from section 4.6.4 of the pgfplotsmanual
view={120}{40},
width=320pt,
height=280pt,
z buffer=none,
xmin=-1,xmax=8,
ymin=-10,ymax=8,
zmin=0,zmax=1000,
enlargelimits=upper,
ztick={0,500,1000},
zticklabels={0,500,1000}, % here one has to "cheat"
xtick=data,
extra tick style={grid=major},
ytick=data,
grid=minor,
xlabel={$x$},
ylabel={$y$},
zlabel={$z$},
minor tick num=1,
point meta=explicit,
colormap name=viridis,
scatter/use mapped color={
draw=mapped color,fill=mapped color!70},
]
addplot3 [visualization depends on={z as myz},
scatter/@pre marker code/.append style={/pgfplots/cube/size z=myz},%
scatter,only marks,
mark=cube*,mark size=5]
table[x expr={thisrow{x}},y expr={thisrow{y}},z
expr={thisrow{myvalue}},
meta expr={thisrow{color}}
] resulttable;
end{axis}
end{tikzpicture}
end{document}
Result:
EDIT:
Now after Marmot presented a really nice solution for plotting a 3d histogram, I am asking if it's possible to make it even more automatic, by also computing the depth and width of the bars?
ADDITION:
I have some data sets with a very high range in x and y. When I change the cube size like suggested in x and y direction I get very small bars (see first image below). My data is a classification, where the range is split up in 64 or 100 classes. So one bar needs to be as big as the range divided by 64 or 100 in x and y direction. The solution marmot suggested works fine, but in this specific case the cube sizes are to small. It says 0,00192pt in x and 0,00272pt in y direction. Right now I am calculating the cube size by hand. I take the values given by marmot and multiply them with my range and then divide them with my classes. For x direction: 0,00192pt*65000/64=1,95pt and for y: 0,00272pt*65000/64=2,7625pt. (Result in second image)
How can I adapt this to the code?
tikz-pgf pgfplots
I have found the answer from @marmot in the following post, which looks very nice and doesn't need any external programs. But I have some problem to adjust the z axis to my data.
3-dimensional histogram in pgfplots
In this example the z values of my data are not between 0 and 100, but between 0 and 1000.
I don't get the part where it says "here one has to cheat". What do I need to adjust for z values not between 0 and 100?
documentclass[tikz,border=3.14pt]{standalone}
usepackage{pgfplots}
usepackage{pgfplotstable}
pgfplotsset{compat=1.15}
begin{document}
pgfplotstableread[col sep=comma,header=true]{%
x,y,color,myvalue
2,3,1,1000
4,3,2,30
2,7,3,0.75
7,7,4,450
8,5,2,300
2,5,1,100
4,-4,2,1
4,1,3,750
5,-1,4,4
5,2,2,300
1,-2,1,100
2,5,2,5
3,-8,3,750
4,5,4,420
7,-2,2,200
}{datatable}
%
pgfplotstablesort[col sep=comma,header=true]resulttable{datatable}
begin{tikzpicture}%[x={(0.866cm,-0.5cm)},y={(0.866cm,0.5cm)},z={(0cm,1 cm)}]
pgfplotsset{set layers}
begin{axis}[% from section 4.6.4 of the pgfplotsmanual
view={120}{40},
width=320pt,
height=280pt,
z buffer=none,
xmin=-1,xmax=8,
ymin=-10,ymax=8,
zmin=0,zmax=1000,
enlargelimits=upper,
ztick={0,500,1000},
zticklabels={0,500,1000}, % here one has to "cheat"
xtick=data,
extra tick style={grid=major},
ytick=data,
grid=minor,
xlabel={$x$},
ylabel={$y$},
zlabel={$z$},
minor tick num=1,
point meta=explicit,
colormap name=viridis,
scatter/use mapped color={
draw=mapped color,fill=mapped color!70},
]
addplot3 [visualization depends on={z as myz},
scatter/@pre marker code/.append style={/pgfplots/cube/size z=myz},%
scatter,only marks,
mark=cube*,mark size=5]
table[x expr={thisrow{x}},y expr={thisrow{y}},z
expr={thisrow{myvalue}},
meta expr={thisrow{color}}
] resulttable;
end{axis}
end{tikzpicture}
end{document}
Result:
EDIT:
Now after Marmot presented a really nice solution for plotting a 3d histogram, I am asking if it's possible to make it even more automatic, by also computing the depth and width of the bars?
ADDITION:
I have some data sets with a very high range in x and y. When I change the cube size like suggested in x and y direction I get very small bars (see first image below). My data is a classification, where the range is split up in 64 or 100 classes. So one bar needs to be as big as the range divided by 64 or 100 in x and y direction. The solution marmot suggested works fine, but in this specific case the cube sizes are to small. It says 0,00192pt in x and 0,00272pt in y direction. Right now I am calculating the cube size by hand. I take the values given by marmot and multiply them with my range and then divide them with my classes. For x direction: 0,00192pt*65000/64=1,95pt and for y: 0,00272pt*65000/64=2,7625pt. (Result in second image)
How can I adapt this to the code?
tikz-pgf pgfplots
tikz-pgf pgfplots
edited Jul 3 '18 at 7:31
sporc
asked Jun 6 '18 at 8:04
sporcsporc
493214
493214
add a comment |
add a comment |
1 Answer
1
active
oldest
votes
You also need to adjust the height in that case. Note that you also draw some of the bars at the same x
and y
values. The current version of this trick doesn't support this. Before fixing this I would like to know if you really mean to draw them at the same x-y positions. UPDATE: I added an improved sort. Have a guess from whom I stole it. (Hint: his last name starts with "F" and ends with "euersänger";-) ANOTHER UPDATE: I made the thing more automatic. Due to the usual expansion issues, I could not make the conversion fully automatic, but now at least it will tell you what to put.
documentclass[tikz,border=3.14pt]{standalone}
usetikzlibrary{calc}
usepackage{pgfplots}
usepackage{pgfplotstable}
pgfplotsset{compat=1.16}
% from https://tex.stackexchange.com/a/102770/121799
defpgfplotsinvokeiflessthan#1#2#3#4{%
pgfkeysvalueof{/pgfplots/iflessthan/.@cmd}{#1}{#2}{#3}{#4}pgfeov
}%
defpgfplotsmulticmpthree#1#2#3#4#5#6do#7#8{%
pgfplotsset{float <}%
pgfplotsinvokeiflessthan{#1}{#4}{%
% first key <:
#7%
}{%
pgfplotsinvokeiflessthan{#4}{#1}{%
% first key >:
#8%
}{%
% first key ==:
pgfplotsset{float <}%
pgfplotsinvokeiflessthan{#2}{#5}{%
% second key <
#7%
}{%
pgfplotsinvokeiflessthan{#5}{#2}{%
% second key >
#8%
}{%
% second key ==
pgfplotsset{float <}%
pgfplotsinvokeiflessthan{#3}{#6}{%
% third key <
#7%
}{%
% third key >=
#8%
}%
}%
}%
}%
}%
}%
begin{document}
pgfplotstableread[col sep=comma,header=true]{%
x,y,color,myvalue
2,3,1,1000
4,3,2,30
2,7,3,0.75
7,7,4,450
8,5,2,300
2,5,1,100
4,-4,2,1
4,1,3,750
5,-1,4,4
5,2,2,300
1,-2,1,100
2,5,2,5
3,-8,3,750
4,5,4,420
7,-2,2,200
}{datatable}
%
%pgfplotstablesort[col sep=comma,header=true]resulttable{datatable}
pgfplotstablesort[create on use/sortkey/.style={
create col/assign/.code={%
edefentry{{thisrow{x}}{thisrow{y}}{thisrow{myvalue}}}%
pgfkeyslet{/pgfplots/table/create col/next content}entry
}
},
sort key=sortkey,
sort cmp={%
iflessthan/.code args={#1#2#3#4}{%
edeftemp{#1#2}%
expandafterpgfplotsmulticmpthreetempdo{#3}{#4}%
},
},
sort,
columns/Mtx/.style={string type},
columns/Kind/.style={string type},]resulttable{datatable}
begin{tikzpicture}%[x={(0.866cm,-0.5cm)},y={(0.866cm,0.5cm)},z={(0cm,1 cm)}]
pgfplotsset{set layers}
begin{axis}[% from section 4.6.4 of the pgfplotsmanual
view={120}{40},
width=320pt,
height=280pt,
z buffer=none,
xmin=-1,xmax=9,
ymin=-10,ymax=8,
zmin=0,zmax=2000,
enlargelimits=upper,
ztick={0,1000,2000},
zticklabels={0,500,1000}, % here one has to "cheat"
% meaning that one has to put labels which are the actual value
% divided by 2. This is because the bars will be centered at these
% values
xtick=data,
extra tick style={grid=major},
ytick=data,
grid=minor,
xlabel={$x$},
ylabel={$y$},
zlabel={$z$},
minor tick num=1,
point meta=explicit,
colormap name=viridis,
scatter/use mapped color={
draw=mapped color,fill=mapped color!70},
execute at begin plot={}
]
path let p1=($(axis cs:0,0,1)-(axis cs:0,0,0)$) in
pgfextra{pgfmathsetmacro{conv}{2*y1}
typeout{Kindlyspacespace considerspace settingspace thespace
prefactorspace ofspace zspace tospace conv}};
addplot3 [visualization depends on={
0.09952*z as myz}, % you'll get told how to adjust the prefactor
scatter/@pre marker code/.append style={/pgfplots/cube/size z=myz},%
scatter,only marks,
mark=cube*,mark size=5,opacity=1]
table[x expr={thisrow{x}},y expr={thisrow{y}},z
expr={1*thisrow{myvalue}},
meta expr={thisrow{color}}
] resulttable;
end{axis}
end{tikzpicture}
end{document}
ADDENDUM: In this version, the dimension for "full size" bars are computed, i.e. the x and y dimensions to make the bar fill out one unit in each direction. It also checks if the user already has put the correct z scale. It computes the correct scale factor, and asks you to recompile if necessary.
documentclass[tikz,border=3.14pt]{standalone}
usetikzlibrary{calc}
usepackage{pgfplots}
usepackage{pgfplotstable}
pgfplotsset{compat=1.16}
% from https://tex.stackexchange.com/a/102770/121799
defpgfplotsinvokeiflessthan#1#2#3#4{%
pgfkeysvalueof{/pgfplots/iflessthan/.@cmd}{#1}{#2}{#3}{#4}pgfeov
}%
defpgfplotsmulticmpthree#1#2#3#4#5#6do#7#8{%
pgfplotsset{float <}%
pgfplotsinvokeiflessthan{#1}{#4}{%
% first key <:
#7%
}{%
pgfplotsinvokeiflessthan{#4}{#1}{%
% first key >:
#8%
}{%
% first key ==:
pgfplotsset{float <}%
pgfplotsinvokeiflessthan{#2}{#5}{%
% second key <
#7%
}{%
pgfplotsinvokeiflessthan{#5}{#2}{%
% second key >
#8%
}{%
% second key ==
pgfplotsset{float <}%
pgfplotsinvokeiflessthan{#3}{#6}{%
% third key <
#7%
}{%
% third key >=
#8%
}%
}%
}%
}%
}%
}%
begin{document}
ifdefinedgconv
else
pgfmathsetmacro{gconv}{0.1}
fi
pgfplotstableread[col sep=comma,header=true]{%
x,y,color,myvalue
2,3,1,1000
4,3,2,30
2,7,3,0.75
7,7,4,450
8,5,2,300
2,5,1,100
4,-4,2,1
4,1,3,750
5,-1,4,4
5,2,2,300
1,-2,1,100
2,5,2,5
3,-8,3,750
4,5,4,420
7,-2,2,200
}{datatable}
%
%pgfplotstablesort[col sep=comma,header=true]resulttable{datatable}
pgfplotstablesort[create on use/sortkey/.style={
create col/assign/.code={%
edefentry{{thisrow{x}}{thisrow{y}}{thisrow{myvalue}}}%
pgfkeyslet{/pgfplots/table/create col/next content}entry
}
},
sort key=sortkey,
sort cmp={%
iflessthan/.code args={#1#2#3#4}{%
edeftemp{#1#2}%
expandafterpgfplotsmulticmpthreetempdo{#3}{#4}%
},
},
sort,
columns/Mtx/.style={string type},
columns/Kind/.style={string type},]resulttable{datatable}
begin{tikzpicture}%[x={(0.866cm,-0.5cm)},y={(0.866cm,0.5cm)},z={(0cm,1 cm)}]
pgfplotsset{set layers}
begin{axis}[% from section 4.6.4 of the pgfplotsmanual
view={120}{40},
width=320pt,
height=280pt,
z buffer=none,
xmin=-1,xmax=9,
ymin=-10,ymax=8,
zmin=0,zmax=2000,
enlargelimits=upper,
ztick={0,1000,2000},
zticklabels={0,500,1000}, % here one has to "cheat"
% meaning that one has to put labels which are the actual value
% divided by 2. This is because the bars will be centered at these
% values
xtick=data,
extra tick style={grid=major},
ytick=data,
grid=minor,
xlabel={$x$},
ylabel={$y$},
zlabel={$z$},
minor tick num=1,
point meta=explicit,
colormap name=viridis,
scatter/use mapped color={
draw=mapped color,fill=mapped color!70},
execute at begin plot={}
]
path let p1=($(axis cs:0,0,1)-(axis cs:0,0,0)$) in
pgfextra{pgfmathsetmacro{conv}{2*y1}
ifxgconvconv
else
xdefgconv{conv}
typeout{Pleasespace recompilespace thespace file!}
fi
};
path let p1=($(axis cs:1,0,0)-(axis cs:0,0,0)$) in
pgfextra{pgfmathsetmacro{convx}{veclen(x1,y1)}
typeout{Onespace unitspace inspace xspace
directionspace isspaceconvx pt}
};
path let p1=($(axis cs:0,1,0)-(axis cs:0,0,0)$) in
pgfextra{pgfmathsetmacro{convy}{veclen(x1,y1)}
typeout{Onespace unitspace inspace yspace
directionspace isspaceconvy pt}
};
addplot3 [visualization depends on={
gconv*z as myz}, % you may have to recompile to get the prefactor right
scatter/@pre marker code/.append style={/pgfplots/cube/size z=myz},%
scatter/@pre marker code/.append style={/pgfplots/cube/size x=11.66135pt},%
scatter/@pre marker code/.append style={/pgfplots/cube/size y=9.10493pt},%
scatter,only marks,
mark=cube*,mark size=5,opacity=1]
table[x expr={thisrow{x}},y expr={thisrow{y}},z
expr={1*thisrow{myvalue}},
meta expr={thisrow{color}}
] resulttable;
end{axis}
makeatletter
immediatewrite@mainaux{xdefstringgconv{gconv}relax}
makeatother
end{tikzpicture}
end{document}
I really appreciate your efforts. Thank you! When you change the angle of the view, for example toview={50}{70}
something get's messed up with the sorting, the bars are overlapping, the same happens when you setx dir=reversed
. Maybe there is a solution for it by changing the sorting algorithm. One little addition: You could add "pt" at the end of the typeout for the depth and width.
– sporc
Jun 12 '18 at 7:35
@sporc Yes, of course, if you change the view, it won't work any more. And I am doing the sort independently of the view. At this point, I don't see any easy way to fix that. But thanks for the remark onpt
, I'll change this right away.
– marmot
Jun 12 '18 at 14:45
Could you please explain how you calculate the x and y dimensions. As far as I understand you take the length from (1,0,0) to (0,0,0) for x and divide it by xmax? I am asking beacuase I want to adjust the code so that it takes the length (1,0,0) to (0,0,0) and divides it by a fix value, like 100. So that 100 bars would fit along the axis
– sporc
Jun 28 '18 at 11:22
@sporc Yes, that's precisely how I compute it.
– marmot
Jun 28 '18 at 14:18
I can't see where you divide. Isn't this just the length?pgfextra{pgfmathsetmacro{convy}{veclen(x1,y1)}
– sporc
Jun 29 '18 at 6:44
|
show 8 more comments
Your Answer
StackExchange.ready(function() {
var channelOptions = {
tags: "".split(" "),
id: "85"
};
initTagRenderer("".split(" "), "".split(" "), channelOptions);
StackExchange.using("externalEditor", function() {
// Have to fire editor after snippets, if snippets enabled
if (StackExchange.settings.snippets.snippetsEnabled) {
StackExchange.using("snippets", function() {
createEditor();
});
}
else {
createEditor();
}
});
function createEditor() {
StackExchange.prepareEditor({
heartbeatType: 'answer',
autoActivateHeartbeat: false,
convertImagesToLinks: false,
noModals: true,
showLowRepImageUploadWarning: true,
reputationToPostImages: null,
bindNavPrevention: true,
postfix: "",
imageUploader: {
brandingHtml: "Powered by u003ca class="icon-imgur-white" href="https://imgur.com/"u003eu003c/au003e",
contentPolicyHtml: "User contributions licensed under u003ca href="https://creativecommons.org/licenses/by-sa/3.0/"u003ecc by-sa 3.0 with attribution requiredu003c/au003e u003ca href="https://stackoverflow.com/legal/content-policy"u003e(content policy)u003c/au003e",
allowUrls: true
},
onDemand: true,
discardSelector: ".discard-answer"
,immediatelyShowMarkdownHelp:true
});
}
});
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
StackExchange.ready(
function () {
StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2ftex.stackexchange.com%2fquestions%2f435193%2f3d-histogram-without-external-programs%23new-answer', 'question_page');
}
);
Post as a guest
Required, but never shown
1 Answer
1
active
oldest
votes
1 Answer
1
active
oldest
votes
active
oldest
votes
active
oldest
votes
You also need to adjust the height in that case. Note that you also draw some of the bars at the same x
and y
values. The current version of this trick doesn't support this. Before fixing this I would like to know if you really mean to draw them at the same x-y positions. UPDATE: I added an improved sort. Have a guess from whom I stole it. (Hint: his last name starts with "F" and ends with "euersänger";-) ANOTHER UPDATE: I made the thing more automatic. Due to the usual expansion issues, I could not make the conversion fully automatic, but now at least it will tell you what to put.
documentclass[tikz,border=3.14pt]{standalone}
usetikzlibrary{calc}
usepackage{pgfplots}
usepackage{pgfplotstable}
pgfplotsset{compat=1.16}
% from https://tex.stackexchange.com/a/102770/121799
defpgfplotsinvokeiflessthan#1#2#3#4{%
pgfkeysvalueof{/pgfplots/iflessthan/.@cmd}{#1}{#2}{#3}{#4}pgfeov
}%
defpgfplotsmulticmpthree#1#2#3#4#5#6do#7#8{%
pgfplotsset{float <}%
pgfplotsinvokeiflessthan{#1}{#4}{%
% first key <:
#7%
}{%
pgfplotsinvokeiflessthan{#4}{#1}{%
% first key >:
#8%
}{%
% first key ==:
pgfplotsset{float <}%
pgfplotsinvokeiflessthan{#2}{#5}{%
% second key <
#7%
}{%
pgfplotsinvokeiflessthan{#5}{#2}{%
% second key >
#8%
}{%
% second key ==
pgfplotsset{float <}%
pgfplotsinvokeiflessthan{#3}{#6}{%
% third key <
#7%
}{%
% third key >=
#8%
}%
}%
}%
}%
}%
}%
begin{document}
pgfplotstableread[col sep=comma,header=true]{%
x,y,color,myvalue
2,3,1,1000
4,3,2,30
2,7,3,0.75
7,7,4,450
8,5,2,300
2,5,1,100
4,-4,2,1
4,1,3,750
5,-1,4,4
5,2,2,300
1,-2,1,100
2,5,2,5
3,-8,3,750
4,5,4,420
7,-2,2,200
}{datatable}
%
%pgfplotstablesort[col sep=comma,header=true]resulttable{datatable}
pgfplotstablesort[create on use/sortkey/.style={
create col/assign/.code={%
edefentry{{thisrow{x}}{thisrow{y}}{thisrow{myvalue}}}%
pgfkeyslet{/pgfplots/table/create col/next content}entry
}
},
sort key=sortkey,
sort cmp={%
iflessthan/.code args={#1#2#3#4}{%
edeftemp{#1#2}%
expandafterpgfplotsmulticmpthreetempdo{#3}{#4}%
},
},
sort,
columns/Mtx/.style={string type},
columns/Kind/.style={string type},]resulttable{datatable}
begin{tikzpicture}%[x={(0.866cm,-0.5cm)},y={(0.866cm,0.5cm)},z={(0cm,1 cm)}]
pgfplotsset{set layers}
begin{axis}[% from section 4.6.4 of the pgfplotsmanual
view={120}{40},
width=320pt,
height=280pt,
z buffer=none,
xmin=-1,xmax=9,
ymin=-10,ymax=8,
zmin=0,zmax=2000,
enlargelimits=upper,
ztick={0,1000,2000},
zticklabels={0,500,1000}, % here one has to "cheat"
% meaning that one has to put labels which are the actual value
% divided by 2. This is because the bars will be centered at these
% values
xtick=data,
extra tick style={grid=major},
ytick=data,
grid=minor,
xlabel={$x$},
ylabel={$y$},
zlabel={$z$},
minor tick num=1,
point meta=explicit,
colormap name=viridis,
scatter/use mapped color={
draw=mapped color,fill=mapped color!70},
execute at begin plot={}
]
path let p1=($(axis cs:0,0,1)-(axis cs:0,0,0)$) in
pgfextra{pgfmathsetmacro{conv}{2*y1}
typeout{Kindlyspacespace considerspace settingspace thespace
prefactorspace ofspace zspace tospace conv}};
addplot3 [visualization depends on={
0.09952*z as myz}, % you'll get told how to adjust the prefactor
scatter/@pre marker code/.append style={/pgfplots/cube/size z=myz},%
scatter,only marks,
mark=cube*,mark size=5,opacity=1]
table[x expr={thisrow{x}},y expr={thisrow{y}},z
expr={1*thisrow{myvalue}},
meta expr={thisrow{color}}
] resulttable;
end{axis}
end{tikzpicture}
end{document}
ADDENDUM: In this version, the dimension for "full size" bars are computed, i.e. the x and y dimensions to make the bar fill out one unit in each direction. It also checks if the user already has put the correct z scale. It computes the correct scale factor, and asks you to recompile if necessary.
documentclass[tikz,border=3.14pt]{standalone}
usetikzlibrary{calc}
usepackage{pgfplots}
usepackage{pgfplotstable}
pgfplotsset{compat=1.16}
% from https://tex.stackexchange.com/a/102770/121799
defpgfplotsinvokeiflessthan#1#2#3#4{%
pgfkeysvalueof{/pgfplots/iflessthan/.@cmd}{#1}{#2}{#3}{#4}pgfeov
}%
defpgfplotsmulticmpthree#1#2#3#4#5#6do#7#8{%
pgfplotsset{float <}%
pgfplotsinvokeiflessthan{#1}{#4}{%
% first key <:
#7%
}{%
pgfplotsinvokeiflessthan{#4}{#1}{%
% first key >:
#8%
}{%
% first key ==:
pgfplotsset{float <}%
pgfplotsinvokeiflessthan{#2}{#5}{%
% second key <
#7%
}{%
pgfplotsinvokeiflessthan{#5}{#2}{%
% second key >
#8%
}{%
% second key ==
pgfplotsset{float <}%
pgfplotsinvokeiflessthan{#3}{#6}{%
% third key <
#7%
}{%
% third key >=
#8%
}%
}%
}%
}%
}%
}%
begin{document}
ifdefinedgconv
else
pgfmathsetmacro{gconv}{0.1}
fi
pgfplotstableread[col sep=comma,header=true]{%
x,y,color,myvalue
2,3,1,1000
4,3,2,30
2,7,3,0.75
7,7,4,450
8,5,2,300
2,5,1,100
4,-4,2,1
4,1,3,750
5,-1,4,4
5,2,2,300
1,-2,1,100
2,5,2,5
3,-8,3,750
4,5,4,420
7,-2,2,200
}{datatable}
%
%pgfplotstablesort[col sep=comma,header=true]resulttable{datatable}
pgfplotstablesort[create on use/sortkey/.style={
create col/assign/.code={%
edefentry{{thisrow{x}}{thisrow{y}}{thisrow{myvalue}}}%
pgfkeyslet{/pgfplots/table/create col/next content}entry
}
},
sort key=sortkey,
sort cmp={%
iflessthan/.code args={#1#2#3#4}{%
edeftemp{#1#2}%
expandafterpgfplotsmulticmpthreetempdo{#3}{#4}%
},
},
sort,
columns/Mtx/.style={string type},
columns/Kind/.style={string type},]resulttable{datatable}
begin{tikzpicture}%[x={(0.866cm,-0.5cm)},y={(0.866cm,0.5cm)},z={(0cm,1 cm)}]
pgfplotsset{set layers}
begin{axis}[% from section 4.6.4 of the pgfplotsmanual
view={120}{40},
width=320pt,
height=280pt,
z buffer=none,
xmin=-1,xmax=9,
ymin=-10,ymax=8,
zmin=0,zmax=2000,
enlargelimits=upper,
ztick={0,1000,2000},
zticklabels={0,500,1000}, % here one has to "cheat"
% meaning that one has to put labels which are the actual value
% divided by 2. This is because the bars will be centered at these
% values
xtick=data,
extra tick style={grid=major},
ytick=data,
grid=minor,
xlabel={$x$},
ylabel={$y$},
zlabel={$z$},
minor tick num=1,
point meta=explicit,
colormap name=viridis,
scatter/use mapped color={
draw=mapped color,fill=mapped color!70},
execute at begin plot={}
]
path let p1=($(axis cs:0,0,1)-(axis cs:0,0,0)$) in
pgfextra{pgfmathsetmacro{conv}{2*y1}
ifxgconvconv
else
xdefgconv{conv}
typeout{Pleasespace recompilespace thespace file!}
fi
};
path let p1=($(axis cs:1,0,0)-(axis cs:0,0,0)$) in
pgfextra{pgfmathsetmacro{convx}{veclen(x1,y1)}
typeout{Onespace unitspace inspace xspace
directionspace isspaceconvx pt}
};
path let p1=($(axis cs:0,1,0)-(axis cs:0,0,0)$) in
pgfextra{pgfmathsetmacro{convy}{veclen(x1,y1)}
typeout{Onespace unitspace inspace yspace
directionspace isspaceconvy pt}
};
addplot3 [visualization depends on={
gconv*z as myz}, % you may have to recompile to get the prefactor right
scatter/@pre marker code/.append style={/pgfplots/cube/size z=myz},%
scatter/@pre marker code/.append style={/pgfplots/cube/size x=11.66135pt},%
scatter/@pre marker code/.append style={/pgfplots/cube/size y=9.10493pt},%
scatter,only marks,
mark=cube*,mark size=5,opacity=1]
table[x expr={thisrow{x}},y expr={thisrow{y}},z
expr={1*thisrow{myvalue}},
meta expr={thisrow{color}}
] resulttable;
end{axis}
makeatletter
immediatewrite@mainaux{xdefstringgconv{gconv}relax}
makeatother
end{tikzpicture}
end{document}
I really appreciate your efforts. Thank you! When you change the angle of the view, for example toview={50}{70}
something get's messed up with the sorting, the bars are overlapping, the same happens when you setx dir=reversed
. Maybe there is a solution for it by changing the sorting algorithm. One little addition: You could add "pt" at the end of the typeout for the depth and width.
– sporc
Jun 12 '18 at 7:35
@sporc Yes, of course, if you change the view, it won't work any more. And I am doing the sort independently of the view. At this point, I don't see any easy way to fix that. But thanks for the remark onpt
, I'll change this right away.
– marmot
Jun 12 '18 at 14:45
Could you please explain how you calculate the x and y dimensions. As far as I understand you take the length from (1,0,0) to (0,0,0) for x and divide it by xmax? I am asking beacuase I want to adjust the code so that it takes the length (1,0,0) to (0,0,0) and divides it by a fix value, like 100. So that 100 bars would fit along the axis
– sporc
Jun 28 '18 at 11:22
@sporc Yes, that's precisely how I compute it.
– marmot
Jun 28 '18 at 14:18
I can't see where you divide. Isn't this just the length?pgfextra{pgfmathsetmacro{convy}{veclen(x1,y1)}
– sporc
Jun 29 '18 at 6:44
|
show 8 more comments
You also need to adjust the height in that case. Note that you also draw some of the bars at the same x
and y
values. The current version of this trick doesn't support this. Before fixing this I would like to know if you really mean to draw them at the same x-y positions. UPDATE: I added an improved sort. Have a guess from whom I stole it. (Hint: his last name starts with "F" and ends with "euersänger";-) ANOTHER UPDATE: I made the thing more automatic. Due to the usual expansion issues, I could not make the conversion fully automatic, but now at least it will tell you what to put.
documentclass[tikz,border=3.14pt]{standalone}
usetikzlibrary{calc}
usepackage{pgfplots}
usepackage{pgfplotstable}
pgfplotsset{compat=1.16}
% from https://tex.stackexchange.com/a/102770/121799
defpgfplotsinvokeiflessthan#1#2#3#4{%
pgfkeysvalueof{/pgfplots/iflessthan/.@cmd}{#1}{#2}{#3}{#4}pgfeov
}%
defpgfplotsmulticmpthree#1#2#3#4#5#6do#7#8{%
pgfplotsset{float <}%
pgfplotsinvokeiflessthan{#1}{#4}{%
% first key <:
#7%
}{%
pgfplotsinvokeiflessthan{#4}{#1}{%
% first key >:
#8%
}{%
% first key ==:
pgfplotsset{float <}%
pgfplotsinvokeiflessthan{#2}{#5}{%
% second key <
#7%
}{%
pgfplotsinvokeiflessthan{#5}{#2}{%
% second key >
#8%
}{%
% second key ==
pgfplotsset{float <}%
pgfplotsinvokeiflessthan{#3}{#6}{%
% third key <
#7%
}{%
% third key >=
#8%
}%
}%
}%
}%
}%
}%
begin{document}
pgfplotstableread[col sep=comma,header=true]{%
x,y,color,myvalue
2,3,1,1000
4,3,2,30
2,7,3,0.75
7,7,4,450
8,5,2,300
2,5,1,100
4,-4,2,1
4,1,3,750
5,-1,4,4
5,2,2,300
1,-2,1,100
2,5,2,5
3,-8,3,750
4,5,4,420
7,-2,2,200
}{datatable}
%
%pgfplotstablesort[col sep=comma,header=true]resulttable{datatable}
pgfplotstablesort[create on use/sortkey/.style={
create col/assign/.code={%
edefentry{{thisrow{x}}{thisrow{y}}{thisrow{myvalue}}}%
pgfkeyslet{/pgfplots/table/create col/next content}entry
}
},
sort key=sortkey,
sort cmp={%
iflessthan/.code args={#1#2#3#4}{%
edeftemp{#1#2}%
expandafterpgfplotsmulticmpthreetempdo{#3}{#4}%
},
},
sort,
columns/Mtx/.style={string type},
columns/Kind/.style={string type},]resulttable{datatable}
begin{tikzpicture}%[x={(0.866cm,-0.5cm)},y={(0.866cm,0.5cm)},z={(0cm,1 cm)}]
pgfplotsset{set layers}
begin{axis}[% from section 4.6.4 of the pgfplotsmanual
view={120}{40},
width=320pt,
height=280pt,
z buffer=none,
xmin=-1,xmax=9,
ymin=-10,ymax=8,
zmin=0,zmax=2000,
enlargelimits=upper,
ztick={0,1000,2000},
zticklabels={0,500,1000}, % here one has to "cheat"
% meaning that one has to put labels which are the actual value
% divided by 2. This is because the bars will be centered at these
% values
xtick=data,
extra tick style={grid=major},
ytick=data,
grid=minor,
xlabel={$x$},
ylabel={$y$},
zlabel={$z$},
minor tick num=1,
point meta=explicit,
colormap name=viridis,
scatter/use mapped color={
draw=mapped color,fill=mapped color!70},
execute at begin plot={}
]
path let p1=($(axis cs:0,0,1)-(axis cs:0,0,0)$) in
pgfextra{pgfmathsetmacro{conv}{2*y1}
typeout{Kindlyspacespace considerspace settingspace thespace
prefactorspace ofspace zspace tospace conv}};
addplot3 [visualization depends on={
0.09952*z as myz}, % you'll get told how to adjust the prefactor
scatter/@pre marker code/.append style={/pgfplots/cube/size z=myz},%
scatter,only marks,
mark=cube*,mark size=5,opacity=1]
table[x expr={thisrow{x}},y expr={thisrow{y}},z
expr={1*thisrow{myvalue}},
meta expr={thisrow{color}}
] resulttable;
end{axis}
end{tikzpicture}
end{document}
ADDENDUM: In this version, the dimension for "full size" bars are computed, i.e. the x and y dimensions to make the bar fill out one unit in each direction. It also checks if the user already has put the correct z scale. It computes the correct scale factor, and asks you to recompile if necessary.
documentclass[tikz,border=3.14pt]{standalone}
usetikzlibrary{calc}
usepackage{pgfplots}
usepackage{pgfplotstable}
pgfplotsset{compat=1.16}
% from https://tex.stackexchange.com/a/102770/121799
defpgfplotsinvokeiflessthan#1#2#3#4{%
pgfkeysvalueof{/pgfplots/iflessthan/.@cmd}{#1}{#2}{#3}{#4}pgfeov
}%
defpgfplotsmulticmpthree#1#2#3#4#5#6do#7#8{%
pgfplotsset{float <}%
pgfplotsinvokeiflessthan{#1}{#4}{%
% first key <:
#7%
}{%
pgfplotsinvokeiflessthan{#4}{#1}{%
% first key >:
#8%
}{%
% first key ==:
pgfplotsset{float <}%
pgfplotsinvokeiflessthan{#2}{#5}{%
% second key <
#7%
}{%
pgfplotsinvokeiflessthan{#5}{#2}{%
% second key >
#8%
}{%
% second key ==
pgfplotsset{float <}%
pgfplotsinvokeiflessthan{#3}{#6}{%
% third key <
#7%
}{%
% third key >=
#8%
}%
}%
}%
}%
}%
}%
begin{document}
ifdefinedgconv
else
pgfmathsetmacro{gconv}{0.1}
fi
pgfplotstableread[col sep=comma,header=true]{%
x,y,color,myvalue
2,3,1,1000
4,3,2,30
2,7,3,0.75
7,7,4,450
8,5,2,300
2,5,1,100
4,-4,2,1
4,1,3,750
5,-1,4,4
5,2,2,300
1,-2,1,100
2,5,2,5
3,-8,3,750
4,5,4,420
7,-2,2,200
}{datatable}
%
%pgfplotstablesort[col sep=comma,header=true]resulttable{datatable}
pgfplotstablesort[create on use/sortkey/.style={
create col/assign/.code={%
edefentry{{thisrow{x}}{thisrow{y}}{thisrow{myvalue}}}%
pgfkeyslet{/pgfplots/table/create col/next content}entry
}
},
sort key=sortkey,
sort cmp={%
iflessthan/.code args={#1#2#3#4}{%
edeftemp{#1#2}%
expandafterpgfplotsmulticmpthreetempdo{#3}{#4}%
},
},
sort,
columns/Mtx/.style={string type},
columns/Kind/.style={string type},]resulttable{datatable}
begin{tikzpicture}%[x={(0.866cm,-0.5cm)},y={(0.866cm,0.5cm)},z={(0cm,1 cm)}]
pgfplotsset{set layers}
begin{axis}[% from section 4.6.4 of the pgfplotsmanual
view={120}{40},
width=320pt,
height=280pt,
z buffer=none,
xmin=-1,xmax=9,
ymin=-10,ymax=8,
zmin=0,zmax=2000,
enlargelimits=upper,
ztick={0,1000,2000},
zticklabels={0,500,1000}, % here one has to "cheat"
% meaning that one has to put labels which are the actual value
% divided by 2. This is because the bars will be centered at these
% values
xtick=data,
extra tick style={grid=major},
ytick=data,
grid=minor,
xlabel={$x$},
ylabel={$y$},
zlabel={$z$},
minor tick num=1,
point meta=explicit,
colormap name=viridis,
scatter/use mapped color={
draw=mapped color,fill=mapped color!70},
execute at begin plot={}
]
path let p1=($(axis cs:0,0,1)-(axis cs:0,0,0)$) in
pgfextra{pgfmathsetmacro{conv}{2*y1}
ifxgconvconv
else
xdefgconv{conv}
typeout{Pleasespace recompilespace thespace file!}
fi
};
path let p1=($(axis cs:1,0,0)-(axis cs:0,0,0)$) in
pgfextra{pgfmathsetmacro{convx}{veclen(x1,y1)}
typeout{Onespace unitspace inspace xspace
directionspace isspaceconvx pt}
};
path let p1=($(axis cs:0,1,0)-(axis cs:0,0,0)$) in
pgfextra{pgfmathsetmacro{convy}{veclen(x1,y1)}
typeout{Onespace unitspace inspace yspace
directionspace isspaceconvy pt}
};
addplot3 [visualization depends on={
gconv*z as myz}, % you may have to recompile to get the prefactor right
scatter/@pre marker code/.append style={/pgfplots/cube/size z=myz},%
scatter/@pre marker code/.append style={/pgfplots/cube/size x=11.66135pt},%
scatter/@pre marker code/.append style={/pgfplots/cube/size y=9.10493pt},%
scatter,only marks,
mark=cube*,mark size=5,opacity=1]
table[x expr={thisrow{x}},y expr={thisrow{y}},z
expr={1*thisrow{myvalue}},
meta expr={thisrow{color}}
] resulttable;
end{axis}
makeatletter
immediatewrite@mainaux{xdefstringgconv{gconv}relax}
makeatother
end{tikzpicture}
end{document}
I really appreciate your efforts. Thank you! When you change the angle of the view, for example toview={50}{70}
something get's messed up with the sorting, the bars are overlapping, the same happens when you setx dir=reversed
. Maybe there is a solution for it by changing the sorting algorithm. One little addition: You could add "pt" at the end of the typeout for the depth and width.
– sporc
Jun 12 '18 at 7:35
@sporc Yes, of course, if you change the view, it won't work any more. And I am doing the sort independently of the view. At this point, I don't see any easy way to fix that. But thanks for the remark onpt
, I'll change this right away.
– marmot
Jun 12 '18 at 14:45
Could you please explain how you calculate the x and y dimensions. As far as I understand you take the length from (1,0,0) to (0,0,0) for x and divide it by xmax? I am asking beacuase I want to adjust the code so that it takes the length (1,0,0) to (0,0,0) and divides it by a fix value, like 100. So that 100 bars would fit along the axis
– sporc
Jun 28 '18 at 11:22
@sporc Yes, that's precisely how I compute it.
– marmot
Jun 28 '18 at 14:18
I can't see where you divide. Isn't this just the length?pgfextra{pgfmathsetmacro{convy}{veclen(x1,y1)}
– sporc
Jun 29 '18 at 6:44
|
show 8 more comments
You also need to adjust the height in that case. Note that you also draw some of the bars at the same x
and y
values. The current version of this trick doesn't support this. Before fixing this I would like to know if you really mean to draw them at the same x-y positions. UPDATE: I added an improved sort. Have a guess from whom I stole it. (Hint: his last name starts with "F" and ends with "euersänger";-) ANOTHER UPDATE: I made the thing more automatic. Due to the usual expansion issues, I could not make the conversion fully automatic, but now at least it will tell you what to put.
documentclass[tikz,border=3.14pt]{standalone}
usetikzlibrary{calc}
usepackage{pgfplots}
usepackage{pgfplotstable}
pgfplotsset{compat=1.16}
% from https://tex.stackexchange.com/a/102770/121799
defpgfplotsinvokeiflessthan#1#2#3#4{%
pgfkeysvalueof{/pgfplots/iflessthan/.@cmd}{#1}{#2}{#3}{#4}pgfeov
}%
defpgfplotsmulticmpthree#1#2#3#4#5#6do#7#8{%
pgfplotsset{float <}%
pgfplotsinvokeiflessthan{#1}{#4}{%
% first key <:
#7%
}{%
pgfplotsinvokeiflessthan{#4}{#1}{%
% first key >:
#8%
}{%
% first key ==:
pgfplotsset{float <}%
pgfplotsinvokeiflessthan{#2}{#5}{%
% second key <
#7%
}{%
pgfplotsinvokeiflessthan{#5}{#2}{%
% second key >
#8%
}{%
% second key ==
pgfplotsset{float <}%
pgfplotsinvokeiflessthan{#3}{#6}{%
% third key <
#7%
}{%
% third key >=
#8%
}%
}%
}%
}%
}%
}%
begin{document}
pgfplotstableread[col sep=comma,header=true]{%
x,y,color,myvalue
2,3,1,1000
4,3,2,30
2,7,3,0.75
7,7,4,450
8,5,2,300
2,5,1,100
4,-4,2,1
4,1,3,750
5,-1,4,4
5,2,2,300
1,-2,1,100
2,5,2,5
3,-8,3,750
4,5,4,420
7,-2,2,200
}{datatable}
%
%pgfplotstablesort[col sep=comma,header=true]resulttable{datatable}
pgfplotstablesort[create on use/sortkey/.style={
create col/assign/.code={%
edefentry{{thisrow{x}}{thisrow{y}}{thisrow{myvalue}}}%
pgfkeyslet{/pgfplots/table/create col/next content}entry
}
},
sort key=sortkey,
sort cmp={%
iflessthan/.code args={#1#2#3#4}{%
edeftemp{#1#2}%
expandafterpgfplotsmulticmpthreetempdo{#3}{#4}%
},
},
sort,
columns/Mtx/.style={string type},
columns/Kind/.style={string type},]resulttable{datatable}
begin{tikzpicture}%[x={(0.866cm,-0.5cm)},y={(0.866cm,0.5cm)},z={(0cm,1 cm)}]
pgfplotsset{set layers}
begin{axis}[% from section 4.6.4 of the pgfplotsmanual
view={120}{40},
width=320pt,
height=280pt,
z buffer=none,
xmin=-1,xmax=9,
ymin=-10,ymax=8,
zmin=0,zmax=2000,
enlargelimits=upper,
ztick={0,1000,2000},
zticklabels={0,500,1000}, % here one has to "cheat"
% meaning that one has to put labels which are the actual value
% divided by 2. This is because the bars will be centered at these
% values
xtick=data,
extra tick style={grid=major},
ytick=data,
grid=minor,
xlabel={$x$},
ylabel={$y$},
zlabel={$z$},
minor tick num=1,
point meta=explicit,
colormap name=viridis,
scatter/use mapped color={
draw=mapped color,fill=mapped color!70},
execute at begin plot={}
]
path let p1=($(axis cs:0,0,1)-(axis cs:0,0,0)$) in
pgfextra{pgfmathsetmacro{conv}{2*y1}
typeout{Kindlyspacespace considerspace settingspace thespace
prefactorspace ofspace zspace tospace conv}};
addplot3 [visualization depends on={
0.09952*z as myz}, % you'll get told how to adjust the prefactor
scatter/@pre marker code/.append style={/pgfplots/cube/size z=myz},%
scatter,only marks,
mark=cube*,mark size=5,opacity=1]
table[x expr={thisrow{x}},y expr={thisrow{y}},z
expr={1*thisrow{myvalue}},
meta expr={thisrow{color}}
] resulttable;
end{axis}
end{tikzpicture}
end{document}
ADDENDUM: In this version, the dimension for "full size" bars are computed, i.e. the x and y dimensions to make the bar fill out one unit in each direction. It also checks if the user already has put the correct z scale. It computes the correct scale factor, and asks you to recompile if necessary.
documentclass[tikz,border=3.14pt]{standalone}
usetikzlibrary{calc}
usepackage{pgfplots}
usepackage{pgfplotstable}
pgfplotsset{compat=1.16}
% from https://tex.stackexchange.com/a/102770/121799
defpgfplotsinvokeiflessthan#1#2#3#4{%
pgfkeysvalueof{/pgfplots/iflessthan/.@cmd}{#1}{#2}{#3}{#4}pgfeov
}%
defpgfplotsmulticmpthree#1#2#3#4#5#6do#7#8{%
pgfplotsset{float <}%
pgfplotsinvokeiflessthan{#1}{#4}{%
% first key <:
#7%
}{%
pgfplotsinvokeiflessthan{#4}{#1}{%
% first key >:
#8%
}{%
% first key ==:
pgfplotsset{float <}%
pgfplotsinvokeiflessthan{#2}{#5}{%
% second key <
#7%
}{%
pgfplotsinvokeiflessthan{#5}{#2}{%
% second key >
#8%
}{%
% second key ==
pgfplotsset{float <}%
pgfplotsinvokeiflessthan{#3}{#6}{%
% third key <
#7%
}{%
% third key >=
#8%
}%
}%
}%
}%
}%
}%
begin{document}
ifdefinedgconv
else
pgfmathsetmacro{gconv}{0.1}
fi
pgfplotstableread[col sep=comma,header=true]{%
x,y,color,myvalue
2,3,1,1000
4,3,2,30
2,7,3,0.75
7,7,4,450
8,5,2,300
2,5,1,100
4,-4,2,1
4,1,3,750
5,-1,4,4
5,2,2,300
1,-2,1,100
2,5,2,5
3,-8,3,750
4,5,4,420
7,-2,2,200
}{datatable}
%
%pgfplotstablesort[col sep=comma,header=true]resulttable{datatable}
pgfplotstablesort[create on use/sortkey/.style={
create col/assign/.code={%
edefentry{{thisrow{x}}{thisrow{y}}{thisrow{myvalue}}}%
pgfkeyslet{/pgfplots/table/create col/next content}entry
}
},
sort key=sortkey,
sort cmp={%
iflessthan/.code args={#1#2#3#4}{%
edeftemp{#1#2}%
expandafterpgfplotsmulticmpthreetempdo{#3}{#4}%
},
},
sort,
columns/Mtx/.style={string type},
columns/Kind/.style={string type},]resulttable{datatable}
begin{tikzpicture}%[x={(0.866cm,-0.5cm)},y={(0.866cm,0.5cm)},z={(0cm,1 cm)}]
pgfplotsset{set layers}
begin{axis}[% from section 4.6.4 of the pgfplotsmanual
view={120}{40},
width=320pt,
height=280pt,
z buffer=none,
xmin=-1,xmax=9,
ymin=-10,ymax=8,
zmin=0,zmax=2000,
enlargelimits=upper,
ztick={0,1000,2000},
zticklabels={0,500,1000}, % here one has to "cheat"
% meaning that one has to put labels which are the actual value
% divided by 2. This is because the bars will be centered at these
% values
xtick=data,
extra tick style={grid=major},
ytick=data,
grid=minor,
xlabel={$x$},
ylabel={$y$},
zlabel={$z$},
minor tick num=1,
point meta=explicit,
colormap name=viridis,
scatter/use mapped color={
draw=mapped color,fill=mapped color!70},
execute at begin plot={}
]
path let p1=($(axis cs:0,0,1)-(axis cs:0,0,0)$) in
pgfextra{pgfmathsetmacro{conv}{2*y1}
ifxgconvconv
else
xdefgconv{conv}
typeout{Pleasespace recompilespace thespace file!}
fi
};
path let p1=($(axis cs:1,0,0)-(axis cs:0,0,0)$) in
pgfextra{pgfmathsetmacro{convx}{veclen(x1,y1)}
typeout{Onespace unitspace inspace xspace
directionspace isspaceconvx pt}
};
path let p1=($(axis cs:0,1,0)-(axis cs:0,0,0)$) in
pgfextra{pgfmathsetmacro{convy}{veclen(x1,y1)}
typeout{Onespace unitspace inspace yspace
directionspace isspaceconvy pt}
};
addplot3 [visualization depends on={
gconv*z as myz}, % you may have to recompile to get the prefactor right
scatter/@pre marker code/.append style={/pgfplots/cube/size z=myz},%
scatter/@pre marker code/.append style={/pgfplots/cube/size x=11.66135pt},%
scatter/@pre marker code/.append style={/pgfplots/cube/size y=9.10493pt},%
scatter,only marks,
mark=cube*,mark size=5,opacity=1]
table[x expr={thisrow{x}},y expr={thisrow{y}},z
expr={1*thisrow{myvalue}},
meta expr={thisrow{color}}
] resulttable;
end{axis}
makeatletter
immediatewrite@mainaux{xdefstringgconv{gconv}relax}
makeatother
end{tikzpicture}
end{document}
You also need to adjust the height in that case. Note that you also draw some of the bars at the same x
and y
values. The current version of this trick doesn't support this. Before fixing this I would like to know if you really mean to draw them at the same x-y positions. UPDATE: I added an improved sort. Have a guess from whom I stole it. (Hint: his last name starts with "F" and ends with "euersänger";-) ANOTHER UPDATE: I made the thing more automatic. Due to the usual expansion issues, I could not make the conversion fully automatic, but now at least it will tell you what to put.
documentclass[tikz,border=3.14pt]{standalone}
usetikzlibrary{calc}
usepackage{pgfplots}
usepackage{pgfplotstable}
pgfplotsset{compat=1.16}
% from https://tex.stackexchange.com/a/102770/121799
defpgfplotsinvokeiflessthan#1#2#3#4{%
pgfkeysvalueof{/pgfplots/iflessthan/.@cmd}{#1}{#2}{#3}{#4}pgfeov
}%
defpgfplotsmulticmpthree#1#2#3#4#5#6do#7#8{%
pgfplotsset{float <}%
pgfplotsinvokeiflessthan{#1}{#4}{%
% first key <:
#7%
}{%
pgfplotsinvokeiflessthan{#4}{#1}{%
% first key >:
#8%
}{%
% first key ==:
pgfplotsset{float <}%
pgfplotsinvokeiflessthan{#2}{#5}{%
% second key <
#7%
}{%
pgfplotsinvokeiflessthan{#5}{#2}{%
% second key >
#8%
}{%
% second key ==
pgfplotsset{float <}%
pgfplotsinvokeiflessthan{#3}{#6}{%
% third key <
#7%
}{%
% third key >=
#8%
}%
}%
}%
}%
}%
}%
begin{document}
pgfplotstableread[col sep=comma,header=true]{%
x,y,color,myvalue
2,3,1,1000
4,3,2,30
2,7,3,0.75
7,7,4,450
8,5,2,300
2,5,1,100
4,-4,2,1
4,1,3,750
5,-1,4,4
5,2,2,300
1,-2,1,100
2,5,2,5
3,-8,3,750
4,5,4,420
7,-2,2,200
}{datatable}
%
%pgfplotstablesort[col sep=comma,header=true]resulttable{datatable}
pgfplotstablesort[create on use/sortkey/.style={
create col/assign/.code={%
edefentry{{thisrow{x}}{thisrow{y}}{thisrow{myvalue}}}%
pgfkeyslet{/pgfplots/table/create col/next content}entry
}
},
sort key=sortkey,
sort cmp={%
iflessthan/.code args={#1#2#3#4}{%
edeftemp{#1#2}%
expandafterpgfplotsmulticmpthreetempdo{#3}{#4}%
},
},
sort,
columns/Mtx/.style={string type},
columns/Kind/.style={string type},]resulttable{datatable}
begin{tikzpicture}%[x={(0.866cm,-0.5cm)},y={(0.866cm,0.5cm)},z={(0cm,1 cm)}]
pgfplotsset{set layers}
begin{axis}[% from section 4.6.4 of the pgfplotsmanual
view={120}{40},
width=320pt,
height=280pt,
z buffer=none,
xmin=-1,xmax=9,
ymin=-10,ymax=8,
zmin=0,zmax=2000,
enlargelimits=upper,
ztick={0,1000,2000},
zticklabels={0,500,1000}, % here one has to "cheat"
% meaning that one has to put labels which are the actual value
% divided by 2. This is because the bars will be centered at these
% values
xtick=data,
extra tick style={grid=major},
ytick=data,
grid=minor,
xlabel={$x$},
ylabel={$y$},
zlabel={$z$},
minor tick num=1,
point meta=explicit,
colormap name=viridis,
scatter/use mapped color={
draw=mapped color,fill=mapped color!70},
execute at begin plot={}
]
path let p1=($(axis cs:0,0,1)-(axis cs:0,0,0)$) in
pgfextra{pgfmathsetmacro{conv}{2*y1}
typeout{Kindlyspacespace considerspace settingspace thespace
prefactorspace ofspace zspace tospace conv}};
addplot3 [visualization depends on={
0.09952*z as myz}, % you'll get told how to adjust the prefactor
scatter/@pre marker code/.append style={/pgfplots/cube/size z=myz},%
scatter,only marks,
mark=cube*,mark size=5,opacity=1]
table[x expr={thisrow{x}},y expr={thisrow{y}},z
expr={1*thisrow{myvalue}},
meta expr={thisrow{color}}
] resulttable;
end{axis}
end{tikzpicture}
end{document}
ADDENDUM: In this version, the dimension for "full size" bars are computed, i.e. the x and y dimensions to make the bar fill out one unit in each direction. It also checks if the user already has put the correct z scale. It computes the correct scale factor, and asks you to recompile if necessary.
documentclass[tikz,border=3.14pt]{standalone}
usetikzlibrary{calc}
usepackage{pgfplots}
usepackage{pgfplotstable}
pgfplotsset{compat=1.16}
% from https://tex.stackexchange.com/a/102770/121799
defpgfplotsinvokeiflessthan#1#2#3#4{%
pgfkeysvalueof{/pgfplots/iflessthan/.@cmd}{#1}{#2}{#3}{#4}pgfeov
}%
defpgfplotsmulticmpthree#1#2#3#4#5#6do#7#8{%
pgfplotsset{float <}%
pgfplotsinvokeiflessthan{#1}{#4}{%
% first key <:
#7%
}{%
pgfplotsinvokeiflessthan{#4}{#1}{%
% first key >:
#8%
}{%
% first key ==:
pgfplotsset{float <}%
pgfplotsinvokeiflessthan{#2}{#5}{%
% second key <
#7%
}{%
pgfplotsinvokeiflessthan{#5}{#2}{%
% second key >
#8%
}{%
% second key ==
pgfplotsset{float <}%
pgfplotsinvokeiflessthan{#3}{#6}{%
% third key <
#7%
}{%
% third key >=
#8%
}%
}%
}%
}%
}%
}%
begin{document}
ifdefinedgconv
else
pgfmathsetmacro{gconv}{0.1}
fi
pgfplotstableread[col sep=comma,header=true]{%
x,y,color,myvalue
2,3,1,1000
4,3,2,30
2,7,3,0.75
7,7,4,450
8,5,2,300
2,5,1,100
4,-4,2,1
4,1,3,750
5,-1,4,4
5,2,2,300
1,-2,1,100
2,5,2,5
3,-8,3,750
4,5,4,420
7,-2,2,200
}{datatable}
%
%pgfplotstablesort[col sep=comma,header=true]resulttable{datatable}
pgfplotstablesort[create on use/sortkey/.style={
create col/assign/.code={%
edefentry{{thisrow{x}}{thisrow{y}}{thisrow{myvalue}}}%
pgfkeyslet{/pgfplots/table/create col/next content}entry
}
},
sort key=sortkey,
sort cmp={%
iflessthan/.code args={#1#2#3#4}{%
edeftemp{#1#2}%
expandafterpgfplotsmulticmpthreetempdo{#3}{#4}%
},
},
sort,
columns/Mtx/.style={string type},
columns/Kind/.style={string type},]resulttable{datatable}
begin{tikzpicture}%[x={(0.866cm,-0.5cm)},y={(0.866cm,0.5cm)},z={(0cm,1 cm)}]
pgfplotsset{set layers}
begin{axis}[% from section 4.6.4 of the pgfplotsmanual
view={120}{40},
width=320pt,
height=280pt,
z buffer=none,
xmin=-1,xmax=9,
ymin=-10,ymax=8,
zmin=0,zmax=2000,
enlargelimits=upper,
ztick={0,1000,2000},
zticklabels={0,500,1000}, % here one has to "cheat"
% meaning that one has to put labels which are the actual value
% divided by 2. This is because the bars will be centered at these
% values
xtick=data,
extra tick style={grid=major},
ytick=data,
grid=minor,
xlabel={$x$},
ylabel={$y$},
zlabel={$z$},
minor tick num=1,
point meta=explicit,
colormap name=viridis,
scatter/use mapped color={
draw=mapped color,fill=mapped color!70},
execute at begin plot={}
]
path let p1=($(axis cs:0,0,1)-(axis cs:0,0,0)$) in
pgfextra{pgfmathsetmacro{conv}{2*y1}
ifxgconvconv
else
xdefgconv{conv}
typeout{Pleasespace recompilespace thespace file!}
fi
};
path let p1=($(axis cs:1,0,0)-(axis cs:0,0,0)$) in
pgfextra{pgfmathsetmacro{convx}{veclen(x1,y1)}
typeout{Onespace unitspace inspace xspace
directionspace isspaceconvx pt}
};
path let p1=($(axis cs:0,1,0)-(axis cs:0,0,0)$) in
pgfextra{pgfmathsetmacro{convy}{veclen(x1,y1)}
typeout{Onespace unitspace inspace yspace
directionspace isspaceconvy pt}
};
addplot3 [visualization depends on={
gconv*z as myz}, % you may have to recompile to get the prefactor right
scatter/@pre marker code/.append style={/pgfplots/cube/size z=myz},%
scatter/@pre marker code/.append style={/pgfplots/cube/size x=11.66135pt},%
scatter/@pre marker code/.append style={/pgfplots/cube/size y=9.10493pt},%
scatter,only marks,
mark=cube*,mark size=5,opacity=1]
table[x expr={thisrow{x}},y expr={thisrow{y}},z
expr={1*thisrow{myvalue}},
meta expr={thisrow{color}}
] resulttable;
end{axis}
makeatletter
immediatewrite@mainaux{xdefstringgconv{gconv}relax}
makeatother
end{tikzpicture}
end{document}
edited 4 hours ago
answered Jun 6 '18 at 13:53
marmotmarmot
115k5145276
115k5145276
I really appreciate your efforts. Thank you! When you change the angle of the view, for example toview={50}{70}
something get's messed up with the sorting, the bars are overlapping, the same happens when you setx dir=reversed
. Maybe there is a solution for it by changing the sorting algorithm. One little addition: You could add "pt" at the end of the typeout for the depth and width.
– sporc
Jun 12 '18 at 7:35
@sporc Yes, of course, if you change the view, it won't work any more. And I am doing the sort independently of the view. At this point, I don't see any easy way to fix that. But thanks for the remark onpt
, I'll change this right away.
– marmot
Jun 12 '18 at 14:45
Could you please explain how you calculate the x and y dimensions. As far as I understand you take the length from (1,0,0) to (0,0,0) for x and divide it by xmax? I am asking beacuase I want to adjust the code so that it takes the length (1,0,0) to (0,0,0) and divides it by a fix value, like 100. So that 100 bars would fit along the axis
– sporc
Jun 28 '18 at 11:22
@sporc Yes, that's precisely how I compute it.
– marmot
Jun 28 '18 at 14:18
I can't see where you divide. Isn't this just the length?pgfextra{pgfmathsetmacro{convy}{veclen(x1,y1)}
– sporc
Jun 29 '18 at 6:44
|
show 8 more comments
I really appreciate your efforts. Thank you! When you change the angle of the view, for example toview={50}{70}
something get's messed up with the sorting, the bars are overlapping, the same happens when you setx dir=reversed
. Maybe there is a solution for it by changing the sorting algorithm. One little addition: You could add "pt" at the end of the typeout for the depth and width.
– sporc
Jun 12 '18 at 7:35
@sporc Yes, of course, if you change the view, it won't work any more. And I am doing the sort independently of the view. At this point, I don't see any easy way to fix that. But thanks for the remark onpt
, I'll change this right away.
– marmot
Jun 12 '18 at 14:45
Could you please explain how you calculate the x and y dimensions. As far as I understand you take the length from (1,0,0) to (0,0,0) for x and divide it by xmax? I am asking beacuase I want to adjust the code so that it takes the length (1,0,0) to (0,0,0) and divides it by a fix value, like 100. So that 100 bars would fit along the axis
– sporc
Jun 28 '18 at 11:22
@sporc Yes, that's precisely how I compute it.
– marmot
Jun 28 '18 at 14:18
I can't see where you divide. Isn't this just the length?pgfextra{pgfmathsetmacro{convy}{veclen(x1,y1)}
– sporc
Jun 29 '18 at 6:44
I really appreciate your efforts. Thank you! When you change the angle of the view, for example to
view={50}{70}
something get's messed up with the sorting, the bars are overlapping, the same happens when you set x dir=reversed
. Maybe there is a solution for it by changing the sorting algorithm. One little addition: You could add "pt" at the end of the typeout for the depth and width.– sporc
Jun 12 '18 at 7:35
I really appreciate your efforts. Thank you! When you change the angle of the view, for example to
view={50}{70}
something get's messed up with the sorting, the bars are overlapping, the same happens when you set x dir=reversed
. Maybe there is a solution for it by changing the sorting algorithm. One little addition: You could add "pt" at the end of the typeout for the depth and width.– sporc
Jun 12 '18 at 7:35
@sporc Yes, of course, if you change the view, it won't work any more. And I am doing the sort independently of the view. At this point, I don't see any easy way to fix that. But thanks for the remark on
pt
, I'll change this right away.– marmot
Jun 12 '18 at 14:45
@sporc Yes, of course, if you change the view, it won't work any more. And I am doing the sort independently of the view. At this point, I don't see any easy way to fix that. But thanks for the remark on
pt
, I'll change this right away.– marmot
Jun 12 '18 at 14:45
Could you please explain how you calculate the x and y dimensions. As far as I understand you take the length from (1,0,0) to (0,0,0) for x and divide it by xmax? I am asking beacuase I want to adjust the code so that it takes the length (1,0,0) to (0,0,0) and divides it by a fix value, like 100. So that 100 bars would fit along the axis
– sporc
Jun 28 '18 at 11:22
Could you please explain how you calculate the x and y dimensions. As far as I understand you take the length from (1,0,0) to (0,0,0) for x and divide it by xmax? I am asking beacuase I want to adjust the code so that it takes the length (1,0,0) to (0,0,0) and divides it by a fix value, like 100. So that 100 bars would fit along the axis
– sporc
Jun 28 '18 at 11:22
@sporc Yes, that's precisely how I compute it.
– marmot
Jun 28 '18 at 14:18
@sporc Yes, that's precisely how I compute it.
– marmot
Jun 28 '18 at 14:18
I can't see where you divide. Isn't this just the length?
pgfextra{pgfmathsetmacro{convy}{veclen(x1,y1)}
– sporc
Jun 29 '18 at 6:44
I can't see where you divide. Isn't this just the length?
pgfextra{pgfmathsetmacro{convy}{veclen(x1,y1)}
– sporc
Jun 29 '18 at 6:44
|
show 8 more comments
Thanks for contributing an answer to TeX - LaTeX Stack Exchange!
- Please be sure to answer the question. Provide details and share your research!
But avoid …
- Asking for help, clarification, or responding to other answers.
- Making statements based on opinion; back them up with references or personal experience.
To learn more, see our tips on writing great answers.
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
StackExchange.ready(
function () {
StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2ftex.stackexchange.com%2fquestions%2f435193%2f3d-histogram-without-external-programs%23new-answer', 'question_page');
}
);
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown